# Onboarding

> Three first-run flows: stepped interest chips into workspace naming under a springing progress bar, a split screen whose live workspace preview updates as you type, and a checklist card that morphs as tasks complete.

- Collection: Pages
- Tier: pro
- Docs: https://geturui.com/docs/onboarding-pages
- Install: `npx shadcn@latest add @geturui-pro/onboarding-pages`
- Dependencies: motion, lucide-react

## Variants

### Stepped

Interest chips, then workspace name with a live URL and team size, then a done screen with a shape burst, all under a springing progress bar.

Install: `npx shadcn@latest add @geturui-pro/onboarding-pages-stepped`

```tsx
import { Stepped } from "@/components/pages/onboarding-pages/stepped";

export default function Welcome() {
  return (
    <Stepped
      domain="acme.app"
      onComplete={async ({ interests, workspace, slug, teamSize }) => {
        await api.workspaces.create({ name: workspace, slug, teamSize, interests });
      }}
      onFinish={({ slug }) => router.push("/" + slug)}
    />
  );
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| productName | `string` | "Kestrel" | Header lockup. |
| domain | `string` | "kestrel.app" | Shown before the generated slug. |
| interests | `{ id; label; icon? }[]` | — | Chips on step one. |
| teamSizes | `string[]` | — | Options for the team-size radio group. |
| onComplete | `(result: { interests; workspace; slug; teamSize }) => void | Promise<void>` | — | Runs when step two is submitted. Throw to show an error. |
| onFinish | `(result) => void` | — | Done-screen button handler. |
| className | `string` | — | Classes for the outer container. |

### Split screen

Vertical stepper and form on the left; a live app-window preview on the right that picks up your name, workspace, accent colour and invites as you type.

Install: `npx shadcn@latest add @geturui-pro/onboarding-pages-split-screen`

```tsx
import { SplitScreen } from "@/components/pages/onboarding-pages/split-screen";

export default function Setup() {
  return (
    <SplitScreen
      roles={["Engineer", "Designer", "Product manager"]}
      onComplete={({ name, role, workspace, accent, invites }) => api.setup({ name, role, workspace, accent, invites })}
      onLaunch={() => router.push("/app")}
    />
  );
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| productName | `string` | "Kestrel" | Header lockup. |
| roles | `string[]` | — | Options for the role select. |
| onComplete | `(result: { name; role; workspace; accent: "volt" | "ember" | "info" | "success"; invites: string[] }) => void | Promise<void>` | — | Runs on the last step. Throw to show an error. |
| onLaunch | `(result) => void` | — | Done-state button handler. |
| className | `string` | — | Classes for the outer container. |

### Morphing checklist

Getting-started card over a blurred app: finished tasks fly into a summary stack, the next task opens, a ring fills, and the card collapses into a celebration when everything is done.

Install: `npx shadcn@latest add @geturui-pro/onboarding-pages-morphing-checklist`

```tsx
import { MorphingChecklist } from "@/components/pages/onboarding-pages/morphing-checklist";

export default function GettingStarted() {
  return (
    <MorphingChecklist
      defaultCompleted={["snippet"]}
      onTaskComplete={(id) => api.onboarding.complete(id)}
      onFinish={() => router.push("/dashboards")}
    />
  );
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| productName | `string` | "Kestrel" | Used in the final card copy. |
| heading | `string` | "Get set up" | Card heading. |
| tasks | `{ id; title; description; actionLabel; detail? }[]` | — | Checklist tasks in order. |
| defaultCompleted | `string[]` | ["snippet"] | Task ids that start done. |
| onTaskComplete | `(id: string) => void | Promise<void>` | — | Runs a task. Throw to keep it open with an error. |
| onFinish | `() => void` | — | Final card button handler. |
| className | `string` | — | Classes for the outer container. |

## Accessibility

- Chips are toggle buttons with aria-pressed; single-choice groups are radiogroups with roving focus and arrow keys.
- Progress is exposed as a progressbar or an ordered list with aria-current=step; focus moves to each new step’s heading after navigation.
- Checklist rows are disclosure buttons with aria-expanded; layout morphs and bursts are skipped under reduced motion.

## Source

Pro item — send `Authorization: Bearer <registry token>` to include the source.
