WebberUI

Setup Checklist Rail

An onboarding checklist pinned to the side of the app — completed items check off and collapse, the progress ring at the top counts up, and once everything is done it shrinks into an expandable floating badge.

Loading preview…
npx shadcn@latest add https://webberui.com/r/setup-checklist-rail.json

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

<SetupChecklistRail />

Installation

npx shadcn@latest add https://webberui.com/r/setup-checklist-rail.json

Or, once registries are configured in components.json, install it as @webberui/setup-checklist-rail.

Usage

It is data driven: pass an items array and the component manages the completed state internally (uncontrolled mode).

import { SetupChecklistRail } from "@/components/ui/setup-checklist-rail";

const items = [
  { id: "profile", title: "Complete your profile", description: "Add an avatar and a name.", actionLabel: "Go to profile" },
  { id: "workspace", title: "Create a workspace", description: "Keep your projects in one place." },
  { id: "invite", title: "Invite teammates" },
];

<SetupChecklistRail items={items} defaultCompleted={["profile"]} />

To keep progress in sync with a backend, switch to controlled mode:

const [done, setDone] = React.useState<string[]>([]);

<SetupChecklistRail
  items={items}
  completed={done}
  onCompletedChange={setDone}
  onAllComplete={() => track("onboarding_complete")}
/>

Props

PropTypeDefaultDescription
itemsSetupChecklistItem[]Checklist items (see the type below)
completedstring[]Controlled array of completed ids; when omitted, the component manages it internally
defaultCompletedstring[][]Initially completed ids in uncontrolled mode
onCompletedChange(ids: string[]) => voidFires when the completed set changes (in both controlled and uncontrolled modes)
onAllComplete() => voidFires once when everything is complete
titlestring"開始使用"Panel title
side"left" | "right""right"Which edge the panel hugs
position"fixed" | "absolute""fixed"fixed hugs the viewport; absolute is contained by a relative parent
collapseOnCompletebooleantrueWhether to shrink into the floating badge automatically once everything is done
doneLabelstring"設定完成"Text shown on the badge after completion
classNamestringAppended to the outermost container's className

SetupChecklistItem

FieldTypeDescription
idstringUnique identifier, used as the key for completion state
titlestringStep title
descriptionReact.ReactNodeStep description; collapses away with the row once completed
actionLabelstringOptional action button text
onAction() => voidCallback for clicking the action button

How it works

  • Incomplete steps sort to the front automatically, so the next thing to do floats to the top.
  • Checking a step collapses its description and strikes through its title, while the progress ring's arc length and its center number both "count" all the way to the new value.
  • A single MotionValue (the completion ratio) drives both the arc length and the center number, so the two can never fall out of sync.
  • The collapse button in the title row can shrink the whole rail into a floating badge at any time; clicking the badge expands it again. It collapses into the badge automatically once everything is complete.

Accessibility

  • Each row is a role="checkbox" with aria-checked; it can be focused with Tab and checked with Space / Enter.
  • The progress ring container is a role="progressbar" with aria-valuemin / aria-valuemax / aria-valuenow, and aria-valuenow reports the real completed count rather than the in-flight animated value.
  • The panel is a section with an aria-label; the badge button's aria-label includes the current progress and an expand hint.
  • When the user has "reduce motion" enabled at the system level, the scale, reflow, and stroke animations are disabled and only an instant fade in / fade out remains.

On this page