caliper uidocs

Checklist

Free

A list people tick through: a ticked item is struck out where it is, then settles into Done at the bottom, so what is left stays at the top. Add from the last row, reorder with Alt+arrows, undo from the line that confirms it.

Installs components/ui/checklist.tsxDepends on lucide-reactMotion honours reduced motion
pnpm dlx shadcn@latest add https://caliperui.site/r/checklist.json

Launch: multi-currency matching

1 of 4 done

When to use #

Use it for

  • Launch, onboarding or review checklists people work through.
  • Shared to-do lists inside a record.

Skip it when

  • An agent's plan that people only watch; use the todo list.
  • Tasks with owners and due dates; use a task table.

Decisions #

Why it is built this way, so you know what to keep when you change your copy.

Behaviour

Strike first, then move
A ticked item stays put, struck out, for a moment before it slides to Done. Moving it instantly would yank it from under the pointer and hide whether the tick landed.
Every change can be taken back
Ticks, removals and reorders each leave one line with Undo. There is no confirmation dialog for removing an item because undo is cheaper.

Styling

Animate transform, never layout
Rows slide with a transform from where they were to where they are, measured before and after the change, so the list never reflows twice.

Usage

Respect reduced motion
With reduced motion the rows move without sliding and the strike-through appears at once; the order and undo work the same.

Installation #

terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/checklist.json

Adds its 3 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.

Usage #

This is the code behind the preview above.

example.tsx
import { useState } from "react"
import { Checklist, type ChecklistItem } from "@/components/ui/checklist"

export function ChecklistDemo() {
  const [items, setItems] = useState<ChecklistItem[]>([
    { id: "a", text: "Write the release note", done: false },
    { id: "b", text: "Record the two-minute walkthrough", done: false },
    { id: "c", text: "Email workspaces with foreign-currency accounts", done: false },
    { id: "d", text: "Update the help article on reconciliation", done: true },
  ]);
  return (
    <div className="w-full max-w-md">
      <Checklist label="Launch: multi-currency matching" items={items} onItemsChange={setItems} />
    </div>
  );
}

API reference #

Checklist

component
PropTypeDefaultDescription
items *readonly ChecklistItem[]—
onItemsChange *(items: ChecklistItem[]) => void—
labelstring"Checklist"
placeholderstring"Add an item"
settleMsnumber600How long a ticked item stays struck out in place before it moves to Done.
classNamestring—

Accessibility #

It is built on native elements and keeps aria-keyshortcuts, aria-label, aria-hidden, aria-labelledby, aria-expanded and aria-controls in step with state. Changes that matter are announced through a live region.

KeyBehaviour
↑Moves to the previous item or value.

Motion #

It checks prefers-reduced-motion itself and settles immediately instead of travelling. Every state is still reachable.