Confirmation Core
useConfirmation, the hook every SureUI control is built on. Put click again, hold, slide and undo on any element.
// Nothing has run yet
Every SureUI control is built on one hook, useConfirmation. It owns the gesture rules, the timing, the undo window and the pending state. The controls only add labels and styling. Use it when you need a confirmation on something SureUI doesn't ship: a card, a toolbar icon, a keyboard shortcut or a canvas tool.
confirmation.ts comes with every SureUI item, so there's nothing extra to install.
import { useConfirmation } from "@/components/ui/sureui/confirmation"const { state, fillRef, getTriggerProps } = useConfirmation({ gesture: "hold", onConfirm: archiveProject,})<button {...getTriggerProps({})} data-state={state}> <span ref={fillRef} className="origin-left scale-x-0" /> Hold to archive</button>Spread getTriggerProps on the element people press. Pass your own handlers to it (getTriggerProps({ onClick })) rather than setting them next to it, so yours run first and the hook's still run. Put fillRef on an element to get the hold or slide fill; it animates the scale property from scale-x-0.
Icon button
An icon-only button that turns red and asks for a second click.
// Nothing has run yet
Keyboard shortcut
A shortcut is a trigger too. Here Backspace clicks the button, so pressing it twice deletes, the way terminals ask you to press Ctrl+C twice. Typing in a field is left alone.
// Nothing has run yet
useConfirmation(options)
| Prop | Type | Default |
|---|---|---|
| onConfirm | () => void | Promise<unknown> | required |
| onCancel | () => void | — |
| onConfirmError | (error: unknown) => void | — |
| gesture | "click" | "click-again" | "hold" | "slide" | "click" |
| undo | boolean | number | "manual" | false |
| pauseUndoOnHover | boolean | true |
| pauseUndoOnFocus | boolean | true |
| timeout | number | 3000 |
| duration | number | 1200 |
| holdFallback | "click-again" | "none" | "click-again" |
| armDelay | number | 0 |
| wait | number | 0 |
| disabled | boolean | false |
It returns:
state:"idle" | "armed" | "holding" | "undo" | "pending". Set it asdata-stateto style each state.failed:trueafteronConfirmfailed withonConfirmErrorset, until the next attempt.waiting: the seconds left whilewaitcounts down.fillRef: a ref for the fill element.getTriggerProps(props): your props with the gesture handlers composed in, plusdisabledwhile pending or waiting.
- The hook handles pointer, keyboard and focus: Space and Enter hold, a second activation confirms a hold or slide, and leaving the element cancels.
- Labels and announcements are yours. Change the visible text or
aria-labelwithstate, as the examples do, and announce armed and undo states in a polite live region.confirm-button.tsxshows how the built-in controls do it withuseConfirmationLabels.