Hold to confirm
A delete you can't hit by accident. Press and hold, and colour fills the key from the start while it trembles, barely at first and harder toward the end. Let go early and the fill drains back. Hold to the end and it confirms with a pop.
Installation
npx @neelshha/ui@latest add hold-to-confirmUsage
import { HoldToConfirm } from "@/components/ui/hold-to-confirm";
<HoldToConfirm onConfirm={remove} doneLabel="Deleted">
Hold to delete
</HoldToConfirm>It's for actions that are hard to undo but common enough that a dialog would nag. The fill runs at a steady rate, so it shows how much longer to hold. Say "hold" in the label: nothing else tells people a click won't do.
Tones
Red for deleting, the blue key for shipping, ink for signing. A longer duration makes it a more deliberate act.
<HoldToConfirm tone="key" doneLabel="Deployed" onConfirm={deploy}>
Hold to deploy
</HoldToConfirm>
<HoldToConfirm
tone="ink"
duration={2500}
doneLabel="Signed"
onConfirm={sign}
>
Hold to sign
</HoldToConfirm>From a shortcut
held lets a shortcut of your own hold it. This one holds while D is down.
or hold D
// True while D is down, from your own key listener.
<HoldToConfirm held={holdingD} onConfirm={remove}>
Delete
</HoldToConfirm>Keyboard
Hold Space or Enter while it has focus. Screen readers and switch controls click without pressing first, and they can't hold, so that kind of click confirms at once. The label has to say what the button does.
API
Other props go to the button. A long press on a touch screen won't open a menu partway through the hold. With reduced motion it doesn't tremble or pop, but the hold still takes the whole duration. It's a safeguard, not motion.
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | The label, like "Hold to delete". | |
onConfirm | () => void | Runs once a hold lasts the whole duration. | |
duration | number | 1500 | How long to hold, in milliseconds. |
doneLabel | ReactNode | Shown for a moment once it confirms. | |
held | boolean | false | Holds it from outside, for a shortcut of your own. After a confirm it has to go false before it can hold again. |
tone | "danger" | "key" | "ink" | "danger" | The colour it fills with. |