Skip to content

fix(distribution-toolbar): add focus trap and fix RTL positioning closes #437 - #578

Open
Sycosmile wants to merge 2 commits into
RevoraOrg:masterfrom
Sycosmile:uiux/distribution-filter-toolbar
Open

fix(distribution-toolbar): add focus trap and fix RTL positioning closes #437#578
Sycosmile wants to merge 2 commits into
RevoraOrg:masterfrom
Sycosmile:uiux/distribution-filter-toolbar

Conversation

@Sycosmile

Copy link
Copy Markdown

Context

DistributionFilterToolbar already exists on master (built for #214) and is
wired into DistributionDashboard.tsx with full URL-param sync. This PR does
not rebuild the toolbar — it closes the two gaps #437 calls out that #214
missed: keyboard focus loops and RTL wrapping, plus a few smaller a11y gaps
found along the way.

Changes

  • new src/hooks/useFocusTrap.ts — focus-trap + return-focus hook, used
    by every popover panel and the mobile sheet
  • DistributionFilterToolbar.tsx — wires in the hook, adds an aria-live
    status region, id/aria-controls linking triggers to panels, hides
    decorative emoji from AT, mobile trigger now literally reads Filters (n)
  • DistributionFilterToolbar.css — converted physical CSS properties to
    logical ones (inset-inline-*, padding-inline-*, border-inline-*);
    fixed the presets panel's un-flippable inline right: 0 positioning;
    removed a pre-existing RTL rule that was actually double-flipping pill
    order back to LTR
  • new DistributionFilterToolbar.a11y-rtl.test.tsx /
    useFocusTrap.test.tsx — cover focus trap/return-focus, RTL rendering,
    many-active-filters, and the remaining branches needed for 95%+ coverage
  • vite.config.ts — added both new files to the coverage include/
    thresholds lists (95%), since neither was tracked before

Verified locally

  • npm run lint — clean
  • npx tsc --noEmit — clean
  • npx vitest run (scoped) — 40/40 passing
  • Coverage: DistributionFilterToolbar.tsx 100% lines/stmts/funcs, 99.4%
    branches; useFocusTrap.ts 100% across the board
  • Existing DistributionFilterToolbar.test.tsx (15 tests) untouched, still
    passing unmodified

Manual QA

  • Tab through each popover — focus stays inside, wraps both ends
  • Escape closes a popover, focus returns to its trigger
  • Open/close the mobile sheet (<768px) — focus returns to Filters (n)
  • <html dir="rtl"> — popovers anchor correctly, pills read in the same
    logical order, no icon/text overlap in search
  • axe DevTools scan with a popover open and with the mobile sheet open

Note for maintainers (unrelated, found while testing)

src/pages/DistributionDashboard.tsx currently fails to parse for coverage
on master (Rollup: Expected ',', got '{') during a full unscoped
vitest run. Pre-existing, not touched by this PR — flagging separately.

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