crucıble

Beacon

A dynamic-island status pill that fluidly morphs between size presets — a minimal indicator, a compact row, a wide media bar, and a tall card. Width, height, and corner radius are spring-coupled as one liquid shape that overshoots ~1% and beads down like mercury, while the content restacks in lockstep, the outgoing line sliding down and under the incoming. Sequenceable for guided flows, keyboard-expandable, and announced through an aria-live status region.

motionpro

Installation

CLI

npx shadcn@latest add @crucible/beacon

Manual — install dependencies, then copy the source

npm install motion

Props

PropTypeDefaultDescription
statesBeaconState[]a connecting → connected → live setThe states this beacon can morph between.
valuestringControlled active state id. Pair with onValueChange.
defaultValuestringfirst stateInitial active state id when uncontrolled.
onValueChange(id: string) => voidFires whenever the active state changes, from any source.
sequenceBeaconSequenceStep[]Ordered steps for a self-running flow, driven by play() or autoPlay.
autoPlaybooleanfalseStart the sequence automatically on mount.
loopbooleanfalseLoop the sequence instead of stopping at the last step.
onSequenceEnd() => voidFires when a non-looping sequence reaches its end.
stepDurationnumber2200Fallback dwell per step, in ms, when a step omits duration.
speednumber0.50–1 morph responsiveness — higher springs snappier between sizes.
intensitynumber0.50–1 mercury-bead overshoot on settle. 0 lands critically damped; 0.5 gives the signature ~1% overshoot before it beads down.
expandablebooleantrueAllow Enter/Space/click to expand a state that has a body.
pausedbooleanfalsePause the running sequence and freeze the live indicator.
politeness"polite" | "assertive""polite"Live-region politeness for status announcements.
colors{ /** Live-status indicator accent. @default "#5eead4" */ accent?: string; /** Pill shell fill. @default "#0b0b0d" */ shell?: string; /** Primary text color. @default "#f4f4f5" */ text?: string; }Colors — one cool accent over a neutral near-black shell.
sizesPartial<Record<BeaconSize, Partial<BeaconDimensions>>>Per-size geometry overrides.
Also accepts all props of Omit<React.ComponentPropsWithoutRef<"div">, "children" | "onChange">they pass through to the underlying element.

Honors prefers-reduced-motion with a designed static fallback, and passes className through.