Skip to content

Modals have no focus trap and do not restore focus on close #96

Description

@yash-sangwan

The hand-rolled modals share the same accessibility gaps:

  • no role="dialog" and no aria-modal="true", so screen readers do not announce them as dialogs
  • no focus trap, so Tab walks straight out of the modal into the page behind it while the backdrop still blocks the mouse
  • focus is never returned to the trigger on close, so keyboard users land back at the top of the document
  • the preview modal never moves focus into itself at all
  • the create-folder dialog puts its Escape handler on an inner div, so Escape only works while focus happens to be inside it
  • the preview modal backdrop is a clickable <div> with no keyboard equivalent

@radix-ui/react-dialog is already a dependency and shared/components/ui/dialog.tsx wraps it, so most of this is solved by using what we have.

Where:

  • frontend/src/components/file-preview/file-preview-modal.tsx
  • frontend/src/features/dashboard/components/ui/dialogs/create-folder-dialog.tsx
  • frontend/src/features/dashboard/components/views/search/advance-search-sheet/advanced-search-sheet.tsx
  • frontend/src/features/upload/components/duplicate-dialog.tsx
  • frontend/src/shared/components/ui/dialog.tsx

What to do:

  • Port these onto the Radix dialog primitive, which gives focus trap, focus restore, Escape, and the ARIA wiring
  • Where a custom modal has to stay, add role="dialog", aria-modal, aria-labelledby, focus-on-open, and focus-restore-on-close
  • Move Escape handling to a document listener rather than a element-scoped one

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions