Button
A clear, responsive action with quiet secondary states.
A destructive button that morphs into an inline confirmation, a spinner, and a result with undo.
npx shadcn@latest add @silicon-ui/confirm-morphnpx shadcn@latest add @silicon-ui/confirm-morphInstall the dependencies.
npm install lucide-react motionCopy these files into your project. Shared files are skipped if you already have them.
components/silicon-ui/confirm-morph/confirm-morph.tsxcomponents/silicon-ui/confirm-morph/confirm-morph.module.cssInstall the foundation once per app for the design and motion tokens: npx shadcn@latest add @silicon-ui/silicon-foundation
| Prop | Type | Default |
|---|---|---|
label*The resting label, such as "Delete project". | ReactNode | — |
iconA plain icon before the resting label. | ReactNode | — |
promptThe question shown while confirming, such as "Delete 3 files?". Defaults to the label with a question mark. | ReactNode | — |
confirmLabel | string | "Delete" |
cancelLabel | string | "Cancel" |
pendingLabelShown beside the spinner while `onConfirm` resolves. | string | "Deleting" |
doneLabel | string | "Deleted" |
errorLabel | string | "Couldn’t finish" |
retryLabel | string | "Retry" |
undoLabel | string | "Undo" |
undoingLabelShown beside the spinner while `onUndo` resolves. | string | "Restoring" |
tone`danger` (default) gives the confirm button the danger colour, for actions that destroy something. `neutral` gives it the accent, for important actions that can be reversed. The resting button is neutral either way. | "danger" | "neutral" | "danger" |
confirmMode`press` confirms on a press. `hold` asks for a press held for `holdDuration`. `countdown` confirms, then counts down `countdown` seconds that Cancel or Escape can still stop. | ConfirmMorphMode
| "press" |
holdDurationMilliseconds the confirm button must be held in `hold` mode. | number | 1000 |
countdownSeconds counted down before the action runs in `countdown` mode. | number | 3 |
countdownLabelText before the seconds in `countdown` mode, such as "Deleting in". Defaults to the pending label followed by "in". | string | — |
onConfirmRuns on confirm. Return a promise to show the pending face; a rejection shows the error face with Retry. | () => void | Promise<unknown> | — |
onUndoOffering it adds Undo to the result. Return a promise to show a pending face while it runs. | () => void | Promise<unknown> | — |
onCancel | () => void | — |
stateControlled state. Pair it with `onStateChange`. | ConfirmMorphState
| — |
defaultStateStarting state when uncontrolled. | ConfirmMorphState
| "idle" |
onStateChange | (state: ConfirmMorphState) => void | — |
confirmTimeoutMilliseconds before an unanswered question returns to rest. Resting the pointer on the control pauses it. 0 turns it off. | number | 6000 |
resultTimeoutMilliseconds a result stays before returning to rest. Resting the pointer on the control pauses it. 0 turns it off. | number | 5000 |
cancelOnOutsidePressA press outside the control cancels an open question. Defaults to true. | boolean | true |
disabled | boolean | false |
className | string | — |
refReceives the root element, which also takes focus while the action is pending. | Ref<HTMLDivElement> | — |