Skip to content

feat: collapse Ask AI matched items by default#122

Merged
akifbayram merged 10 commits into
mainfrom
feat/ai-collapsed-items
May 9, 2026
Merged

feat: collapse Ask AI matched items by default#122
akifbayram merged 10 commits into
mainfrom
feat/ai-collapsed-items

Conversation

@akifbayram

Copy link
Copy Markdown
Owner

Summary

  • Hide matched items by default in Ask AI answer turns. Each bin row exposes a per-bin disclosure on the right that reveals the items inline; the existing "tap bin to open" behavior is preserved.
  • Three render modes selected per match by a pure helper that reads the existing server-emitted relevance string: header-only (empty bin, no pill), nav-disclosure (truncated — bin has items but the AI returned none, count pill navigates to bin detail), inline-disclosure (matched items, count pill expands inline).
  • Auto-expansion fires only when relevance starts with contains "..." and items.length === 1 — preserves the "found it" moment for single-item lookups (e.g. "where's my drill") without expanding multi-match results by default.

Architecture is client-only — no server schema, wire format, or executor changes. The decision logic lives in a new src/features/ai/matchDisplay.ts helper. The disclosure UI is a new BinDisclosurePill component (button in expand mode, span in nav mode). BinGroupHeader was refactored to accept a trailing slot plus an interactive flag for split-button rendering.

Notable details

  • Animation: items wrapper uses the grid-template-rows: 0fr ⇄ 1fr CSS trick (200ms ease-out, motion-reduce:transition-none). Inner <div className="min-h-0 overflow-hidden"> clips during collapse.
  • A11y: disclosure has aria-expanded + aria-controls, the <section> has aria-label="Items in {name}" and aria-hidden={!expanded}, and collapsed contents are excluded from the tab order via inert.
  • Hit targets: pill is min-h-[44px] min-w-[44px] per WCAG 2.5.5.
  • State: local useState per BinItemGroup instance; turns are keyed by match.bin_id in ItemQueryResults, so new questions correctly reset state.

Test plan

  • npx vitest run — 170 files / 1711 tests pass
  • npx tsc --noEmit — clean
  • npx biome check on changed files — clean
  • npx vite build — succeeds
  • Visual smoke (must run locally with npm run dev:all):
    • "show me pinned bins" → all collapsed with N items ▾ pill
    • "where's my drill" (single bin, single matched item) → auto-expanded
    • Multi-match query → independent expand state per bin
    • Tap bin name vs pill: only pill expands, only name navigates
    • Tab order skips collapsed items
    • DevTools prefers-reduced-motion: reduce → instant expand/collapse
    • Bulk-select inside an expanded bin still works

Files

New:

  • src/features/ai/matchDisplay.ts (+ tests)
  • src/features/ai/BinDisclosurePill.tsx (+ tests)

Modified:

  • src/features/ai/BinGroupHeader.tsx (+ tests) — adds trailing slot and interactive split mode
  • src/features/ai/BinItemGroup.tsx (+ tests) — wires the helpers, owns expand state
  • src/features/ai/__tests__/AiTurnQueryResult.test.tsx — adds mixed-mode integration test
  • src/features/ai/__tests__/QueryAnswerBody.test.tsx — fixture updated so item-name assertions remain meaningful with the new collapse default

akifbayram added 10 commits May 6, 2026 22:11
Apply review feedback from /simplify:
- Reuse plural() from @/lib/utils for the "+N more items" footer.
- Replace imperative inert ref callback with the JSX prop pattern used by
  the shared Disclosure component, plus aria-hidden on the collapsed
  section so AT consumers don't read clipped content.
- Extract isExpandable to remove the four repeated mode comparisons.
- Drop the redundant data-trashed on the interactive wrapper div; the
  inner open button still carries it for tests and styling hooks.
@akifbayram akifbayram merged commit 3ff8998 into main May 9, 2026
1 check passed
@akifbayram akifbayram deleted the feat/ai-collapsed-items branch May 9, 2026 02:02
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.

1 participant