a11y: add keyboard focus-trap to shared Modal (Tab cycling within dialog) #1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Background
While shipping the venue-page "Request to book" hero button (opens the booking-request form in a dialog), we hardened the shared Modal's accessibility. The following landed in
packages/ui/src/ui/tamagui/components/overlay/Modal.tsx:role="dialog"+aria-modal="true"on the panel containeraria-labelledbytied to the Modal header title (guarded so header-less consumers don't emit a dangling reference)What's deferred (this issue)
A full keyboard focus-trap — constraining Tab / Shift+Tab to cycle within the open dialog instead of moving into the background page — was intentionally deferred.
aria-modal="true"means assistive tech already treats the background as inert, but the DOM tab order is not yet constrained, so a sighted keyboard user can Tab out of the dialog into the page behind it.It was deferred because
Modalis a shared primitive with 30+ consumers (auth overlays, admin gates, broadcast composer, claim wizard, ask/manage views, etc.), and a naive trap risks regressing consumers that manage their own focus. It needs its own scoped pass.Scope / acceptance criteria
ClaimVenueWizardfocuses its heading;AdminEmailVerificationGateis header-less).prefers-reduced-motion(no change expected, just don't regress).Pointers
packages/ui/src/ui/tamagui/components/overlay/Modal.tsx— the component; see the recently addedrole/aria-modal/aria-labelledby/focus-in/focus-return logic to build on.OverlayHost,AppOverlayProvider,SignInOverlay,UnifiedAuthOverlay,BroadcastComposer,AskManageView.Priority: low/medium (a11y polish;
aria-modalmitigates the AT case today).