Extract a shared combobox hook for SearchBox and TagPicker
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 52/100
- Issue type
- Refactor
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- react, typescript
- Domain
- accessibility, frontend, testing
Research direction
Start by locating SearchBox and TagPicker, then compare their existing combobox state, ARIA IDs, keyboard handlers, and focus-out behavior. Use SearchBox.test.tsx and TagPicker.test.tsx as the behavioral contract; done means the shared hook or adopted Command approach centralizes the contract without changing either widget's rendering and activation behavior, and both test suites pass.
Written by the indexing model from the issue text.
Description
Follow-up from PR #155 (ARIA correctness).
SearchBox and TagPicker now both implement the ARIA APG combobox-with-listbox pattern by hand: open / activeIndex state, clamped activeIdx, useId()-derived listbox/option ids, aria-activedescendant, wrapping ArrowUp/ArrowDown, Enter/Escape, guarded onMouseMove highlight, and close-on-focus-out. The two copies have already drifted in small ways (SearchBox swallows mousedown on the popup and closes on input blur; TagPicker uses a container onBlur + relatedTarget check with tabIndex={-1} options).
Extract a useCombobox hook (or adopt shadcn's Command) so the keyboard/ARIA contract lives in one place and the two widgets only differ in how they render options and what activation does. Keep the existing SearchBox.test.tsx / TagPicker.test.tsx as the behavioural contract.
🤖 Generated with Claude Code
- Dominant language
- TypeScript
- Stars
- 1
- Forks
- 1
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 25
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from CodeForPhilly/codeforphilly-ng
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
MarkdownEditor toolbar: use Radix Toolbar from radix-ui instead of the hand-rolled roving tabindex Openenhancement
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
All issues in CodeForPhilly/codeforphilly-ng
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
bug v2
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
modelcontextprotocol/inspector#2458 · 1 comment ·
-
Difficulty 1/5 Under an hour Newbie friendliness 75/100
railmapgen/rmp-gallery#4068 ·
-
Mend: dependency security vulnerability status: needs triage 🕵️♀️
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
carbon-design-system/ibm-products#9907 ·