Skip to content
Cynosurev0.5.0
SearchStorybookGitHubnpmColour mode: System. Switch to Light

Components / Controls

Checklist

A list of rows people add, tick, rename and remove, such as a task's subtasks. If people only choose among options you wrote, use Checkbox instead.

Default

When to useLink to "When to use"

  • A list people write themselves and work through: subtasks, a packing list, the steps of a recipe.
  • reorderable: when the order matters to them.
  • readOnly: to show the same list where it cannot be changed.

Use something else when:

  • the options are fixed and people only tick them: Checkbox
  • each row has a name and a value: KeyValueEditor
  • the rows are short tags: TagInput
  • the rows are only put in order: SortableList
  • the rows are steps of a process someone else defined: Steps

UsageLink to "Usage"

tsx
Copy
import { Checklist, type ChecklistItem } from "@arshad-shah/cynosure";

const [subtasks, setSubtasks] = useState<ChecklistItem[]>([]);

<Checklist label="Subtasks" items={subtasks} onChange={setSubtasks} />
<Checklist label="Packing list" defaultItems={[]} onChange={save} />

Each row is { id, label, done }. Give rows from your data a stable id; rows added in the list get one from createId (by default crypto.randomUUID(), or a time-based id where that is missing). onChange receives the full list after every change.

Renaming a rowLink to "Renaming a row"

The Rename button turns the name into a field with the old name selected. Enter saves, Escape cancels, and leaving the field saves. A blank name is not saved: the row keeps the name it had, and Remove is the only way to delete a row.

Rename in place

ReorderingLink to "Reordering"

reorderable puts the rows in a SortableList: each gets a grip to drag, or to move with Space and the arrow keys.

Reorderable

Limits and statesLink to "Limits and states"

maxItems turns the add field and button off when the list is full. disabled turns everything off. readOnly shows only the rows.

PropsLink to "Props"

Every prop of Checklist
PropWhat it doesTypeDefault
labelRequired
What the rows are ("Subtasks"). Names the list; shown above it unless labelHidden.string
labelHidden
Visually hide the label (it still names the list). Default false.booleanfalse
items
The rows, when you control them: { id, label, done }.ChecklistItem[]
defaultItems
Starting rows when uncontrolled.ChecklistItem[]
onChange
Called with the full list after each change: a row added, ticked, renamed, removed or moved.((items: ChecklistItem[]) => void)
createId
Makes the id of a new row. Default: crypto.randomUUID(), or a time-based id where that is missing.(() => string)`crypto
maxItems
The most rows the list may hold; the add field turns off when it is full.number
reorderable
Rows get a grip to drag, or to move with Space and the arrow keys (SortableList). Default false.booleanfalse
disabled
Turns off every checkbox, field and button. Default false.booleanfalse
readOnly
Shows the rows as they are: nothing can be ticked, added, renamed, removed or moved. Default false.booleanfalse
size
Size of the checkboxes, text, fields and buttons. Default "md"."sm" | "md""md"
labels
Replace the built-in English text.Partial<ChecklistLabels>
className
Added to the root element, for layout.string
style
Layout only. Restyle through --cy-checklist-* tokens.CSSProperties

Generated from the type definitions in @arshad-shah/cynosure 0.5.0.

Behaviour and accessibilityLink to "Behaviour and accessibility"

Behaviour and accessibility, table 1
InputResult
Enter in the add field, or the Add buttonAdds the trimmed name as a new row and keeps focus in the field; a blank name adds nothing
Click, tap or Space on a row's checkbox or nameTicks or unticks it
Rename button (click, tap, Enter, Space)Opens the name in a field, focused, with the old name selected
Enter in the rename fieldSaves and returns focus to the Rename button
Escape in the rename fieldCancels and returns focus to the Rename button
Tab or a press outside the rename fieldSaves and leaves focus where it went
Remove buttonDeletes the row and focuses the checkbox of the row that took its place, or the row before it, or the add field when none is left
Grip (reorderable): drag, or Space, arrows, SpaceMoves the row; SortableList announces each step
  • Names: the group and the list are named by label. Each checkbox is named by its row, and the buttons read "Rename Buy milk" and "Remove Buy milk".
  • Done rows are struck through and muted by Checkbox (strikeWhenChecked).
  • Full list: adding the row that reaches maxItems moves focus to that row's checkbox, because the add field turns off.
  • Forms and dialogs: Enter in either field does not submit a form around the list, and Enter and Escape in the rename field do not reach a dialog around it. Enter is left alone while an input method is composing.
  • Read only: the checkboxes can still be focused and read, and a press leaves them as they were.
  • Announcements: adding, renaming and removing are not announced; focus moves to a named control instead.
  • Right to left: the row mirrors.

TouchLink to "Touch"

The Rename, Remove and Add buttons and the grip have 44px hit areas on coarse pointers (phones and tablets), and each checkbox row is at least 44px tall. Nothing depends on a double click or on hover.

ThemingLink to "Theming"

Tokens: --cy-checklist-gap (space between rows, and between the rows and the add field) and --cy-checklist-row-gap (space between a row's checkbox, name and buttons). The checkbox, the strike, the fields, the buttons and the reorderable rows follow the Checkbox, TextField, Button and SortableList tokens.

ts
Copy
createTheme({ components: { checklist: { gap: "0.5rem" } } });

className and style are for layout only (margin, placement, width). Change the look through tokens so every product stays consistent.

Checkbox · KeyValueEditor · SortableList · TagInput · TextField

These examples run Cynosure 0.5.0 (commit 50ce30b), the version on npm.

Getting started
Theming
Icons
Accessibility
Code editors and highlighters
Using Cynosure without React
Build-tool adapters
Components
Accordion
AppShell
AspectRatio
Breadcrumbs
Calendar
Card
Container
Disclosure
Divider
DocumentViewport
Grid
Inline
PageHeader
PanZoomCanvas
ScrollArea
SideNav
SortableList
SplitPane
Stack
StatusBar
Tabs
TitleBar
Toolbar
Tree
VirtualList
ZoomControls
Announcer
Avatar
Badge
CodeBlock
DescriptionList
EmptyState
ErrorBoundary
Field
Heading
IconTile
Image
Kbd
List
LoadingDots
Notice
ProgressBar
Prose
Skeleton
Stat
Steps
Table
Text
Button
Checkbox
Checklist
ColorField
ColorSwatches
Combobox
CompareSlider
CopyButton
DateField
FileDrop
IconButton
KeyValueEditor
Link
NumberField
Pagination
PathField
RadioGroup
SearchField
SegmentedControl
Select
SelectionFrame
SignaturePad
Slider
Switch
TagInput
TextArea
TextField
ThemeToggle
TimeField
ButtonBase
ChoiceBase
DialogBase
FileInputBase
HiddenValue
Icon
InputBase
LinkBase
LiveRegion
TextAreaBase
ChatMessage
Choice
DataGrid
DeviceFrame
HighlightedText
HotkeyField
ListRow
OptionList
OverlayFrame
QRCode
RowActions
Section
SiteFooter
SiteHeader
SkipLink
SortButton
VisuallyHidden
CommandPalette
ContextMenu
Dialog
FloatingToolbar
HoverCard
Menu
Menubar
Popover
ProgressOverlay
Sheet
Toast
Tooltip
Changelog