Confirm Menu Item
A dropdown or context menu item that asks for a second click or a press and hold before it runs, with optional undo.
// Nothing has run yet
npx shadcn@latest add @sureui/confirm-menu-item
import { DropdownMenuContent } from "@/components/ui/dropdown-menu"import { ConfirmMenuItem } from "@/components/ui/sureui/confirm-menu-item"<DropdownMenuContent> <ConfirmMenuItem variant="destructive" onConfirm={deleteFile}> Delete </ConfirmMenuItem></DropdownMenuContent>The first click arms the item and the second confirms. The menu stays open until the action commits.
Hold
gesture="hold" works as on Confirm Button.
// Nothing has run yet
Undo
With undo, the item turns into Undo, and pressing it cancels and closes the menu. Closing the menu during the window commits the action, since the item unmounts with the menu.
With undo="manual", Undo stays until people move to another item, press outside it or close the menu.
// Nothing has run yet
Errors
onConfirmError, errorLabel and armDelay work as on Confirm Button. A failed item keeps the menu open and shows errorLabel, so the next activation tries again.
// Nothing has run yet
Context menu
Set menu="context" inside a ContextMenuContent.
// Nothing has run yet
ConfirmMenuItem
Extends the shadcn DropdownMenuItem, except closeOnClick. The table lists the props it adds.
| Prop | Type | Default |
|---|---|---|
| ...menuItemProps | DropdownMenuItem props | — |
| onConfirm | () => void | Promise<unknown> | required |
| onCancel | () => void | — |
| onConfirmError | (error: unknown) => void | — |
| gesture | "click" | "click-again" | "hold" | "click-again" |
| menu | "dropdown" | "context" | "dropdown" |
| closeOnConfirm | boolean | true |
| undo | boolean | number | "manual" | — |
| pauseUndoOnHover | boolean | true |
| pauseUndoOnFocus | boolean | true |
| confirmLabel | ReactNode | "Click again", or "Confirm" for a hold |
| undoLabel | ReactNode | "Undo" |
| errorLabel | ReactNode | — |
| armDelay | number | 0 |
| timeout | number | 3000 |
| duration | number | 1200 |
| holdFallback | "click-again" | "none" | "click-again" |
| announcements | { armed?, hold?, fallback?, undo?, error? } | — |
Data attributes
The item sets the same data-state values and data-error as Confirm Button.
- Moving the highlight to another item disarms it.
- Key repeat is ignored, so holding Enter can't arm and confirm at once.
- Each state change is announced in a polite live region. Change the text with
announcements.
WCAG
- 2.2.1 Timing Adjustable:
undo="manual"meets it, since Undo has no time limit. - 2.5.2 Pointer Cancellation:
gesture="hold"meets it, because releasing early or moving off the item cancels.