fix(blog): make featured article respect search match
The featured article previously hid whenever a query was active, regardless of whether it matched. Treat it as a normal [data-search] row instead: visible iff it matches the query, and counted toward visibleCount so a featured-only match no longer triggers the "no entries match" message. Closes the follow-up at docs/superpowers/follow-ups/2026-06-02-blog-search-featured-match.md and updates the design spec to match. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
82e5ff6309
commit
0a5a7d5e45
2 changed files with 6 additions and 14 deletions
|
|
@ -42,7 +42,7 @@ The inline script (~30 lines) does:
|
||||||
|
|
||||||
1. On `input`, normalize query: `value.toLowerCase().trim().split(/\s+/).filter(Boolean)`.
|
1. On `input`, normalize query: `value.toLowerCase().trim().split(/\s+/).filter(Boolean)`.
|
||||||
2. For each `[data-search]`: visible iff every token is a substring of its `data-search` value. Toggle `.is-hidden`.
|
2. For each `[data-search]`: visible iff every token is a substring of its `data-search` value. Toggle `.is-hidden`.
|
||||||
3. The featured block (marked `data-featured`) is additionally `.is-hidden` whenever the query is non-empty, independent of match.
|
3. The featured block (marked `data-featured`) is itself a `[data-search]` row, so it filters by the same match check — visible iff it matches the query. (Originally it hid whenever a query was active; changed per `docs/superpowers/follow-ups/2026-06-02-blog-search-featured-match.md` so featured behaves like any other filterable row.)
|
||||||
4. For each `[data-year-head]`: count visible siblings until the next year head; hide the head if zero.
|
4. For each `[data-year-head]`: count visible siblings until the next year head; hide the head if zero.
|
||||||
5. Toggle a no-results message (`<p data-empty>`) on/off based on whether any row is visible.
|
5. Toggle a no-results message (`<p data-empty>`) on/off based on whether any row is visible.
|
||||||
6. Empty query: clear `.is-hidden` from everything (including featured); hide the no-results message.
|
6. Empty query: clear `.is-hidden` from everything (including featured); hide the no-results message.
|
||||||
|
|
@ -103,7 +103,7 @@ Empty-state `<p>` reuses the `.count` style (mono 11px, `--fg-on-dark-3`).
|
||||||
| Whitespace-only query | Treated as empty: full archive restored. |
|
| Whitespace-only query | Treated as empty: full archive restored. |
|
||||||
| Tokens with regex-special chars | Safe — only `String.includes()` is used. |
|
| Tokens with regex-special chars | Safe — only `String.includes()` is used. |
|
||||||
| Query matches nothing | No-results message shown; all rows + year heads hidden. |
|
| Query matches nothing | No-results message shown; all rows + year heads hidden. |
|
||||||
| Single-post archive | Featured shows with empty query; non-empty query hides featured and the lone archive entry. Acceptable. |
|
| Single-post archive | Featured shows with empty query; a non-empty query keeps the featured (and lone archive entry) visible iff it matches. Acceptable. |
|
||||||
| JavaScript disabled | Input renders but does nothing; full archive visible. No regression. |
|
| JavaScript disabled | Input renders but does nothing; full archive visible. No regression. |
|
||||||
|
|
||||||
## Theme parity
|
## Theme parity
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,6 @@
|
||||||
const rows = Array.from(
|
const rows = Array.from(
|
||||||
document.querySelectorAll<HTMLElement>("[data-search]")
|
document.querySelectorAll<HTMLElement>("[data-search]")
|
||||||
);
|
);
|
||||||
const featured = document.querySelector<HTMLElement>("[data-featured]");
|
|
||||||
const yearHeads = Array.from(
|
const yearHeads = Array.from(
|
||||||
document.querySelectorAll<HTMLElement>("[data-year-head]")
|
document.querySelectorAll<HTMLElement>("[data-year-head]")
|
||||||
);
|
);
|
||||||
|
|
@ -103,18 +102,11 @@
|
||||||
let visibleCount = 0;
|
let visibleCount = 0;
|
||||||
for (const row of rows) {
|
for (const row of rows) {
|
||||||
const haystack = row.dataset.search ?? "";
|
const haystack = row.dataset.search ?? "";
|
||||||
const isFeatured = row === featured;
|
// The featured article is just another [data-search] row: it's
|
||||||
let visible: boolean;
|
// visible iff it matches the query, same as every archive row.
|
||||||
if (!isFiltering) {
|
const visible = !isFiltering || tokens.every((t) => haystack.includes(t));
|
||||||
visible = true;
|
|
||||||
} else if (isFeatured) {
|
|
||||||
// Featured hides whenever there's a query, regardless of match.
|
|
||||||
visible = false;
|
|
||||||
} else {
|
|
||||||
visible = tokens.every((t) => haystack.includes(t));
|
|
||||||
}
|
|
||||||
row.classList.toggle("is-hidden", !visible);
|
row.classList.toggle("is-hidden", !visible);
|
||||||
if (visible && !isFeatured) visibleCount += 1;
|
if (visible) visibleCount += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide year heads whose following rows are all hidden.
|
// Hide year heads whose following rows are all hidden.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue