Skip to content

fix(a11y): expose modals/sheets as dialogs with focus + Escape - #33

Merged
EnesYilmazcode merged 1 commit into
mainfrom
claude/funny-hawking-930hed
Jul 15, 2026
Merged

EnesYilmazcode merged 1 commit into
mainfrom
claude/funny-hawking-930hed

Conversation

@EnesYilmazcode

Copy link
Copy Markdown
Owner

Fixes #15.

Problem

The two bottom sheets had no role/aria-modal, no focus management, and no Escape-to-close; the two modals duplicated a window-level Escape listener, which would double-close a modal stacked over a sheet.

(The scroll-bleed part of #15 is already prevented by the global body { position: fixed; overflow: hidden } lock added in the bottom-nav fix #21, so this pass covers the a11y/focus/Escape half.)

Fix

New shared useDialog hook:

  • Marks the element as a dialog (caller adds role="dialog" aria-modal="true").
  • Moves focus into it on open.
  • Closes on Escape via an element-level onKeyDown — so a modal opened over the sheet closes only itself, not both.
  • active keys the focus for the always-mounted AddToPlaylistSheet host (focus each time it opens, not once at startup).

All four overlays adopt it; the modals' hand-rolled Escape effects are removed (net de-duplication).

Verification

Built clean; behavioral test:

Check Result
Sheet has role=dialog + aria-modal, receives focus ✅
Escape closes the sheet ✅
Confirm modal over sheet: role=dialog, focused ✅
Escape closes only the modal, sheet stays open ✅
page errors none ✅

Note: this focuses the dialog container but doesn't implement a full Tab focus-trap — a reasonable follow-up, but out of scope here.

🤖 Generated with Claude Code


Generated by Claude Code

The two bottom sheets had no role/aria-modal, no focus management, and no
Escape-to-close, and the two modals duplicated a window-level Escape listener
(which would double-close a modal stacked over a sheet).

Add a shared useDialog hook: marks the element as a dialog (caller adds
role="dialog" aria-modal="true"), moves focus into it on open, and closes on
Escape via an element-level onKeyDown — so a modal opened over the sheet closes
only itself, not both. `active` keys the focus for the always-mounted
AddToPlaylistSheet host (focus each time it opens, not once at startup). All
four overlays now use it; the modals' hand-rolled Escape effects are removed.

(Background scroll bleed is already prevented by the global body lock from the
bottom-nav fix, so this pass is the a11y/focus/Escape half of the issue.)

Verified in-browser: each overlay is role=dialog + aria-modal, receives focus
on open, closes on Escape, and a confirm modal over the sheet closes only the
modal.

Fixes #15.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FkDKh1Uo1a4D7n5wCKdcKF
@EnesYilmazcode
EnesYilmazcode merged commit 7810e43 into main Jul 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants