Skip to content

Commit 130ac96

Browse files
committed
Add search to filter the plugin list
A slim filter input in the top bar narrows the table client-side as you type (matching plugin name and URL), with a "no matches" empty state.
1 parent 8aed70b commit 130ac96

2 files changed

Lines changed: 68 additions & 2 deletions

File tree

homeView.tsx

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,25 @@ export function renderHomeHtml(pluginsData: PluginsData) {
4444
}, 1600);
4545
});
4646
}
47+
48+
// live filter
49+
const search = document.getElementById("plugin-search");
50+
if (search != null) {
51+
const rows = document.getElementsByClassName("plugin-row");
52+
const table = document.getElementsByClassName("plugin-table")[0];
53+
const noMatches = document.getElementById("no-matches");
54+
search.addEventListener("input", () => {
55+
const query = search.value.trim().toLowerCase();
56+
let visible = 0;
57+
for (const row of rows) {
58+
const match = query === "" || (row.dataset.search || "").indexOf(query) !== -1;
59+
row.hidden = !match;
60+
if (match) visible++;
61+
}
62+
if (table != null) table.hidden = visible === 0;
63+
if (noMatches != null) noMatches.hidden = visible !== 0;
64+
});
65+
}
4766
});
4867
</script>
4968
</head>
@@ -58,9 +77,19 @@ function renderPage(pluginsData: PluginsData) {
5877
return (
5978
<main class="page">
6079
<div class="topbar">
80+
<input
81+
type="search"
82+
id="plugin-search"
83+
class="plugin-search"
84+
placeholder="Filter plugins…"
85+
aria-label="Filter plugins"
86+
autocomplete="off"
87+
spellcheck={false}
88+
/>
6189
<a class="docs-link" href="https://dprint.dev/plugins">dprint plugin docs <span></span></a>
6290
</div>
6391
{renderPlugins(pluginsData)}
92+
<div id="no-matches" class="no-matches" hidden>No plugins match your filter.</div>
6493
{renderCommands()}
6594
</main>
6695
);
@@ -103,7 +132,7 @@ function renderPlugins(data: PluginsData) {
103132

104133
function renderPlugin(plugin: PluginData) {
105134
return (
106-
<div class="plugin-row" role="row" key={plugin.name}>
135+
<div class="plugin-row" role="row" key={plugin.name} data-search={`${plugin.name} ${plugin.url}`.toLowerCase()}>
107136
<div class="col-name" role="cell">
108137
<span class="swatch"></span>
109138
<span class="name-text">{plugin.name}</span>

style.css

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,32 @@ a {
4444

4545
.topbar {
4646
display: flex;
47-
justify-content: flex-end;
47+
align-items: center;
48+
justify-content: space-between;
49+
flex-wrap: wrap;
50+
gap: 14px;
4851
margin-bottom: 22px;
4952
}
53+
.plugin-search {
54+
flex: 1;
55+
min-width: 200px;
56+
max-width: 360px;
57+
font-family: inherit;
58+
font-size: 14px;
59+
color: #e8e8ea;
60+
background: #181a1e;
61+
border: 1px solid #33373f;
62+
border-radius: 8px;
63+
padding: 9px 13px;
64+
outline: none;
65+
transition: border-color 0.15s;
66+
}
67+
.plugin-search::placeholder {
68+
color: #6e7681;
69+
}
70+
.plugin-search:focus {
71+
border-color: #4d5564;
72+
}
5073
.docs-link {
5174
display: inline-flex;
5275
align-items: center;
@@ -103,6 +126,20 @@ a {
103126
.plugin-row:hover {
104127
background: #1d2025;
105128
}
129+
.plugin-row[hidden] {
130+
display: none;
131+
}
132+
133+
.no-matches {
134+
background: #181a1e;
135+
border: 1px solid #33373f;
136+
border-radius: 14px;
137+
padding: 30px 22px;
138+
margin-top: 12px;
139+
color: #6e7681;
140+
font-size: 14px;
141+
text-align: center;
142+
}
106143

107144
.col-name {
108145
display: flex;

0 commit comments

Comments
 (0)