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