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.

Finish setting up your workspace

A few quick steps to get the most out of Koala.

2 of 6 complete33%
  • Create your account
    You're in. Welcome to Koala.
    Completed
  • Invite your team
    Add teammates to collaborate on projects together.
    Completed
  • Connect a repository
    Link your Git provider to sync changes automatically.
    In progress
  • Install the CLI
    Ship straight from your terminal with npx koalaui-cli.
    Not started
  • Set up billing
    Add a payment method to move to production.
    Not started
  • Deploy your first project
    Push to main and watch it go live in seconds.
    Not started

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Add this component (its dependencies come along)npx koalaui-cli@latest add checklist

Usage#

usage.tsxTSX
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.

Getting started

1 of 3 complete33%
  • Create your account
    You're all set.
    Completed
  • Invite your team
    Add teammates to collaborate.
    In progress
  • Set up billing
    Add a payment method to go live.
    Not started

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.

In progress

2 of 4 complete50%
  • Create your account
    Completed
  • Invite your team
    Completed
  • Connect a repository
    In progress
  • Deploy your project
    Not started

All done

All steps complete100%
  • Create your account
    Completed
  • Invite your team
    Completed
  • Connect a repository
    Completed
  • Deploy your project
    Completed

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.

Comfortable

1 of 2 complete50%
  • Install the CLI
    Completed
  • Connect a repo
    In progress

Compact

1 of 2 complete50%
  • Install the CLI
    Completed
  • Connect a repo
    In progress

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.

Team tasks

Housekeeping for this week and next.

0 of 0 complete0%
  • Rotate the on-call schedule
    Ana Torres, due Friday
  • Archive tickets older than 90 days
    Marc Vidal, due Monday
  • Review the refund macro
    Lucia Ramos, due Tuesday

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.

Team tasks
Housekeeping for this week and next.
0 of 0 complete0%
  • Rotate the on-call schedule
    Ana Torres, due Friday
  • Archive tickets older than 90 days
    Marc Vidal, due Monday
  • Review the refund macro
    Lucia Ramos, due Tuesday

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.

Send an email invite or share a link.

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, checked decides complete. @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 by ChecklistItemTitle, the row as its hit area, data-state on 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.

FAQ#

From the root's value and total. ChecklistProgress derives the percentage, the 'X of Y complete' label and the aria-valuenow itself, so the header and the item statuses can't drift out of sync. Both counts are clamped, so a value greater than total (or a negative) can never overrun the bar or report over 100%.