Skip to content

Make the ConfirmDialog trap focus and close on Escape and overlay click #28

Description

@mikewheeleer

Harden the ConfirmDialog with focus trap, Escape, and overlay-dismiss

Description

src/components/ConfirmDialog.tsx renders role="dialog" with aria-modal="true" but does not trap focus, does not move initial focus into the dialog, does not close on Escape, and clicking the backdrop does nothing — all expected behaviours for an accessible modal. This issue makes it WCAG-compliant before it is wired into destructive flows.

Requirements and context

  • Repository scope: StableRoute-Org/Stableroute-frontend only.
  • On open, move focus to the first focusable control (or the dialog) and restore focus to the previously focused element on close.
  • Trap Tab/Shift+Tab within the dialog while open and close on Escape (calling onCancel).
  • Close when the backdrop (not the panel) is clicked, without triggering onConfirm.
  • Keep role="dialog", aria-modal, and aria-labelledby="confirm-title"; add aria-describedby when description is present.

Suggested execution

  • Fork the repo and create a branch
  • git checkout -b a11y/dialog-28-focus-trap
  • Implement changes
  • Test and commit

Test and commit

  • Run npm run lint, npm test, and npm run build.
  • Cover edge cases: open focus, Escape closes, Tab wraps, Shift+Tab wraps, backdrop click, and panel click does not close.
  • Include the full npm test output and a11y notes in the PR description.

Example commit message

feat: add focus trap, Escape, and overlay dismiss to ConfirmDialog

Guidelines

  • Minimum 95 percent test coverage for impacted modules.
  • Clear, reviewer-focused documentation.
  • Timeframe: 96 hours.

Community & contribution rewards

  • 💬 Join the StableRoute community on Discord for questions, reviews, and faster merges: https://discord.gg/37aCpusvx
  • ⭐ This is a GrantFox OSS / Official Campaign task and may be rewarded. When your PR is merged you'll be prompted to rate the project — if this issue and the maintainers helped you ship, we'd be grateful for a 5-star rating. Clear questions in Discord and tidy, well-tested PRs are the fastest path to a merge and a reward.

Metadata

Metadata

Assignees

No fields configured for Feature.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions