Skip to content

feat(a11y): add opt-in backdrop-click cancel to ConfirmDialog#189

Merged
mikewheeleer merged 1 commit into
Agentpay-Org:mainfrom
ekwe7:Give-the-ConfirmDialog-backdrop-an-accessible-cancel-affordance
Jun 27, 2026
Merged

feat(a11y): add opt-in backdrop-click cancel to ConfirmDialog#189
mikewheeleer merged 1 commit into
Agentpay-Org:mainfrom
ekwe7:Give-the-ConfirmDialog-backdrop-an-accessible-cancel-affordance

Conversation

@ekwe7

@ekwe7 ekwe7 commented Jun 27, 2026

Copy link
Copy Markdown

closes #92

Add Optional, Accessible Backdrop-Click Dismissal to ConfirmDialog

Summary

This PR adds an opt-in backdrop-click dismissal mechanism to ConfirmDialog while preserving the component's existing accessibility guarantees and keyboard interactions.

A new dismissOnBackdrop prop allows consumers to enable modal dismissal by clicking outside the dialog panel. The implementation ensures that only genuine backdrop interactions trigger cancellation and that clicks originating inside the dialog do not.

Problem

ConfirmDialog already provides:

  • Focus trapping
  • Escape-key dismissal
  • Focus restoration
  • Proper dialog semantics

However, the backdrop is currently non-interactive. Users who expect modal dialogs to close when clicking outside the dialog panel have no way to do so, and consumers cannot opt into this behavior.

Solution

Introduced an optional:

dismissOnBackdrop?: boolean

prop that enables backdrop-click cancellation.

When enabled:

  • Clicking the backdrop invokes onCancel
  • Clicking inside the dialog panel does not trigger cancellation
  • Focus trapping remains intact
  • Escape key behavior remains unchanged
  • Focus restoration continues to function correctly

When disabled:

  • Backdrop clicks are ignored
  • Existing behavior remains unchanged

Changes

ConfirmDialog

Updated:

src/components/ConfirmDialog.tsx

Changes include:

  • Added dismissOnBackdrop prop
  • Added backdrop interaction handling
  • Ensured dialog panel clicks do not trigger backdrop dismissal
  • Preserved existing modal accessibility semantics
  • Preserved focus trap implementation
  • Preserved focus restoration behavior

Tests

Extended:

src/components/__tests__/ConfirmDialog.test.tsx

Added coverage for:

  • Backdrop click triggers cancel when enabled
  • Backdrop click does not trigger cancel when disabled
  • Dialog panel clicks do not trigger cancel
  • Escape key dismissal continues to work
  • Focus trap behavior remains intact
  • Focus restoration remains intact

Documentation

Updated component JSDoc to document:

  • dismissOnBackdrop
  • Expected behavior
  • Accessibility considerations

Accessibility Considerations

The implementation preserves:

  • role="dialog"
  • aria-modal
  • aria-labelledby
  • Keyboard accessibility
  • Escape-key dismissal
  • Focus trapping
  • Focus restoration

Backdrop interaction is additive and does not replace existing accessible dismissal methods.

Users can continue to dismiss the dialog using:

  • Escape
  • Cancel button
  • Backdrop click (when enabled)

This ensures that backdrop interaction is never the sole dismissal mechanism.

Edge Cases Covered

  • Backdrop click with dismissOnBackdrop={false}
  • Backdrop click with dismissOnBackdrop={true}
  • Clicks originating inside the dialog panel
  • Escape key while dialog is open
  • Focus restoration after dismissal
  • Focus trap integrity during interaction

Validation

Executed:

npm run lint
npm run typecheck
npm test
npm run build

Acceptance Criteria

  • Added dismissOnBackdrop prop
  • Backdrop click invokes onCancel when enabled
  • Dialog panel clicks do not trigger cancellation
  • Focus trap remains functional
  • Escape handling remains functional
  • Focus restoration remains intact
  • Existing dialog accessibility attributes preserved
  • Comprehensive tests added
  • JSDoc updated
  • High component test coverage maintained

@mikewheeleer

Copy link
Copy Markdown
Contributor

nice a11y touch — opt-in backdrop-click cancel is the right default. lgtm 🙌

@mikewheeleer mikewheeleer merged commit 4b5f605 into Agentpay-Org:main Jun 27, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Give the ConfirmDialog backdrop an accessible cancel affordance

3 participants