crucıble

Primer

Multi-step onboarding wizard in a card: a numbered step rail whose track fills to the current step (completed nodes draw a check, reached steps stay clickable), direction-aware sliding step bodies with a springing card height, and schema-driven step kinds — name + role chips, workspace name with a live typed slug preview and async availability check, email-chip invites with a role, preference toggle cards, and a review summary with Edit jumps. Per-step validation shakes and explains, Enter advances, Back keeps answers, and Finish fires a spark burst and onComplete(values).

motionpro

Installation

CLI

npx shadcn@latest add @crucible/primer

Manual — install dependencies, then copy the source

npm install motion

Props

PropTypeDefaultDescription
stepsPrimerStep[]Ordered step schema. Omit for Welcome → Workspace → Invite → Preferences → Done.
initialStepnumber0Step index to open on. Earlier steps count as reachable.
defaultValuesPartial<PrimerValues>Initial answers (merged over empty defaults).
onComplete(values: PrimerValues) => void | Promise<unknown>Called with every answer when the person presses Finish. Return a Promise to hold the button pending — resolve shows the success state (with a spark burst), reject shows the rejection's message inline.
onStepChange(index: number, step: PrimerStep) => voidFires whenever the visible step changes, with its index and schema entry.
onChange(values: PrimerValues) => voidFires whenever any answer changes.
validatePrimerValidatea simulated check that rejects a few reserved wordsAsync slug availability check.
domainstring"app.example.com"Host shown in the live URL preview.
accentColorstring"#34d399"Signature accent for the rail, primary button, focus rings and sparks.
refReact.Ref<PrimerHandle>Imperative handle (goTo(i), reset(), replay()). React 19 ref-as-prop.
classNamestringExtra classes for the card root.
Also accepts all props of Omit<React.ComponentPropsWithoutRef<"div">, "onChange" | "children"> — they pass through to the underlying element.

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