Skip to content

feat(deck): search bar to filter cards by artist or title - #36

Merged
damarals merged 1 commit into
mainfrom
feat/32-deck-search-filter
May 10, 2026
Merged

damarals merged 1 commit into
mainfrom
feat/32-deck-search-filter

Conversation

@damarals

Copy link
Copy Markdown
Owner

Closes #32

Summary

  • Adds a fixed search TextInput to the unified deck page (app/deck/[id].tsx) that lives inside the FlatList's ListHeaderComponent, so it scrolls with the list rather than floating.
  • Live-filters the merged kept/dropped row list by case-insensitive substring match against artist OR title, composed on top of the existing kept/skipped pill filter.
  • Adds a "No cards match '<query>'" empty-state row, shown only when the query is non-empty.

Implementation notes

  • Filter chain: (filter === 'all' ? rows : rows.filter(r => r.kind === filter)).filter(r => rowMatchesQuery(r, needle)). Existing pill semantics preserved; search composes on top.
  • Single helper rowMatchesQuery(row, needle) covers both kept (Card) and dropped (DroppedTrack) rows since both share artist/title fields, so the dropped-tracks list is filtered by the same pass through the unified DeckRow[].
  • Search input kept inline (not extracted to a CardSearchInput atom): only one usage, no reuse value.
  • Design tokens: bg-navy800 (Tailwind class wired to tokens.colors.navy800), tokens.colors.navy50 for input text, Nunito_600SemiBold 13px (matches the body weight loaded in app/_layout.tsx; Nunito_500Medium is not loaded).
  • Filter is purely visual: editingIsrc is keyed by ISRC, so year-override edits still apply correctly to filtered-out cards. PDF export and drops state are untouched.
  • Kept pill block remains gated on hasDrops (the existing droppedCount > 0 semantics) — only the ListHeaderComponent wrapper is now always rendered (to host the search input).

Test plan

  • npm run typecheck clean
  • npm run lint clean
  • npm test — 143/143 passing
  • Manual: open a deck, type a query, confirm live filter on artist and title (case-insensitive), clearing restores list.
  • Manual: with drops present, confirm pill + search compose (e.g., kept + "queen").
  • Manual: with drops present, confirm dropped-tracks rows are filtered by the same query.
  • Manual: type a non-matching query, confirm No cards match "..." row appears.
  • Manual: edit a year override on a card; with that card filtered out, confirm the override still persisted.

@damarals
damarals merged commit 0e547d8 into main May 10, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Search bar on deck page to filter cards by artist or title

1 participant