# Onboarding Checklist

> An animated onboarding checklist for React and shadcn, with a progress ring and a Done pill at the end.

A setup checklist that keeps score. Ticks draw, a strike wipes across each finished label, the ring fills while the count rolls, the next step unfolds with its action, and the finished list folds into a Done pill.

- Tier: Eased Pro
- Interaction: Press
- Page: https://eased.dev/components/onboarding-checklist
- Installs: motion

## Install

Onboarding Checklist ships with Eased Pro (https://eased.dev/#pricing). Members add the `@eased-pro` registry with their token (https://eased.dev/account), then run:

```bash
npx shadcn add @eased-pro/onboarding-checklist
```

A setup checklist that keeps score: ticks draw, labels strike through, a ring fills, and the finished list folds into a Done pill. Built on Auto Height, Button and Number Roll.

## When to use

- The first-run panel of a SaaS product: install, connect, invite, schedule.
- When each step has one obvious next action the user can take from the list.

## When not to use

- One question per screen: use a multi-step form or Spotlight Tour.
- A long to-do list the user owns: use a plain checklist with Checkbox.

## Usage

```tsx example.tsx
import { OnboardingChecklist } from "@/components/eased/onboarding-checklist/onboarding-checklist";

<OnboardingChecklist
  title="Get started with Orbit"
  steps={[
    { id: "snippet", label: "Install the snippet", minutes: 2 },
    { id: "source", label: "Connect a data source", description: "Postgres, Snowflake or Stripe.", action: "Connect", minutes: 5 },
    { id: "invite", label: "Invite your team", action: "Invite", minutes: 1 },
  ]}
  defaultCompleted={["snippet"]}
  onAction={(id) => openSetup(id)}
/>
```

## API reference

### OnboardingChecklist

| Prop | Type | Default | Description |
|---|---|---|---|
| `steps` | `OnboardingStep[]` | | `{ id, label, description?, action?, minutes? }`. |
| `completed` / `defaultCompleted` / `onCompletedChange` | `string[]` | `[]` | Finished step ids. |
| `onAction` | `(id) => void \| false \| Promise` | | Runs the open step's action. A promise shows the button loading; the step completes when it resolves. Return `false` (or resolve to it) when your app completes the step itself, later through `completed`: the step stays open and focus stays where your app puts it. |
| `trailing` | `ReactNode` | | At the end of the header row, after the Done pill: a hide or dismiss control. |
| `title` / `doneTitle` | `string` | "Get started" / "You’re all set" | |
| `collapseWhenDone` | `boolean` | `true` | Fold the list into a Done pill when every step is done. |
| `locale` | `string` | runtime | |
| `className` | `string` | `""` | |

## Keyboard

| Key | Action |
|---|---|
| `Tab` | Moves through each step's tick, its label and the open step's action. |
| `Space` | Toggles a step's tick. |
| `Enter` on a label | Opens that step. |

## Accessibility

- Each tick is a `checkbox` named by its step; labels are buttons with `aria-expanded`.
- The "3 steps left" line is a polite live region.
- Focus never strands: when the list folds it moves to the Done pill, and reopening returns it to the first step.

## Motion

A tick draws its check on the snappy spring while a strike wipes across the label left to right (clip-path, 320ms) and the ring fills on `smooth` as the count rolls. The next step unfolds on Auto Height. 700ms after the last tick the list folds away and the Done pill rises with a blur. Reduced motion: states change at once.

## Notes for AI

Use it for first-run setup with three to six steps. Give each step a short `action` and return a promise from `onAction` so the button shows progress.

Don't add your own progress bar or counter: the ring and the subtitle are both. Don't hide finished steps yourself; the strike and the fold do it.

## Related

- [Checkbox](/components/checkbox): a single tick.
- [Spotlight Tour](/components/spotlight-tour): guiding through the real UI.
