suiss/ui · Pattern
Action Menu
A list of actions that opens as a dropdown menu on desktop and an action sheet on mobile.
Action Menu is an open-source pattern from suiss/ui for React. The @esuiss/ui CLI copies its source into your project, so you own the code.
ActionMenu renders a DropdownMenu on desktop and an AlertSheet below the 48rem breakpoint (useIsMobile). Each part switches to its matching component: items become DropdownMenuItems or AlertSheetActions, and the label becomes a menu label or the sheet title. On mobile, the content wraps the items in a grouped card and appends a Cancel button.
Use it for a short set of actions on a single object, such as editing, sharing or deleting a record, where an iOS-style action sheet suits touch screens.
Installation
CLI
Works in any project with a components.json. See Installation for the one-line registry setup. Or use the suiss/ui CLI:
Manual
-
Add the pieces it builds on: Alert Sheet, Dropdown Menu,
use-mobile. -
Copy the source into
components/patterns/action-menu.tsx:
- Update the import paths to match your project.
Usage
Pass render to ActionMenuTrigger to use your own button, for example a Button with variant="outline". open, defaultOpen and onOpenChange work on both layouts, so the menu can be controlled or uncontrolled. align, alignOffset, side and sideOffset on ActionMenuContent position the desktop popup and are ignored on mobile.
Examples
With icons
Places an icon before every action, including a destructive Delete item.
Not dismissible
Sets dismissible to false so the mobile sheet closes only through an action or Cancel.
API Reference
ActionMenu
The root that renders a DropdownMenu on desktop and an AlertSheet on mobile.
| Prop | Type | Default | Description |
|---|---|---|---|
onOpenChange | (open: boolean) => void | - | Called when the menu or sheet opens or closes. |
dismissible | boolean | true | When true, the mobile sheet closes on an outside press; when false, it uses an alert dialog that closes only through an action or Cancel. |
Also accepts the props of React.ComponentProps<typeof DropdownMenu>.
ActionMenuTrigger
The button that opens the menu or sheet.
| Prop | Type | Default | Description |
|---|---|---|---|
render | React.ReactElement | - | Replaces the default button element with your own element, such as a Button. |
Also accepts the props of React.ButtonHTMLAttributes<HTMLButtonElement>.
ActionMenuContent
The popup holding the actions; on mobile it adds a Cancel button below them.
| Prop | Type | Default | Description |
|---|---|---|---|
cancelLabel | string | "Cancel" | Text of the Cancel button shown below the actions on mobile. |
Also accepts the props of React.HTMLAttributes<HTMLElement>, React.ComponentProps<typeof DropdownMenuContent>.
ActionMenuLabel
A non-interactive heading; a menu label on desktop and the sheet title on mobile.
Also accepts the props of React.HTMLAttributes<HTMLElement>.
ActionMenuItem
An actionable entry that closes the menu when chosen.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "default" | "destructive" | - | Use destructive to style the item as a destructive action. |
disabled | boolean | - | Prevents the item from being chosen. |
Also accepts the props of React.HTMLAttributes<HTMLElement>.
On the aria base, respond to the item with onAction.
ActionMenuSeparator
A divider between groups of items, rendered on desktop only.
Also accepts the props of React.HTMLAttributes<HTMLElement>.
Accessibility
- On desktop the popup has the
menurole and each item has themenuitemrole. ArrowDownfrom the trigger opens the menu and focuses the first item; arrow keys move between items andEnterruns the focused one.Escapecloses the menu and returns focus to the trigger.
Notes
Parts carry data-slot values action-menu, action-menu-trigger, action-menu-content, action-menu-label, action-menu-item and action-menu-separator. ActionMenuSeparator renders nothing on mobile; the sheet groups items in a single card instead.