Simplify website search and listing controls (#1553)

* Removing search from the home pageThis was a little confusing because there are two searches, but the overall site search is a lot more powerful

* Prefilter website search by resource page

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* small error handling and formatting

* Simplify website listing controls

Remove per-page text search, trim page-specific controls, and move remaining sort/filter controls into compact flyouts.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Aaron Powell
2026-04-29 16:03:08 +10:00
committed by GitHub
parent 0d7a5ad4c2
commit 76ac13a9b8
29 changed files with 1166 additions and 1331 deletions
+17 -31
View File
@@ -18,39 +18,24 @@ const initialItems = sortAgents(agentsData.items, 'title');
<div class="page-content">
<div class="container">
<div class="listing-toolbar">
<div class="search-bar">
<label for="search-input" class="sr-only">Search agents</label>
<input type="text" id="search-input" placeholder="Search agents..." autocomplete="off">
</div>
<!-- Filters -->
<div class="filters-bar" id="filters-bar">
<div class="filter-group">
<label for="filter-model">Model:</label>
<select id="filter-model" multiple aria-label="Filter by model"></select>
</div>
<div class="filter-group">
<label for="filter-tool">Tool:</label>
<select id="filter-tool" multiple aria-label="Filter by tool"></select>
</div>
<div class="filter-group">
<label class="checkbox-label">
<input type="checkbox" id="filter-handoffs">
Has Handoffs
</label>
</div>
<div class="filter-group">
<label for="sort-select">Sort:</label>
<select id="sort-select" aria-label="Sort by">
<option value="title">Name (A-Z)</option>
<option value="lastUpdated">Recently Updated</option>
</select>
</div>
<button id="clear-filters" class="btn btn-secondary btn-small">Clear Filters</button>
<div class="listing-toolbar-row">
<div class="results-count" id="results-count" aria-live="polite">{initialItems.length} agents</div>
<details class="listing-controls">
<summary class="listing-controls-trigger btn btn-secondary btn-small">Sort</summary>
<div class="listing-controls-panel">
<div class="filters-bar" id="filters-bar">
<div class="filter-group">
<label for="sort-select">Sort:</label>
<select id="sort-select" aria-label="Sort by">
<option value="title">Name (A-Z)</option>
<option value="lastUpdated">Recently Updated</option>
</select>
</div>
</div>
</div>
</details>
</div>
</div>
<div class="results-count" id="results-count" aria-live="polite">{initialItems.length} of {initialItems.length} agents</div>
<div class="resource-list" id="resource-list" role="list" set:html={renderAgentsHtml(initialItems)}></div>
<ContributeCTA resourceType="agents" />
</div>
@@ -62,6 +47,7 @@ const initialItems = sortAgents(agentsData.items, 'title');
<EmbeddedPageData filename="agents.json" data={agentsData} />
<script>
import '../scripts/listing-flyouts';
import '../scripts/pages/agents';
</script>
</StarlightPage>
+22 -24
View File
@@ -18,32 +18,29 @@ const initialItems = sortHooks(hooksData.items, 'title');
<div class="page-content">
<div class="container">
<div class="listing-toolbar">
<div class="search-bar">
<label for="search-input" class="sr-only">Search hooks</label>
<input type="text" id="search-input" placeholder="Search hooks..." autocomplete="off">
</div>
<div class="filters-bar" id="filters-bar">
<div class="filter-group">
<label for="filter-hook">Hook Event:</label>
<select id="filter-hook" multiple aria-label="Filter by hook event"></select>
</div>
<div class="filter-group">
<label for="filter-tag">Tag:</label>
<select id="filter-tag" multiple aria-label="Filter by tag"></select>
</div>
<div class="filter-group">
<label for="sort-select">Sort:</label>
<select id="sort-select" aria-label="Sort by">
<option value="title">Name (A-Z)</option>
<option value="lastUpdated">Recently Updated</option>
</select>
</div>
<button id="clear-filters" class="btn btn-secondary btn-small">Clear Filters</button>
<div class="listing-toolbar-row">
<div class="results-count" id="results-count" aria-live="polite">{initialItems.length} hooks</div>
<details class="listing-controls">
<summary class="listing-controls-trigger btn btn-secondary btn-small">Sort &amp; Filter</summary>
<div class="listing-controls-panel">
<div class="filters-bar" id="filters-bar">
<div class="filter-group">
<label for="filter-tag">Tag:</label>
<select id="filter-tag" multiple aria-label="Filter by tag"></select>
</div>
<div class="filter-group">
<label for="sort-select">Sort:</label>
<select id="sort-select" aria-label="Sort by">
<option value="title">Name (A-Z)</option>
<option value="lastUpdated">Recently Updated</option>
</select>
</div>
<button id="clear-filters" class="btn btn-secondary btn-small">Clear Filters</button>
</div>
</div>
</details>
</div>
</div>
<div class="results-count" id="results-count" aria-live="polite">{initialItems.length} of {initialItems.length} hooks</div>
<div class="resource-list" id="resource-list" role="list" set:html={renderHooksHtml(initialItems)}></div>
<ContributeCTA resourceType="hooks" />
</div>
@@ -55,6 +52,7 @@ const initialItems = sortHooks(hooksData.items, 'title');
<EmbeddedPageData filename="hooks.json" data={hooksData} />
<script>
import '../scripts/listing-flyouts';
import '../scripts/pages/hooks';
</script>
</StarlightPage>
-43
View File
@@ -40,49 +40,6 @@ const base = import.meta.env.BASE_URL;
Community-contributed agents, instructions, and skills to enhance your
GitHub Copilot experience
</p>
<div class="hero-search">
<label for="global-search" class="sr-only">Search all resources</label
>
<p id="global-search-help" class="sr-only">
Type at least two characters to show matching resources, then press
the Down Arrow key to move into the results.
</p>
<p id="global-search-status" class="sr-only" aria-live="polite"></p>
<div class="search-row">
<input
type="text"
id="global-search"
placeholder="Search all resources..."
autocomplete="off"
aria-describedby="global-search-help global-search-status"
/>
<a
href="https://github.com/github/awesome-copilot"
target="_blank"
rel="noopener"
class="github-btn"
aria-label="View on GitHub"
>
<svg
viewBox="0 0 24 24"
width="20"
height="20"
fill="currentColor"
>
<path
d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"
></path>
</svg>
<span>GitHub</span>
</a>
</div>
<div
id="search-results"
class="search-results hidden"
aria-label="Search results"
>
</div>
</div>
</div>
</section>
+22 -20
View File
@@ -18,28 +18,29 @@ const initialItems = sortInstructions(instructionsData.items, 'title');
<div class="page-content">
<div class="container">
<div class="listing-toolbar">
<div class="search-bar">
<label for="search-input" class="sr-only">Search instructions</label>
<input type="text" id="search-input" placeholder="Search instructions..." autocomplete="off">
</div>
<div class="filters-bar" id="filters-bar">
<div class="filter-group">
<label for="filter-extension">File Extension:</label>
<select id="filter-extension" multiple aria-label="Filter by file extension"></select>
</div>
<div class="filter-group">
<label for="sort-select">Sort:</label>
<select id="sort-select" aria-label="Sort by">
<option value="title">Name (A-Z)</option>
<option value="lastUpdated">Recently Updated</option>
</select>
</div>
<button id="clear-filters" class="btn btn-secondary btn-small">Clear Filters</button>
<div class="listing-toolbar-row">
<div class="results-count" id="results-count" aria-live="polite">{initialItems.length} instructions</div>
<details class="listing-controls">
<summary class="listing-controls-trigger btn btn-secondary btn-small">Sort &amp; Filter</summary>
<div class="listing-controls-panel">
<div class="filters-bar" id="filters-bar">
<div class="filter-group">
<label for="filter-extension">File Extension:</label>
<select id="filter-extension" multiple aria-label="Filter by file extension"></select>
</div>
<div class="filter-group">
<label for="sort-select">Sort:</label>
<select id="sort-select" aria-label="Sort by">
<option value="title">Name (A-Z)</option>
<option value="lastUpdated">Recently Updated</option>
</select>
</div>
<button id="clear-filters" class="btn btn-secondary btn-small">Clear Filters</button>
</div>
</div>
</details>
</div>
</div>
<div class="results-count" id="results-count" aria-live="polite">{initialItems.length} of {initialItems.length} instructions</div>
<div class="resource-list" id="resource-list" role="list" set:html={renderInstructionsHtml(initialItems)}></div>
<ContributeCTA resourceType="instructions" />
</div>
@@ -51,6 +52,7 @@ const initialItems = sortInstructions(instructionsData.items, 'title');
<EmbeddedPageData filename="instructions.json" data={instructionsData} />
<script>
import '../scripts/listing-flyouts';
import '../scripts/pages/instructions';
</script>
</StarlightPage>
+24 -15
View File
@@ -6,9 +6,9 @@ import ContributeCTA from '../components/ContributeCTA.astro';
import EmbeddedPageData from '../components/EmbeddedPageData.astro';
import PageHeader from '../components/PageHeader.astro';
import BackToTop from '../components/BackToTop.astro';
import { renderPluginsHtml } from '../scripts/pages/plugins-render';
import { renderPluginsHtml, sortPlugins } from '../scripts/pages/plugins-render';
const initialItems = pluginsData.items;
const initialItems = sortPlugins(pluginsData.items, 'title');
---
<StarlightPage frontmatter={{ title: 'Plugins', description: 'Curated plugins of agents, hooks, and skills for specific workflows', template: 'splash', prev: false, next: false, editUrl: false }}>
@@ -27,21 +27,29 @@ const initialItems = pluginsData.items;
</div>
<div class="listing-toolbar">
<div class="search-bar">
<label for="search-input" class="sr-only">Search plugins</label>
<input type="text" id="search-input" placeholder="Search plugins..." autocomplete="off">
</div>
<div class="filters-bar" id="filters-bar">
<div class="filter-group">
<label for="filter-tag">Tag:</label>
<select id="filter-tag" multiple aria-label="Filter by tag"></select>
</div>
<button id="clear-filters" class="btn btn-secondary btn-small">Clear Filters</button>
<div class="listing-toolbar-row">
<div class="results-count" id="results-count" aria-live="polite">{initialItems.length} plugins</div>
<details class="listing-controls">
<summary class="listing-controls-trigger btn btn-secondary btn-small">Sort &amp; Filter</summary>
<div class="listing-controls-panel">
<div class="filters-bar" id="filters-bar">
<div class="filter-group">
<label for="filter-tag">Tag:</label>
<select id="filter-tag" multiple aria-label="Filter by tag"></select>
</div>
<div class="filter-group">
<label for="sort-select">Sort:</label>
<select id="sort-select" aria-label="Sort plugins">
<option value="title">Title</option>
<option value="lastUpdated">Recently Updated</option>
</select>
</div>
<button id="clear-filters" class="btn btn-secondary btn-small">Clear Filters</button>
</div>
</div>
</details>
</div>
</div>
<div class="results-count" id="results-count" aria-live="polite">{initialItems.length} of {initialItems.length} plugins</div>
<div class="resource-list" id="resource-list" role="list" set:html={renderPluginsHtml(initialItems)}></div>
<ContributeCTA resourceType="plugins" />
</div>
@@ -53,6 +61,7 @@ const initialItems = pluginsData.items;
<EmbeddedPageData filename="plugins.json" data={pluginsData} />
<script>
import '../scripts/listing-flyouts';
import '../scripts/pages/plugins';
</script>
+17 -26
View File
@@ -18,34 +18,24 @@ const initialItems = sortSkills(skillsData.items, 'title');
<div class="page-content">
<div class="container">
<div class="listing-toolbar">
<div class="search-bar">
<label for="search-input" class="sr-only">Search skills</label>
<input type="text" id="search-input" placeholder="Search skills..." autocomplete="off">
</div>
<div class="filters-bar" id="filters-bar">
<div class="filter-group">
<label for="filter-category">Category:</label>
<select id="filter-category" multiple aria-label="Filter by category"></select>
</div>
<div class="filter-group">
<label class="checkbox-label">
<input type="checkbox" id="filter-has-assets">
Has Bundled Assets
</label>
</div>
<div class="filter-group">
<label for="sort-select">Sort:</label>
<select id="sort-select" aria-label="Sort by">
<option value="title">Name (A-Z)</option>
<option value="lastUpdated">Recently Updated</option>
</select>
</div>
<button id="clear-filters" class="btn btn-secondary btn-small">Clear Filters</button>
<div class="listing-toolbar-row">
<div class="results-count" id="results-count" aria-live="polite">{initialItems.length} skills</div>
<details class="listing-controls">
<summary class="listing-controls-trigger btn btn-secondary btn-small">Sort</summary>
<div class="listing-controls-panel">
<div class="filters-bar" id="filters-bar">
<div class="filter-group">
<label for="sort-select">Sort:</label>
<select id="sort-select" aria-label="Sort by">
<option value="title">Name (A-Z)</option>
<option value="lastUpdated">Recently Updated</option>
</select>
</div>
</div>
</div>
</details>
</div>
</div>
<div class="results-count" id="results-count" aria-live="polite">{initialItems.length} of {initialItems.length} skills</div>
<div class="resource-list" id="resource-list" role="list" set:html={renderSkillsHtml(initialItems)}></div>
<ContributeCTA resourceType="skills" />
</div>
@@ -57,6 +47,7 @@ const initialItems = sortSkills(skillsData.items, 'title');
<EmbeddedPageData filename="skills.json" data={skillsData} />
<script>
import '../scripts/listing-flyouts';
import '../scripts/pages/skills';
</script>
</StarlightPage>
+36 -74
View File
@@ -6,12 +6,15 @@ import ContributeCTA from "../components/ContributeCTA.astro";
import EmbeddedPageData from "../components/EmbeddedPageData.astro";
import PageHeader from "../components/PageHeader.astro";
import BackToTop from '../components/BackToTop.astro';
import { renderToolsHtml } from "../scripts/pages/tools-render";
import { renderToolsHtml, sortTools } from "../scripts/pages/tools-render";
const initialItems = toolsData.items.map((item) => ({
...item,
title: item.name,
}));
const initialItems = sortTools(
toolsData.items.map((item) => ({
...item,
title: item.name,
})),
"title"
);
---
<StarlightPage frontmatter={{ title: 'Tools', description: 'MCP servers and developer tools for GitHub Copilot', template: 'splash', prev: false, next: false, editUrl: false }}>
@@ -20,29 +23,34 @@ const initialItems = toolsData.items.map((item) => ({
<div class="page-content">
<div class="container">
<div class="search-section">
<div class="search-bar">
<label for="search-input" class="sr-only">Search tools</label>
<input
type="text"
id="search-input"
placeholder="Search tools..."
class="search-input"
/>
<div class="listing-toolbar">
<div class="listing-toolbar-row">
<div id="results-count" class="results-count" aria-live="polite">{initialItems.length} tools</div>
<details class="listing-controls">
<summary class="listing-controls-trigger btn btn-secondary btn-small">Sort &amp; Filter</summary>
<div class="listing-controls-panel">
<div class="filters-bar" id="filters-bar">
<div class="filter-group">
<label for="filter-category">Category:</label>
<select id="filter-category" class="filter-select" aria-label="Filter by category">
<option value="">All Categories</option>
{toolsData.filters.categories.map((category) => (
<option value={category}>{category}</option>
))}
</select>
</div>
<div class="filter-group">
<label for="sort-select">Sort:</label>
<select id="sort-select" class="filter-select" aria-label="Sort tools">
<option value="featured">Featured First</option>
<option value="title">Title</option>
</select>
</div>
<button id="clear-filters" class="btn btn-secondary btn-small">Clear</button>
</div>
</div>
</details>
</div>
<div class="filters">
<label for="filter-category" class="sr-only">Filter by category</label>
<select id="filter-category" class="filter-select" aria-label="Filter by category">
<option value="">All Categories</option>
{toolsData.filters.categories.map((category) => (
<option value={category}>{category}</option>
))}
</select>
<button id="clear-filters" class="btn btn-secondary btn-small"
>Clear</button
>
</div>
<div id="results-count" class="results-count" aria-live="polite">{initialItems.length} of {initialItems.length} tools</div>
</div>
<div id="tools-list" role="list" set:html={renderToolsHtml(initialItems)}></div>
@@ -64,53 +72,6 @@ const initialItems = toolsData.items.map((item) => ({
<EmbeddedPageData filename="tools.json" data={toolsData} />
<style is:global>
.search-section {
margin-bottom: 24px;
}
.search-bar {
margin-bottom: 16px;
}
.search-input {
width: 100%;
padding: 12px 16px;
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
background-color: var(--color-card-bg);
color: var(--color-text-primary);
font-size: 16px;
}
.search-input:focus {
outline: none;
border-color: var(--color-primary);
box-shadow: 0 0 0 3px rgba(133, 52, 243, 0.1);
}
.filters {
display: flex;
gap: 12px;
flex-wrap: wrap;
align-items: center;
}
.filter-select {
padding: 8px 12px;
border: 1px solid var(--color-border);
border-radius: var(--border-radius);
background-color: var(--color-card-bg);
color: var(--color-text-primary);
font-size: 14px;
min-width: 180px;
}
.results-count {
margin-top: 12px;
font-size: 14px;
color: var(--color-text-muted);
}
.empty-state {
text-align: center;
padding: 48px;
@@ -310,6 +271,7 @@ const initialItems = toolsData.items.map((item) => ({
</style>
<script>
import '../scripts/listing-flyouts';
import '../scripts/pages/tools';
</script>
</StarlightPage>
+22 -20
View File
@@ -18,28 +18,29 @@ const initialItems = sortWorkflows(workflowsData.items, 'title');
<div class="page-content">
<div class="container">
<div class="listing-toolbar">
<div class="search-bar">
<label for="search-input" class="sr-only">Search workflows</label>
<input type="text" id="search-input" placeholder="Search workflows..." autocomplete="off">
</div>
<div class="filters-bar" id="filters-bar">
<div class="filter-group">
<label for="filter-trigger">Trigger:</label>
<select id="filter-trigger" multiple aria-label="Filter by trigger"></select>
</div>
<div class="filter-group">
<label for="sort-select">Sort:</label>
<select id="sort-select" aria-label="Sort by">
<option value="title">Name (A-Z)</option>
<option value="lastUpdated">Recently Updated</option>
</select>
</div>
<button id="clear-filters" class="btn btn-secondary btn-small">Clear Filters</button>
<div class="listing-toolbar-row">
<div class="results-count" id="results-count" aria-live="polite">{initialItems.length} workflows</div>
<details class="listing-controls">
<summary class="listing-controls-trigger btn btn-secondary btn-small">Sort &amp; Filter</summary>
<div class="listing-controls-panel">
<div class="filters-bar" id="filters-bar">
<div class="filter-group">
<label for="filter-trigger">Trigger:</label>
<select id="filter-trigger" multiple aria-label="Filter by trigger"></select>
</div>
<div class="filter-group">
<label for="sort-select">Sort:</label>
<select id="sort-select" aria-label="Sort by">
<option value="title">Name (A-Z)</option>
<option value="lastUpdated">Recently Updated</option>
</select>
</div>
<button id="clear-filters" class="btn btn-secondary btn-small">Clear Filters</button>
</div>
</div>
</details>
</div>
</div>
<div class="results-count" id="results-count" aria-live="polite">{initialItems.length} of {initialItems.length} workflows</div>
<div class="resource-list" id="resource-list" role="list" set:html={renderWorkflowsHtml(initialItems)}></div>
<ContributeCTA resourceType="workflows" />
</div>
@@ -51,6 +52,7 @@ const initialItems = sortWorkflows(workflowsData.items, 'title');
<EmbeddedPageData filename="workflows.json" data={workflowsData} />
<script>
import '../scripts/listing-flyouts';
import '../scripts/pages/workflows';
</script>
</StarlightPage>