Super-AI-Components

Onboarding Wizard

Multi-step first-run survey / setup

Setup progress: step 1 of 32 to go
x

What do you make?

This picks the templates and sample project you land in.

Changes: Sets your default aspect ratio, template set, and the sample project we open first.

What it is

The first-run flow: one question per screen, answered with choice cards, tracked by a dot rail that says how many steps are left, and escapable at every single step. Steps carry an optional marketing pane, which is the whole of the split-panel variant — same steps, same dots, same Skip, one extra column.

Why it matters

Answers must change the product. A first-run question earns its screen only if answering it visibly moves something downstream — the segment defaults you land on, the templates in your picker, the sample project that opens, the credit pack you are offered. A survey that changes nothing is a tax: it is charged to every new user, at the exact moment they have the least patience and the least reason to trust you, and it buys them nothing. That is why every step here takes an `effect` — the sentence saying what this answer does — and why the honest fix for a step you cannot write an `effect` for is to delete the step, not to leave the field blank. ElevenLabs' role survey, Descript's and CapCut's setup flows, and Claude Cowork's intro all pay for their questions this way: each answer changes what you see the moment the flow ends.

Observed in: ElevenLabs role survey · Descript · CapCut · Claude Cowork intro

Anatomy

  1. 1onboarding-wizardThe card that frames the whole flow.
  2. 2onboarding-wizard-progressA real progressbar. Position, total and how many remain live in its accessible name and aria-valuetext, not only in the dots.
  3. 3onboarding-wizard-progress-labelThe visible 'Setup progress: step N of M' text, which also names the progressbar.
  4. 4onboarding-wizard-dotsThe dot rail. Decorative and aria-hidden — it is the picture of the progress, never the record of it.
  5. 5onboarding-wizard-dotOne dot per step, carrying data-state done / current / upcoming.
  6. 6onboarding-wizard-remainingVisible '3 to go' / 'Last step' counter — the number the flow is actually judged on.
  7. 7onboarding-wizard-contentThe question: choice cards, free-form content, and the effect line.
  8. 8onboarding-wizard-choicesThe radio group behind the choice cards.
  9. 9onboarding-wizard-choiceOne choice card: a label wrapping a real radio, with data-state selected / unselected.
  10. 10onboarding-wizard-effectWhat answering this question changes. The line that separates onboarding from a survey.
  11. 11onboarding-wizard-panelThe marketing pane. Present only on steps that declare one; always after the question in reading order.
  12. 12onboarding-wizard-navThe footer: Back on one side, Skip and the primary on the other.
  13. 13onboarding-wizard-backSecondary. Disabled on the first step.
  14. 14onboarding-wizard-skipPresent on every step, the last one included.
  15. 15onboarding-wizard-primaryReads 'Next' mid-flow and a finish verb on the last step.

How to use it

Reach for it for the first run of a product whose defaults genuinely differ by who you are — a role that picks a template set, a volume that picks a credit pack, a team answer that turns sharing on. Give each step an `id`, a `title`, either `choices` (single-select cards) or free-form `content`, and an `effect` saying what the answer does. Read the answers back through `onAnswerChange`, or hold them yourself with `answers` and apply them as they arrive. Add `panel` to any step to make it split-panel; add `panelSide` to move the pane visually without changing reading order. Leave `step`/`defaultStep` uncontrolled for a self-contained flow, or drive position from a parent that is persisting progress across a reload. Do not reach for it for a settings page or a per-generation setup — settings are revisited, and a per-generation flow with a cost belongs in E8 generation-wizard, whose preview pane exists to show what a choice will spend.

Do

  • State what each answer changes, on the same screen as the question — and cut any step you cannot write that sentence for.

    Setup progress: step 1 of 21 to go
    x

    What do you make?

    Changes: Sets your default aspect ratio and opens the matching sample project.

  • Keep Skip on every step, including the last, so no single question is quietly mandatory.

    Setup progress: step 2 of 2Last step
    x

    How much do you expect to make?

    Changes: Picks your credit pack and whether the batch queue starts on.

  • Use the same steps, dots and nav when you add a marketing pane — split-panel is a prop on a step, not a second flow.

    Setup progress: step 1 of 1Last step
    x

    Bring your brand in

    Optional — you can add this later from Settings.

    Drop a logo and two brand colours.

    Changes: Applies your palette to every generated title card.

    Teams ship 3x faster with a brand kit

    Shared across the workspace, picked up by every template.

Don't

  • Don't ask a question that changes nothing. A survey with no downstream effect is a tax charged to every new user at their least patient moment.

  • Don't let the dots be the whole of the progress — pair them with a real progressbar and a visible 'step N of M, 3 to go'.

  • Don't build choice cards as divs with a click handler. They need radio semantics: a group, arrow keys, and aria-checked.

Accessibility

Keyboard
  • Four tab stops on a step with choices: the choice group, then Back, Skip and the primary. The group counts once, not once per card — it is a real radio group with a roving tabindex. Back is `disabled` on the first step, so the first step has one stop fewer than every step after it.
  • Arrow keys inside the choice group also answer the question. Focus moves to the next card and that card is checked in the same keystroke, firing `onAnswerChange` — there is no way to browse the options from the keyboard without committing to each one you pass through. Home, End and PageUp are not bound at all — measured from the third of four cards, each leaves focus exactly where it was — so arrowing through is the only keyboard route to a later option, and it answers the question with every card it passes
  • Space and Enter activate the footer buttons, which are native buttons. Nothing else is bound: Escape does not leave the flow, Enter does not advance a step, and there is no shortcut for Back or Skip.
  • The step heading takes `tabIndex={-1}` so the wizard can move focus to it programmatically. It is not a tab stop — Tab from the progress row lands on the choice group, not on the title.
  • Anything you pass as `content` brings its own keys. It is not wrapped in a `<form>`, so Enter in a text field submits nothing and the primary button stays the only way forward.
Screen reader
  • The dot rail is `aria-hidden`, so position is carried by a real progressbar instead: `ProgressLabel` renders the visible "Setup progress: step 2 of 4" and names the bar, and `aria-valuetext` reads "Step 2 of 4, 2 steps remaining". A progressbar is not a live region, so moving between steps does not announce the new position — it is there to be found, not to interrupt.
  • The choice group is `aria-labelledby` the step heading, so it announces under the question rather than as an unnamed group.
  • Each card's radio is named by the entire `<label>` wrapping it, which folds `description` into the name: a card announces as "Product designer Templates and defaults for design work, radio button, 1 of 4", not as a name with a separate description. Keep descriptions to one short clause or every card's name becomes a paragraph.
  • `icon` is `aria-hidden` and contributes nothing to a card's name — `label` and `description` carry all of it.
  • The `effect` line is plain text under the choices, tied to nothing. It is read when a user walks the step, and is not re-announced when the answer changes.
  • Skipping the last step ends the flow without moving to another step, so the heading never changes and nothing says setup is finished. Announce that yourself from `onFinish`.
Focus
  • Every step change moves focus to the new step's heading, deliberately — focus is not left sitting on a nav button whose meaning just changed. It is skipped on mount, so the wizard never steals focus the instant it renders.
  • That heading carries `outline-none` and no focus style of its own, so the move is silent for sighted keyboard users: a screen-reader user hears the new question, and everyone else watches focus disappear from the button they pressed.
  • Nothing moves focus at the end. Both the primary and Skip finish the flow in place, leaving focus on a button inside a card your `onFinish` is presumably about to unmount — put focus wherever you send the user next.
  • The footer buttons and the radios draw the vendored primitives' own `focus-visible` rings, so focus is visible everywhere except on the heading.

Watch out for

  • Treating the four declared states as four variants to render one at a time. Choice cards, dot progress and skippability are all present at once in the default flow; split-panel is the only one that is a per-step choice, and even then it is the same machinery with one extra pane.
  • Dropping Skip on the last step because that is what a commit-shaped wizard does. E8 generation-wizard is right to do it — its last step spends credits. Here it would make the final question the one question a user cannot get past, which is exactly where first-run flows get abandoned.
  • Collecting answers and never applying them. onAnswerChange fires with the step id and value for a reason; if the only consumer is analytics, the flow is a survey wearing setup's clothes.
  • Marking the dots as the progress and stopping there. The dot rail here is aria-hidden on purpose — the position, the total and the remaining count are on the progressbar and in visible text, and a build that moves the signal back into the dots has reintroduced a colour-only state.
  • Reaching for text-muted-foreground inside the marketing pane. That pane's frame is bg-muted, and the pairing measures under the 4.5:1 minimum in this token set — use text-foreground or a pinned foreground step (text-foreground/60 floor, TOK-8), as the demo pane's /70 does.
  • Putting the marketing pane before the question in the DOM to get it on the left. Use panelSide: "start", which moves it visually and leaves the question first for keyboard and screen-reader order.

Installation

npx shadcn@latest add https://super-ai-components.vercel.app/r/onboarding-wizard.json

Requires a shadcn app on Base UI (style base-nova). Radix-based styles such as new-york fail to typecheck: these components use Base UI's render prop and callbacks like onOpenChangeComplete, which Radix primitives do not have.