Skip to content

feat(filters-panel): keyboard navigation, re-render optimisation, unit + integration tests - #1298

Open
feyishola wants to merge 2 commits into
MettaChain:mainfrom
feyishola:feat/filters-panel-keyboard-nav-perf-tests
Open

feyishola wants to merge 2 commits into
MettaChain:mainfrom
feyishola:feat/filters-panel-keyboard-nav-perf-tests

Conversation

@feyishola

Copy link
Copy Markdown
Contributor

Closes #1223, closes #1224, closes #1225, closes #1226

Summary

Keyboard navigation (#1226)

  • Each checkbox group (Property type, Blockchain, Bedrooms, Bathrooms, Status) is a labelled role="group" with a roving tabindex, so the group is one Tab stop.
  • Arrow keys move between options and wrap. Home/End jump to the ends, and Space toggles.
  • Tabbing back into a group returns to the last focused option.
  • Escape clears the search query.
  • The panel is a role="search" landmark labelled "Property filters".

Re-render optimisation (#1225)

  • The form-wide useWatch subscription moved into a leaf (FilterAutoApply), so typing no longer re-renders the whole panel.
  • Each checkbox group is a memoized CheckboxGroupField that subscribes to its own field with useController, so a toggle re-renders only that group.
  • Option lists are module-level constants, and the components are wrapped in React.memo.
  • onApplyFilters fires only when the filters actually change.
  • When the parent echoes back the panel's own emit, the form no longer resets. This fixes an in-progress query being wiped when another filter round-trips through the store.

Tests (#1223, #1224)

  • SearchFilterForm.test.tsx: unit tests for rendering, emitting, debounce, Clear, and keyboard navigation.
  • SearchFilterForm.renders.test.tsx: re-render budget using a checkbox that counts its own renders. All three tests fail against the previous implementation.
  • SearchFilterForm.integration.test.tsx: the panel wired to the real useSearchStore, covering the control → store → props loop and a keyboard-only session.

Docs

  • New docs/filters-panel.md covering behaviour, keyboard support, and the re-render model.

Fixes to unblock CI

  • Regenerated package-lock.json. The lockfile on main had invalid JSON from a bad merge, so npm ci failed.
  • Removed src/stories/FilterSidebar.stories.tsx. It imported the deleted FilterSidebar and failed FilterUiConsolidation.test.tsx.

Test plan

  • npx jest src/components/forms: 36/36 pass
  • eslint clean on changed files
  • npm ci --dry-run succeeds with the regenerated lockfile
  • tsc: the repo-wide type errors on main remain. The only one in this file is the unchanged zodResolver(searchFilterSchema) line.

🤖 Generated with Claude Code

feyishola and others added 2 commits October 17, 2026 21:54
…tegration tests

- Roving-tabindex checkbox groups with Arrow/Home/End/Space, Escape clears query
- Isolate useWatch in a leaf, per-group useController + memo, dedupe emits
- Ignore parent echoes so in-progress query typing is not clobbered
- Unit, re-render budget and store-backed integration tests
- Add docs/filters-panel.md

Closes MettaChain#1223, closes MettaChain#1224, closes MettaChain#1225, closes MettaChain#1226

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The lockfile on main contained invalid JSON from a bad merge, breaking npm ci.
FilterSidebar.stories.tsx imported the removed FilterSidebar module and failed
FilterUiConsolidation.test.tsx.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@drips-wave

drips-wave Bot commented Oct 17, 2026

Copy link
Copy Markdown

@feyishola Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant