crucıble

Plume

A celebration button: click it and a seeded plume of glowing sparks erupts upward, arcs out under gravity, and fades while the pill gives a satisfying squash-and-settle. Optionally latch into a success state with a settling checkmark. Seeded canvas particles torn down the instant they fade; under reduced motion the burst becomes a calm glow-and-check.

canvaspro

Installation

CLI

npx shadcn@latest add @crucible/plume

Props

PropTypeDefaultDescription
colorsstring[]["#fff7ed", "#fde68a", "#fbbf24", "#f59e0b"]Palette the burst samples from, one color picked per spark. Any CSS hex colors. Defaults to a warm champagne → gold ramp — celebration reads warm. Pass multiple bright hues for confetti.
intensitynumber1Master energy 0–2: scales spark count, size, and glow. 1 is a generous pop; push to 1.6+ for a firework.
speednumber1Multiplies launch velocity — how far the plume throws before gravity reels it back.
particleCountnumber34Base number of sparks at intensity 1 (the real count scales with intensity).
gravitynumber1400Downward acceleration in px/s² that arcs the sparks back down.
lifetimenumber1.1Seconds a spark lives before fading out (per-spark jittered).
spreadnumber150Width of the upward launch fan in degrees. 360 fires fully radial.
latchbooleanfalseLatch into a success state after the first celebration: a checkmark settles in and further clicks no longer re-burst (onClick still fires).
pausedbooleanfalseSuppress the burst and squash entirely — the button still clicks and latches.
onCelebrate() => voidFires each time a celebration triggers (before the burst draws).
maxParticlesnumber220Hard cap on live sparks; oldest are recycled beyond it.
Also accepts all props of React.ComponentPropsWithoutRef<"button">they pass through to the underlying element.

Honors prefers-reduced-motion with a designed static fallback, pauses offscreen and on hidden tabs, and passes className through.