Skip to content

Shared filtered-list primitive (six pages hand-roll search) #87

Description

@ApocDev

At least six pages implement their own list filtering with a local useState plus toLowerCase().includes(...): routes/turd.tsx, routes/coherence.tsx, routes/factory.tsx, routes/block.tsx, routes/settings.tsx, routes/browse.tsx, and two more pickers inside routes/block.$id.tsx. Behavior drifts between them (what fields are matched, whether internal names match, ranking, empty-result text).

What to do

  • Extract one shared primitive — a useFilteredList hook plus a search-input component — that standardizes: match against localized display names (and internal names as a hidden fallback), ranking via @tanstack/match-sorter-utils (already a dependency), and a consistent "no matches for X" empty state.
  • Adopt it across the pages above; per-page column/field choices stay local.
  • The command palette (Command palette: Ctrl+K / / search-everything #78) needs the same matching behavior, so building the primitive first (or extracting it from the palette work) avoids a third implementation.

Part of the polish epic #35.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: webWeb UI (React/TanStack/vite-plus)enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions