Skip to content

Add modal prop with focus trap to Drawer #37

@PosikBoy

Description

@PosikBoy

Objective

Currently, the Drawer component from @gravity-ui/navigation does not include a focus trap, which can cause accessibility (a11y) issues for keyboard and screen reader users: the focus can move outside the Drawer, and the Escape key does not always properly return focus to the opener element.

Goal: Introduce a modal: boolean prop that, when true, enables:

a focus trap inside the Drawer;

blocking interaction with the content behind the Drawer;

automatic return of focus to the element that opened the Drawer when closed;

support for Escape and veil click to close the Drawer.

Context: other modal components in the library (e.g., Popups/Modals) already follow this pattern, so implementing this via a modal prop ensures consistent API.

Solution Proposal

Add a modal: boolean prop to Drawer (and optionally DrawerItem).

When modal=true:

Wrap the Drawer content in a focus trap (custom or using focus-trap-react).

Implement cyclic keyboard navigation (Tab/Shift+Tab) within the Drawer.

Close Drawer on Escape or veil click.

Return focus to the element that opened the Drawer.

API example:

<Drawer modal onEscape={...} onVeilClick={...}>
  <DrawerItem visible>
    <p>Drawer content</p>
  </DrawerItem>
</Drawer>

Non-modal Drawer (modal=false) behaves as it currently does — no focus trap, no blocking of background content.

Definition of done

  • Modal: boolean prop added to Drawer API.
  • Focus trap works for all focusable elements inside the Drawer when modal=true.
  • Escape key and veil click properly close the Drawer.
  • Focus returns to the opener element after closing the Drawer.
  • Documentation updated with usage examples of modal.
  • Native navigation (Tab, Shift+Tab, Enter, Escape) works correctly in all modern browsers.
  • Implemented in at least two services/pages of the library for testing and demonstration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions