Harden ConfirmDialog with focus trapping, Escape, and focus restoration
Description
src/components/ConfirmDialog.tsx renders a role="dialog" aria-modal="true" overlay, but it does not trap focus inside the dialog, cannot be dismissed with the Escape key, does not move focus into the dialog on open, and does not restore focus to the trigger on close. These are baseline WCAG 2.1 modal requirements. This issue makes the dialog keyboard-accessible.
Requirements and context
- Repository scope:
Agentpay-Org/Agentpay-frontend only.
- On open: move focus to the first focusable element (or the dialog), trap Tab/Shift+Tab within the dialog, and prevent background scroll.
- Bind Escape to
onCancel; clicking the backdrop may also cancel (configurable, but Escape is required).
- On close: restore focus to the element that was focused before opening.
- Keep the existing
aria-labelledby="confirm-title" and Confirm/Cancel buttons.
Suggested execution
- Fork the repo and create a branch
git checkout -b a11y/a11y-20-confirmdialog-focus-trap
- Implement changes
- Write code in:
src/components/ConfirmDialog.tsx — focus management via refs/effects.
- Write comprehensive tests in: create
src/components/__tests__/ConfirmDialog.test.tsx — assert focus moves in on open, Escape calls onCancel, Tab wraps, and focus returns to the trigger on close.
- Add documentation: document the focus/keyboard behaviour in a JSDoc block.
- Validate against WCAG 2.1 SC 2.1.2 (No Keyboard Trap, correctly) and 2.4.3 (Focus Order).
- Test and commit
Test and commit
- Run
npm run lint, npm run typecheck, npm test, and npm run build.
- Cover edge cases: dialog with a single focusable element, rapid open/close, and Escape while focus is on the backdrop.
- Include the
npm test output and a short a11y note.
Example commit message
fix(a11y): trap focus, handle Escape, and restore focus in ConfirmDialog
Guidelines
- Minimum 95 percent test coverage for the component.
- Clear, reviewer-focused documentation.
- Timeframe: 96 hours.
Community & contribution rewards
- 💬 Join the AgentPay community on Discord for questions, reviews, and faster merges: https://discord.gg/eXvRKkgcv
- ⭐ 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 ConfirmDialog with focus trapping, Escape, and focus restoration
Description
src/components/ConfirmDialog.tsxrenders arole="dialog"aria-modal="true"overlay, but it does not trap focus inside the dialog, cannot be dismissed with the Escape key, does not move focus into the dialog on open, and does not restore focus to the trigger on close. These are baseline WCAG 2.1 modal requirements. This issue makes the dialog keyboard-accessible.Requirements and context
Agentpay-Org/Agentpay-frontendonly.onCancel; clicking the backdrop may also cancel (configurable, but Escape is required).aria-labelledby="confirm-title"and Confirm/Cancel buttons.Suggested execution
git checkout -b a11y/a11y-20-confirmdialog-focus-trapsrc/components/ConfirmDialog.tsx— focus management via refs/effects.src/components/__tests__/ConfirmDialog.test.tsx— assert focus moves in on open, Escape callsonCancel, Tab wraps, and focus returns to the trigger on close.Test and commit
npm run lint,npm run typecheck,npm test, andnpm run build.npm testoutput and a short a11y note.Example commit message
fix(a11y): trap focus, handle Escape, and restore focus in ConfirmDialogGuidelines
Community & contribution rewards