Components / Actions
HoldToConfirm
Confirm a destructive action by holding, not tapping.
Install
npx shadcn@latest add https://irisui.dev/r/hold-to-confirm.jsonimport { HoldToConfirm } from "@/components/iris/hold-to-confirm/hold-to-confirm";Preview
HoldToConfirm
A button that commits only after it is held: a fill tracks the hold, letting go early rewinds it, and finishing morphs the label and icon into a done state.
When to use
- Destructive or hard-to-undo actions where a stray tap must not count — deleting a project, rotating a key, sending to a large list.
- When the consequence is already visible on screen, so no extra reading is needed.
- When people need to read consequences first, use a confirmation dialog. For an inline ask-then-undo flow, use
ConfirmMorph.
Usage
import { HoldToConfirm } from "@/components/iris/hold-to-confirm/hold-to-confirm";
<HoldToConfirm
label="Hold to delete project"
confirmedLabel="Project deleted"
tone="danger"
duration={1200}
onConfirm={() => api.deleteProject(id)}
onHoldChange={(holding) => setHint(holding ? "Keep holding" : "")}
/>;
Props
| Prop | Type | Default | Description |
|---|---|---|---|
label |
string |
— | The instruction and the action (required), e.g. "Hold to delete project". |
onConfirm |
() => void |
— | Called once when the hold completes (required). |
confirmedLabel |
string |
"Done" |
Shown after the hold completes. |
duration |
number |
1200 |
Hold length in ms. |
icon |
ReactNode |
trash icon | Icon before the label. |
tone |
"accent" | "danger" | "neutral" |
"accent" |
Fill colour: the accent, --red, or ink. |
confirmed |
boolean |
— | Controls the done state; set back to false to reset. Leave undefined to let the button keep its own state. |
onHoldChange |
(holding: boolean) => void |
— | Reports hold start/end, for hints such as "Keep holding". |
...props |
ButtonHTMLAttributes |
— | Other native attributes (not children or onClick). |
Notes
- Space and Enter can be held too; key repeat is ignored. A live region (
<output>) announces the result and the button is described by a hold hint. - The fill runs on a linear timeline so progress reads honestly; release rewinds on a spring. Reduced motion keeps the hold but drops the morph motion.
- Always phrase the label as the instruction ("Hold to …"), since there is no separate hint by default.