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.
Harden the ConfirmDialog with focus trap, Escape, and overlay-dismiss
Description
src/components/ConfirmDialog.tsxrendersrole="dialog"witharia-modal="true"but does not trap focus, does not move initial focus into the dialog, does not close onEscape, 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
Escape(callingonCancel).onConfirm.role="dialog",aria-modal, andaria-labelledby="confirm-title"; addaria-describedbywhendescriptionis present.Suggested execution
git checkout -b a11y/dialog-28-focus-trapsrc/components/ConfirmDialog.tsx.src/components/__tests__/ConfirmDialog.test.tsxcovering focus, Escape, tab-trap, and backdrop dismiss.README.mdand component JSDoc.Test and commit
npm run lint,npm test, andnpm run build.npm testoutput and a11y notes in the PR description.Example commit message
feat: add focus trap, Escape, and overlay dismiss to ConfirmDialogGuidelines
Community & contribution rewards