KQ-1098 · CONJURE/BUTTON
Conjure Button
A generate button whose own label is the material. Pressed, its letters lift off one after another and become glyph particles orbiting inside the pill on a glide spring while a band of light scans it; when the host's status says done, every particle condenses onto a letter of the new label on the same spring and a spark flares from the icon, and when it says error the orbit scatters and the pill shakes once on a tween. It is a native button: Space and Enter press it, its name is the current label, and it stays busy and focusable while the host works.
Release 2.14
14 merged changes since 2.13
ready · 14 changes · press to draft
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/conjure-button
Props
- status / defaultStatus
- "idle" | "working" | "done" | "error"
- default "idle"
- The run's state, owned by the host (controlled), or its initial state when uncontrolled. The button never decides it is finished.
- onStatusChange
- (status: ConjureStatus) => void
- default —
- Reports "working" from the press; uncontrolled, also "done" or "error" when the promise from onConjure settles.
- onConjure
- () => void | Promise<unknown>
- default —
- The work. Uncontrolled, a returned promise settles the run (resolve for done, reject for error); a plain return means the work is already done.
- label
- string
- default —
- The label at rest, before a run, and the button's accessible name then.
- workingLabel
- string
- default "Working"
- The accessible name and spoken status while the host works.
- doneLabel
- string
- default "Done"
- The finished label the particles condense into.
- errorLabel
- string
- default "Try again"
- The label after a failed run.
- particles
- number
- default 24
- How many glyphs the label comes apart into, 12 to 48.
- orbit
- number
- default 0.4
- Orbit speed in laps per second; the shimmer band sweeps with it.
- palette
- "aurora" | "mono" | "ember"
- default "aurora"
- The particles' colours: accent to signal, the button's own ink, or warn to danger.
- shimmer
- boolean
- default true
- Scan a band of light across the button while the host works.
- sound
- boolean
- default false
- Play the run's synthesised sounds: a shimmer and a rise on the lift, a chime on the spark, a thud on a failure. 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 |
|---|---|---|---|
| status / defaultStatus | "idle" | "working" | "done" | "error" | "idle" | The run's state, owned by the host (controlled), or its initial state when uncontrolled. The button never decides it is finished. |
| onStatusChange | (status: ConjureStatus) => void | — | Reports "working" from the press; uncontrolled, also "done" or "error" when the promise from onConjure settles. |
| onConjure | () => void | Promise<unknown> | — | The work. Uncontrolled, a returned promise settles the run (resolve for done, reject for error); a plain return means the work is already done. |
| label | string | — | The label at rest, before a run, and the button's accessible name then. |
| workingLabel | string | "Working" | The accessible name and spoken status while the host works. |
| doneLabel | string | "Done" | The finished label the particles condense into. |
| errorLabel | string | "Try again" | The label after a failed run. |
| particles | number | 24 | How many glyphs the label comes apart into, 12 to 48. |
| orbit | number | 0.4 | Orbit speed in laps per second; the shimmer band sweeps with it. |
| palette | "aurora" | "mono" | "ember" | "aurora" | The particles' colours: accent to signal, the button's own ink, or warn to danger. |
| shimmer | boolean | true | Scan a band of light across the button while the host works. |
| sound | boolean | false | Play the run's synthesised sounds: a shimmer and a rise on the lift, a chime on the spark, a thud on a failure. 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. |