Checklist
The onboarding panel: a card that tracks a short list of setup tasks and their progress. The bar and the 3-of-6 read-out derive from value and total, and the bar turns green the moment every step is done.
Installation#
Usage#
import {
Checklist,
ChecklistHeader,
ChecklistTitle,
ChecklistDescription,
ChecklistProgress,
ChecklistItems,
ChecklistItem,
ChecklistItemContent,
ChecklistItemTitle,
ChecklistItemDescription,
ChecklistItemAction,
} from "@/components/ui/checklist"
export function Example() {
return (
<Checklist value={2} total={6}>
<ChecklistHeader>
<ChecklistTitle>Get started</ChecklistTitle>
<ChecklistProgress />
</ChecklistHeader>
<ChecklistItems>
<ChecklistItem status="complete">
<ChecklistItemContent>
<ChecklistItemTitle>Create your account</ChecklistItemTitle>
</ChecklistItemContent>
</ChecklistItem>
{/* …more items */}
</ChecklistItems>
</Checklist>
)
}Item states#
Every ChecklistItem carries a status, drawn by the one task mark every task list in the kit shares: 16px, centred on the title's first line. A complete row fills it with the brand and a tick and de-emphasizes the title; active marks the one recommended next step with a brand ring half filled, started but not done, and the primary action; the row stays flat, so the button is what draws the eye. todo rows wait quietly with an empty ring and an outline action.
Progress & completion#
Pass value (completed count) and total to the root; ChecklistProgress derives the bar, the “X of Y” label and the percentage itself. When every step is done the bar eases from brand to success-green and the label swaps to All steps complete.
Density#
Like Card and Dialog, the Checklist reads the density context (or a density prop). Density tunes the card and row padding only. The indicator footprint is fixed at both densities, so the left rail lines up identically.
Tasks the reader ticks#
Give a ChecklistItem checked and onCheckedChange (or defaultChecked to let it keep its own state) and it becomes a task list: the indicator turns into the task mark, a real checkbox drawn like the small Checkbox only round, 16px and centred on the title's first line, with a black tick. It is named by the item's title, the whole row is its hit area, and a ticked title is struck through as it mutes. Leave value and total off the root and the Checklist counts its own items, so the bar follows every tick with no wiring. A row's ChecklistItemAction stays its own target above the hit area.
Inside a Card#
variant="plain" drops the Checklist's own contour and outer padding, so it sits inside a Card (or any surface that already frames it) without a frame inside a frame. The Card's header carries the heading; the indicators line up with it, and the row pills bleed into the Card's padding the way List's plain rows do. ChecklistProgress can lead the header on its own.
The task mark on its own#
ChecklistMark draws the same mark without the Checklist around it, for a task list something else lays out: the steps of an Accordion, a row that is already a button. An empty ring while the task waits, a brand ring half filled on the active step, the brand fill with a tick once it is complete: fill only ever means done. It centres itself on a text-sm first line, so put it in an items-start row. It is decoration, so the row says the state in words.
API reference#
Checklist
The root card. Forwards all div props.
value?: number: completed task count. Leave it out and the Checklist counts its complete items.total?: number: total task count. Leave it out and the Checklist counts its items. Both drive the derived progress (clamped so a bad count can't overrun the bar).variant?: "card" | "plain": the panel contour, or none for a Checklist inside a Card. @default"card"density?: "comfortable" | "compact": padding tier; defaults from the density context.asChild?: boolean: render as a child element via Radix Slot.
ChecklistProgress
The labeled role="progressbar" bar. Reads progress from context. Pass label to override the default “X of Y complete” text.
ChecklistItem
status?: "todo" | "active" | "complete": the task state. On a row the reader ticks,checkeddecidescomplete. @default"todo"checked?: boolean,defaultChecked?: boolean,onCheckedChange?: (checked: boolean) => void: any of them makes the row a task the reader ticks: a Radix checkbox named byChecklistItemTitle, the row as its hit area,data-stateon the row.
ChecklistMark
The task mark alone, aria-hidden, no Checklist needed. Forwards all span props.
status?: "todo" | "active" | "complete": an empty ring, a brand ring half filled, or the brand fill with a tick. @default"todo"
ChecklistHeader · ChecklistTitle · ChecklistDescription · ChecklistItems · ChecklistItemContent · ChecklistItemTitle · ChecklistItemDescription · ChecklistItemAction
Structural parts. Each accepts className (merged last) and forwards its native element props. ChecklistTitle takes asChild.