How to build an accessible ActionSheet in React
Renders role="menu" with role="menuitem" buttons under vertical roving focus (Arrow keys, Home/End, wrapping). The title labels the menu via aria-labelledby (or a built-in label otherwise) and the description via aria-describedby. FocusScope traps and restores focus; DismissableLayer handles Escape and outside-pointer dismissal; a separate Cancel button provides an explicit non-destructive exit.
When to use a ActionSheet
- A short list of discrete actions on a touch surface, rising from the bottom
- Confirming or choosing among a few operations (e.g. Share, Edit, Delete) on mobile
- A mobile-first alternative to an anchored dropdown menu when there is no trigger anchor
When not to use it
- A single yes/no confirmation — use AlertDialog
- A form or scrollable content — use BottomSheet or Sheet
- A menu anchored to a trigger on desktop — use Menu or Dropdown
Keyboard interactions
Role menu, verified at WCAG 2.2-AA.
ArrowUpArrowDownHomeEndEnterSpaceEscape
Common mistakes
Avoid: <ActionSheet actions={[{ label: "OK", onSelect }]} />
Prefer: <AlertDialog title="Delete item?" />
A one-action sheet is a confirmation; AlertDialog states the decision clearly
Example
<ActionSheet
open={isOpen}
onOpenChange={setIsOpen}
title="Share photo"
actions={[
{ label: 'Copy link', onSelect: copyLink },
{ label: 'Delete', onSelect: remove, destructive: true },
]}
/>