fix(portals): make facet chips keyboard-operable and reject zero years

- The chips were plain spans with a click handler, so the whole feature
  was mouse-only. Actionable chips are <button> now (focusable, Enter and
  Space activate); a year chip that cannot be discovered by stays an
  informational span rather than becoming a disabled button. The button
  chrome is neutralized so they render identically to the chips beside
  them, with a visible focus ring.

- `0000-00-00`, the placeholder providers ship for "no date", read as a
  four-digit year: the chip offered it, and the request then dropped the
  filter because 0 is falsy, so the page answered with unfiltered popular
  titles. `isTmdbYearFacet()` now gates both the chip and the route
  params, so a deep link cannot reach a state the chips refuse to offer.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Fable 5 committed 2026-08-16 08:45:31 +02:00
1 parent 065437b378
commit 8a7a7ba8b0
11 files changed
+164 -60

No files matched your search

@@ -119,6 +119,18 @@ export interface TmdbCountryFacet {
name: string;
}
/**
* Whether a number is a year the Discover page can actually filter by.
*
* Providers ship `0000-00-00` as their "no date" placeholder, which reads
* as a four-digit year and would otherwise produce a `0000` chip that
* filters by nothing. Shared by the chip side and the route-param side so
* a deep link cannot smuggle in what a chip refuses to offer.
*/
export function isTmdbYearFacet(year: number): boolean {
return Number.isInteger(year) && year >= 1000 && year <= 9999;
}
/**
* One cached TMDB lookup. Two kinds of rows share the table, discriminated
* by the `lookupKey` prefix: