docs(spec): tag selector search in CatalogSearchOverlay
Captures approved design: in-sidebar typing-to-filter input, case-insensitive substring match, hidden when tags <= 8, selected tags filtered out stay active as header pills. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
# Tag Selector Search in CatalogSearchOverlay
|
||||
|
||||
**Date:** 2026-04-23
|
||||
**Status:** Approved, ready for implementation
|
||||
|
||||
## Problem
|
||||
|
||||
The tag filter in the global catalog search overlay (`src/client/components/CatalogSearchOverlay.tsx`) renders every tag as a chip in a narrow sidebar. When the tag taxonomy grows, users must scroll through the full list to find the one they want. There is no typing-to-filter affordance.
|
||||
|
||||
## Goal
|
||||
|
||||
Allow users to narrow the visible tag list by typing a query, without disrupting selection or the surrounding filter UX.
|
||||
|
||||
## Scope
|
||||
|
||||
Single-file change to `src/client/components/CatalogSearchOverlay.tsx`. No backend changes. No new dependencies. No shared component extraction.
|
||||
|
||||
## Behavior
|
||||
|
||||
**Search state**
|
||||
|
||||
- Add a `tagSearch: string` local state, defaulting to `""`.
|
||||
|
||||
**Input rendering**
|
||||
|
||||
- Render a compact text input at the top of the "Tags" section inside the filter sidebar (above the existing tag chip list).
|
||||
- Style to match the existing minimalist look: similar to the main catalog search input but narrower and with reduced padding so it fits the 224px sidebar.
|
||||
- Render the input only when `tags.length > 8`. Below that threshold scrolling isn't an issue and the extra chrome is noise.
|
||||
- Placeholder text: `Filter tags...`.
|
||||
|
||||
**Filter logic**
|
||||
|
||||
- Compute the visible tag list as: tags whose `name` includes `tagSearch` (case-insensitive substring match).
|
||||
- A selected tag that does not match the query is hidden from the sidebar list. It remains active and visible as a blue pill in the header row (existing behavior — no change required).
|
||||
- When the filter produces zero visible tags, render a small muted hint: `No tags match`.
|
||||
|
||||
**Reset**
|
||||
|
||||
- When the overlay closes, reset `tagSearch` to `""` by extending the existing reset `useEffect` at lines 84–98.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- No fuzzy matching or ranking — plain case-insensitive substring is sufficient.
|
||||
- No keyboard navigation of the tag list (arrow keys / Enter to toggle). Users click chips.
|
||||
- No persistence of `tagSearch` across overlay open/close cycles.
|
||||
- No changes to the active-pill row, active-filter counting, or weight/price range filters.
|
||||
- No unit tests — pure UI state, covered by manual UAT verification during milestone close-out.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
1. Typing in the tag search input immediately narrows the visible tag chips by case-insensitive substring match on tag name.
|
||||
2. Tags that are selected but no longer match the query disappear from the sidebar list and remain selected (visible as blue pills in the header).
|
||||
3. With 8 or fewer tags, the search input is not rendered.
|
||||
4. With more than 8 tags and a query that matches none of them, a `No tags match` hint is shown.
|
||||
5. Closing the overlay and reopening it shows an empty tag search input.
|
||||
6. No regressions to other filter behavior (weight range, price range, active filter pills, clear-all).
|
||||
|
||||
## Files touched
|
||||
|
||||
- `src/client/components/CatalogSearchOverlay.tsx`
|
||||
|
||||
## Out of scope for this spec
|
||||
|
||||
- Tag selector in other components (admin items list, etc.).
|
||||
- Any server-side tag search or query.
|
||||
- Hierarchy-aware filtering (parent match reveals children, etc.) — tags are consumed flat from `useTags()` in this component.
|
||||
Reference in New Issue
Block a user