📌 Description
The accessibility audit (design/accessibility-audit/findings/05-modals.md,
finding F-05-01, severity Critical, WCAG 2.4.3) documents that modals do not
restore focus to their trigger on close, and that focus/trap behavior is
re-implemented inconsistently per modal because there is no shared Dialog
primitive. Affected surfaces include CommitmentCreatedModal.tsx,
CommitmentDetailsModal.tsx, SettlementModal.tsx, and
CommitmentEarlyExitModal/.
This issue introduces a shared accessible Dialog and migrates modals onto it.
Goal: one tested Dialog primitive that traps focus, closes on Esc,
restores focus to the trigger, and is reused by every modal.
🎯 Requirements and Context
- Build a
Dialog that: captures document.activeElement on open, traps focus
while open, closes on Esc and backdrop click, and calls
previousActiveElement.focus() on close.
- Apply correct ARIA (
role="dialog", aria-modal, labelled title).
- Migrate
CommitmentCreatedModal.tsx, CommitmentDetailsModal.tsx,
src/components/modals/SettlementModal.tsx, and CommitmentEarlyExitModal.
- Satisfy the acceptance criteria in
design/accessibility-audit/acceptance-criteria.md and
component-spec-updates.md.
🛠️ Suggested Execution
1. Create a branch
git checkout -b feature/shared-dialog-primitive
2. Implement changes
- Add
src/components/ui/Dialog.tsx (+ module CSS).
- Migrate the modals listed above onto it.
- Add
src/components/__tests__/Dialog.test.tsx covering focus trap, Esc,
backdrop, and focus restoration; update affected modal tests.
3. Test and commit
- Run
npm test.
- Edge cases: no focusable children, nested modals, Esc vs backdrop close,
trigger removed before close.
Example commit message
fix: shared accessible Dialog primitive with focus restoration (F-05-01)
✅ Guidelines
- Minimum 95% test coverage on the Dialog and migrated paths.
- Clear documentation of the primitive's a11y contract.
- Timeframe: 96 hours.
🏷️ Labels
type-security · type-refactor · area-frontend · MAYBE REWARDED · GRANTFOX OSS · OFFICIAL CAMPAIGN
💬 Community & Support
- Join the CommitLabs contributor Discord: https://discord.gg/WV7tdYkJk
- Introduce yourself before starting to avoid duplicate work.
- Maintainers triage actively and review fast.
📌 Description
The accessibility audit (
design/accessibility-audit/findings/05-modals.md,finding F-05-01, severity Critical, WCAG 2.4.3) documents that modals do not
restore focus to their trigger on close, and that focus/trap behavior is
re-implemented inconsistently per modal because there is no shared
Dialogprimitive. Affected surfaces include
CommitmentCreatedModal.tsx,CommitmentDetailsModal.tsx,SettlementModal.tsx, andCommitmentEarlyExitModal/.This issue introduces a shared accessible
Dialogand migrates modals onto it.🎯 Requirements and Context
Dialogthat: capturesdocument.activeElementon open, traps focuswhile open, closes on
Escand backdrop click, and callspreviousActiveElement.focus()on close.role="dialog",aria-modal, labelled title).CommitmentCreatedModal.tsx,CommitmentDetailsModal.tsx,src/components/modals/SettlementModal.tsx, andCommitmentEarlyExitModal.design/accessibility-audit/acceptance-criteria.mdandcomponent-spec-updates.md.🛠️ Suggested Execution
1. Create a branch
2. Implement changes
src/components/ui/Dialog.tsx(+ module CSS).src/components/__tests__/Dialog.test.tsxcovering focus trap, Esc,backdrop, and focus restoration; update affected modal tests.
3. Test and commit
npm test.trigger removed before close.
Example commit message
✅ Guidelines
🏷️ Labels
type-security·type-refactor·area-frontend·MAYBE REWARDED·GRANTFOX OSS·OFFICIAL CAMPAIGN💬 Community & Support