KQ-1099 · SPLIT/CONFIRM
Split Confirm
A destructive button that asks by coming apart. Pressed, a crack runs down its middle and the halves part on a snap spring into Cancel and Confirm, with the crack left in the gap as a hairline countdown that heals from both ends; when it runs out the halves are thrown shut on the same snap and meet with a clack. Confirm fires once and latches, closing on a flick spring into a muted button that no longer presses. Focus moves to Confirm as it arrives, the arrow keys cross the halves, and Escape closes the question.
KQ-1099 · SPLIT/CONFIRM
release/2.14
Shipped 3 days ago · 42 commits
ready · the question stays open 4 s
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/split-confirm
Props
- label
- string
- default —
- The action, as the button reads before it is pressed.
- confirmLabel
- string
- default "Confirm"
- The right half's answer.
- cancelLabel
- string
- default "Cancel"
- The left half's answer.
- confirmedLabel
- string
- default "Done"
- What the latched button reads once the action is confirmed.
- confirmed / defaultConfirmed
- boolean
- default false
- Controlled or initial latch. Controlled, the latched face appears only once the host sets it; setting it back to false (an undo) restores the live button.
- onConfirm
- () => void
- default —
- Fires once, from the Confirm press.
- onCancel
- (reason: "cancel" | "timeout" | "escape") => void
- default —
- Fires when the question closes unanswered, with why.
- timeout
- number
- default 4
- Seconds the halves stay apart before they rejoin on their own.
- split
- "crack" | "slide"
- default "crack"
- A zigzag crack that snaps apart, or a clean seam that glides.
- tone
- "danger" | "neutral"
- default "danger"
- Destructive red, or the primary accent for confirms that are serious but not destructive.
- sound
- boolean
- default false
- Play the synthesised tink of the crack, the clack of the rejoin and the thock of the confirm. Nothing plays, and no audio context exists, unless this is on.
- disabled
- boolean
- default false
- Disables the button.
- className
- string
- default —
- Merged onto the root element's classes.
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | — | The action, as the button reads before it is pressed. |
| confirmLabel | string | "Confirm" | The right half's answer. |
| cancelLabel | string | "Cancel" | The left half's answer. |
| confirmedLabel | string | "Done" | What the latched button reads once the action is confirmed. |
| confirmed / defaultConfirmed | boolean | false | Controlled or initial latch. Controlled, the latched face appears only once the host sets it; setting it back to false (an undo) restores the live button. |
| onConfirm | () => void | — | Fires once, from the Confirm press. |
| onCancel | (reason: "cancel" | "timeout" | "escape") => void | — | Fires when the question closes unanswered, with why. |
| timeout | number | 4 | Seconds the halves stay apart before they rejoin on their own. |
| split | "crack" | "slide" | "crack" | A zigzag crack that snaps apart, or a clean seam that glides. |
| tone | "danger" | "neutral" | "danger" | Destructive red, or the primary accent for confirms that are serious but not destructive. |
| sound | boolean | false | Play the synthesised tink of the crack, the clack of the rejoin and the thock of the confirm. Nothing plays, and no audio context exists, unless this is on. |
| disabled | boolean | false | Disables the button. |
| className | string | — | Merged onto the root element's classes. |