List
A rich list container that stacks rows with automatic hairlines, groups them with sections, and reveals extras inline via disclosure.
Implementation previewEvery example. In one place.
Explore every named example, including states, compositions, and theme variants.
Example source
packages/design-system/src/components/organization/List/List.stories.tsxExport SectionsImplementation preview Local Storybook build 0.2.0-preview.1. Source specification status does not approve this runtime.
Stories + source JSON ↗Local specification source status: preview. Implementation preview pending sign-off.
A rich list container that stacks rows with automatic hairlines, groups them with sections, and reveals extras inline via disclosure.
Implementation API 16 entry points · source-derived preview
Read the actual callable API and preserve its composition constraints. Each union branch is a complete alternative; props marked forbidden cannot be supplied.
import { List } from '@cloakedinc/design-system';ListListProps
packages/design-system/src/components/organization/List/ListRoot/ListRoot.tsx:19
| Prop | Type | Presence | Notes |
|---|---|---|---|
children | React.ReactNode | Required | Rows (`List.Item`), `List.Section` groups, and/or `Divider` boundaries, in render order. |
ariaLabel | string | undefined | Optional | Accessible label announced for the list. |
className | string | undefined | Optional | |
style | React.CSSProperties | undefined | Optional | |
testId | string | undefined | Optional | Test selector for the list container. Rows carry their own `testId`. |
List.ItemListItemProps
packages/design-system/src/components/organization/ListItem/ListItem.tsx:39
| Prop | Type | Presence | Notes |
|---|---|---|---|
leading | React.ReactNode | Optional | Custom leading content (e.g. an `Avatar`, brand logo, or `List.Item.Icon` plate). |
leadingGlyph | "number" | "info" | "guard" | "arrow-left" | "arrow-right" | "arrow-up" | "arrow-down" | "chevron-down" | "chevron-up" | "chevron-left" | "chevron-right" | "caret-down" | "caret-up" | "trend-up" | "trend-down" | "collapse" | "expand" | "dropdown-collapse" | "dropdown-expand" | "close" | "clear" | "menu" | "copy" | "search" | "add" | "share" | "phone" | "sim" | "account" | "family" | "home" | "wifi" | "cart" | "vpn" | "lock" | "block" | "timer" | "check" | "send" | "filter" | "scan" | "log" | "trash" | "missed" | "call" | "voicemail" | "sms" | "email" | "data-removal" | "dark-web-monitoring" | "cloaked-pay" | "cloaked-ai" | "sms-guard" | "email-guard" | "call-guard" | "card" | "password" | "bell" | "circle-outline" | "dot" | "settings" | "clock" | "mail" | "message" | "user" | "upload" | undefined | Optional | Registered glyph rendered as a tone `IconTile` in the leading slot. |
tone | ListItemTone | undefined | Optional | Tone for the generated leading `IconTile`. |
overline | React.ReactNode | Optional | Small copy shown above the title. |
overlineTrailing | React.ReactNode | Optional | Accessory pinned to the top-right, aligned with the overline (e.g. a count badge). |
title | React.ReactNode | Required | Primary row title. |
titleLines | number | undefined | Optional | Wraps the title across up to this many lines before clamping. Defaults to single-line truncation. |
description | React.ReactNode | Optional | Secondary row copy. |
descriptionLines | number | undefined | Optional | Wraps the description across up to this many lines before clamping. Defaults to single-line truncation. |
value | React.ReactNode | Optional | Right-aligned value shown in the title row. |
tag | React.ReactNode | Optional | Tag slot shown at the trailing edge. |
statusLabel | React.ReactNode | Optional | Status text rendered through ListItem.StatusIndicator. |
statusTone | "neutral" | "info" | "success" | "warning" | "danger" | undefined | Optional | Status color treatment for statusLabel. |
trailing | React.ReactNode | Optional | Custom trailing content. |
trailingIcon | React.ReactNode | Optional | Icon slot shown after other trailing content. |
chevron | boolean | undefined | Optional | Override for the disclosure chevron. Leave unset to derive it from interaction — any pressable row shows one, except selection rows and rows with caller-owned trailing content. Pass `true` to force it on (e.g. a non-interactive row inside a pressable card), or `false` to force it off. |
className | string | undefined | Optional | |
style | React.CSSProperties | undefined | Optional | |
divider | boolean | undefined | Optional | Shows a bottom divider when true. |
dividerMode | ListItemDividerMode | undefined | Optional | Divider alignment. |
padding | ListItemPadding | undefined | Optional | Row padding preset. |
size | ListItemSize | undefined | Optional | Row density. `sm` renders a compact row (32px leading slot). Defaults to `md`. |
surface | "page" | "surface" | undefined | Optional | Row background on the `page | surface` scale. Defaults to `surface` (elevated card row); `page` sits flush on a page-level background. |
id | string | undefined | Optional | Optional id for the row container or interactive control. |
ariaControls | string | undefined | Optional | Id of content controlled by this row when used as a disclosure trigger. |
expanded | boolean | undefined | Optional | Expanded state announced for interactive rows. |
disabled | boolean | undefined | Optional | Dims the row and blocks presses. A disabled selection row keeps its radio/checkbox semantics so the choice stays announced — it just can't be chosen. |
onPress | (() => void) | undefined | Optional | Called when the row is pressed. |
ariaLabel | string | undefined | Optional | Accessible label for interactive rows when visible copy is not sufficient. |
haptic | HapticFeedback | undefined | Optional | Haptic feedback for interactive row presses. Defaults to `true` (`light`). |
testId | string | undefined | Optional | Test selector. Lands on the row's button when it is pressable, otherwise on the container. |
List.Item.SelectionListItemSelectionProps
packages/design-system/src/components/organization/ListItem/ListItem.tsx:46
| Prop | Type | Presence | Notes |
|---|---|---|---|
selectionMode | ListItemSelectionMode | undefined | Optional | Selection control shape.Source default: 'multiple' |
selectionPlacement | ListItemSelectionPlacement | undefined | Optional | Where the control renders; `leading` replaces the leading icon. Defaults to `trailing`.Source default: 'trailing' |
selected | boolean | undefined | Optional | Current selected state.Source default: false |
onSelectedChange | ((selected: boolean) => void) | undefined | Optional | Called with the next selected state when pressed. |
surface | "page" | "surface" | undefined | Optional | Row background on the `page | surface` scale. Defaults to `surface` (elevated card row); `page` sits flush on a page-level background. |
overline | React.ReactNode | Optional | Small copy shown above the title. |
id | string | undefined | Optional | Optional id for the row container or interactive control. |
style | React.CSSProperties | undefined | Optional | |
title | React.ReactNode | Required | Primary row title. |
leading | React.ReactNode | Optional | Custom leading content (e.g. an `Avatar`, brand logo, or `List.Item.Icon` plate). |
leadingGlyph | "number" | "info" | "guard" | "arrow-left" | "arrow-right" | "arrow-up" | "arrow-down" | "chevron-down" | "chevron-up" | "chevron-left" | "chevron-right" | "caret-down" | "caret-up" | "trend-up" | "trend-down" | "collapse" | "expand" | "dropdown-collapse" | "dropdown-expand" | "close" | "clear" | "menu" | "copy" | "search" | "add" | "share" | "phone" | "sim" | "account" | "family" | "home" | "wifi" | "cart" | "vpn" | "lock" | "block" | "timer" | "check" | "send" | "filter" | "scan" | "log" | "trash" | "missed" | "call" | "voicemail" | "sms" | "email" | "data-removal" | "dark-web-monitoring" | "cloaked-pay" | "cloaked-ai" | "sms-guard" | "email-guard" | "call-guard" | "card" | "password" | "bell" | "circle-outline" | "dot" | "settings" | "clock" | "mail" | "message" | "user" | "upload" | undefined | Optional | Registered glyph rendered as a tone `IconTile` in the leading slot. |
tone | ListItemTone | undefined | Optional | Tone for the generated leading `IconTile`. |
overlineTrailing | React.ReactNode | Optional | Accessory pinned to the top-right, aligned with the overline (e.g. a count badge). |
titleLines | number | undefined | Optional | Wraps the title across up to this many lines before clamping. Defaults to single-line truncation. |
description | React.ReactNode | Optional | Secondary row copy. |
descriptionLines | number | undefined | Optional | Wraps the description across up to this many lines before clamping. Defaults to single-line truncation. |
value | React.ReactNode | Optional | Right-aligned value shown in the title row. |
tag | React.ReactNode | Optional | Tag slot shown at the trailing edge. |
statusLabel | React.ReactNode | Optional | Status text rendered through ListItem.StatusIndicator. |
statusTone | "neutral" | "info" | "success" | "warning" | "danger" | undefined | Optional | Status color treatment for statusLabel. |
trailing | React.ReactNode | Optional | Custom trailing content. |
trailingIcon | React.ReactNode | Optional | Icon slot shown after other trailing content. |
chevron | boolean | undefined | Optional | Override for the disclosure chevron. Leave unset to derive it from interaction — any pressable row shows one, except selection rows and rows with caller-owned trailing content. Pass `true` to force it on (e.g. a non-interactive row inside a pressable card), or `false` to force it off. |
className | string | undefined | Optional | |
divider | boolean | undefined | Optional | Shows a bottom divider when true. |
dividerMode | ListItemDividerMode | undefined | Optional | Divider alignment. |
padding | ListItemPadding | undefined | Optional | Row padding preset. |
size | ListItemSize | undefined | Optional | Row density. `sm` renders a compact row (32px leading slot). Defaults to `md`. |
ariaControls | string | undefined | Optional | Id of content controlled by this row when used as a disclosure trigger. |
expanded | boolean | undefined | Optional | Expanded state announced for interactive rows. |
disabled | boolean | undefined | Optional | Dims the row and blocks presses. A disabled selection row keeps its radio/checkbox semantics so the choice stays announced — it just can't be chosen. |
ariaLabel | string | undefined | Optional | Accessible label for interactive rows when visible copy is not sufficient. |
haptic | HapticFeedback | undefined | Optional | Haptic feedback for interactive row presses. Defaults to `true` (`light`). |
testId | string | undefined | Optional | Test selector. Lands on the row's button when it is pressable, otherwise on the container. |
List.Item.ProgressListItemProgressProps
packages/design-system/src/components/organization/ListItem/ListItem.tsx:67
| Prop | Type | Presence | Notes |
|---|---|---|---|
progress | number | ListItemProgress | Required | Progress configuration rendered in the row. |
leading | React.ReactNode | Optional | Custom leading content (e.g. an `Avatar`, brand logo, or `List.Item.Icon` plate). |
leadingGlyph | "number" | "info" | "guard" | "arrow-left" | "arrow-right" | "arrow-up" | "arrow-down" | "chevron-down" | "chevron-up" | "chevron-left" | "chevron-right" | "caret-down" | "caret-up" | "trend-up" | "trend-down" | "collapse" | "expand" | "dropdown-collapse" | "dropdown-expand" | "close" | "clear" | "menu" | "copy" | "search" | "add" | "share" | "phone" | "sim" | "account" | "family" | "home" | "wifi" | "cart" | "vpn" | "lock" | "block" | "timer" | "check" | "send" | "filter" | "scan" | "log" | "trash" | "missed" | "call" | "voicemail" | "sms" | "email" | "data-removal" | "dark-web-monitoring" | "cloaked-pay" | "cloaked-ai" | "sms-guard" | "email-guard" | "call-guard" | "card" | "password" | "bell" | "circle-outline" | "dot" | "settings" | "clock" | "mail" | "message" | "user" | "upload" | undefined | Optional | Registered glyph rendered as a tone `IconTile` in the leading slot. |
tone | ListItemTone | undefined | Optional | Tone for the generated leading `IconTile`. |
overline | React.ReactNode | Optional | Small copy shown above the title. |
overlineTrailing | React.ReactNode | Optional | Accessory pinned to the top-right, aligned with the overline (e.g. a count badge). |
title | React.ReactNode | Required | Primary row title. |
titleLines | number | undefined | Optional | Wraps the title across up to this many lines before clamping. Defaults to single-line truncation. |
description | React.ReactNode | Optional | Secondary row copy. |
descriptionLines | number | undefined | Optional | Wraps the description across up to this many lines before clamping. Defaults to single-line truncation. |
value | React.ReactNode | Optional | Right-aligned value shown in the title row. |
tag | React.ReactNode | Optional | Tag slot shown at the trailing edge. |
statusLabel | React.ReactNode | Optional | Status text rendered through ListItem.StatusIndicator. |
statusTone | "neutral" | "info" | "success" | "warning" | "danger" | undefined | Optional | Status color treatment for statusLabel. |
trailing | React.ReactNode | Optional | Custom trailing content. |
trailingIcon | React.ReactNode | Optional | Icon slot shown after other trailing content. |
chevron | boolean | undefined | Optional | Override for the disclosure chevron. Leave unset to derive it from interaction — any pressable row shows one, except selection rows and rows with caller-owned trailing content. Pass `true` to force it on (e.g. a non-interactive row inside a pressable card), or `false` to force it off. |
className | string | undefined | Optional | |
style | React.CSSProperties | undefined | Optional | |
divider | boolean | undefined | Optional | Shows a bottom divider when true. |
dividerMode | ListItemDividerMode | undefined | Optional | Divider alignment. |
padding | ListItemPadding | undefined | Optional | Row padding preset. |
size | ListItemSize | undefined | Optional | Row density. `sm` renders a compact row (32px leading slot). Defaults to `md`. |
surface | "page" | "surface" | undefined | Optional | Row background on the `page | surface` scale. Defaults to `surface` (elevated card row); `page` sits flush on a page-level background. |
id | string | undefined | Optional | Optional id for the row container or interactive control. |
ariaControls | string | undefined | Optional | Id of content controlled by this row when used as a disclosure trigger. |
expanded | boolean | undefined | Optional | Expanded state announced for interactive rows. |
disabled | boolean | undefined | Optional | Dims the row and blocks presses. A disabled selection row keeps its radio/checkbox semantics so the choice stays announced — it just can't be chosen. |
onPress | (() => void) | undefined | Optional | Called when the row is pressed. |
ariaLabel | string | undefined | Optional | Accessible label for interactive rows when visible copy is not sufficient. |
haptic | HapticFeedback | undefined | Optional | Haptic feedback for interactive row presses. Defaults to `true` (`light`). |
testId | string | undefined | Optional | Test selector. Lands on the row's button when it is pressable, otherwise on the container. |
List.Item.StatListItemStatProps
packages/design-system/src/components/organization/ListItem/ListItemStat/ListItemStat.tsx:10
| Prop | Type | Presence | Notes |
|---|---|---|---|
label | string | Required | The key, rendered as secondary text on the left. |
value | string | number | Required | The statistic, rendered as primary text on the right. |
divider | boolean | undefined | Optional | Shows the row divider when true.Source default: true |
testId | string | undefined | Optional | Test selector; lands on the wrapper around the row and its divider. |
List.Item.EmptyListItemEmptyProps
packages/design-system/src/components/organization/ListItem/ListItemEmpty/ListItemEmpty.tsx:10
| Prop | Type | Presence | Notes |
|---|---|---|---|
message | string | Required | The empty-state copy, rendered as secondary text. |
testId | string | undefined | Optional | Test selector for the placeholder container. |
List.Item.IconListItemIconProps
packages/design-system/src/components/organization/ListItem/ListItemIcon/ListItemIcon.tsx:11
| Prop | Type | Presence | Notes |
|---|---|---|---|
children | React.ReactNode | Optional | |
initial | string | undefined | Optional | Fallback initial shown when children are absent. |
tone | ListItemTone | undefined | Optional | Tokenized icon color treatment.Source default: 'neutral' |
label | string | undefined | Optional | Accessible label for meaningful icons. |
background | string | undefined | Optional | Custom background color. |
foreground | string | undefined | Optional | Custom foreground color. |
List.Item.StatusIndicatorStatusIndicatorProps
packages/design-system/src/components/status/StatusIndicator/StatusIndicator.tsx:25
| Prop | Type | Presence | Notes |
|---|---|---|---|
children | React.ReactNode | Required | |
tone | "neutral" | "info" | "success" | "warning" | "danger" | undefined | Optional | Semantic status color for the dot; maps to the `--cds-status-*` tokens. Defaults to `neutral`.Source default: 'neutral' |
className | string | undefined | Optional | |
testId | string | undefined | Optional | Optional test selector. |
List.Item.ArrowIconRead source for the API
packages/design-system/src/components/organization/ListItem/ListItemActionIcons/ListItemActionIcons.tsx:13
List.Item.ChevronIconRead source for the API
packages/design-system/src/components/organization/ListItem/ListItemActionIcons/ListItemActionIcons.tsx:20
List.Item.CopyIconRead source for the API
packages/design-system/src/components/organization/ListItem/ListItemActionIcons/ListItemActionIcons.tsx:27
List.Item.MailIconRead source for the API
packages/design-system/src/components/organization/ListItem/ListItemActionIcons/ListItemActionIcons.tsx:34
List.Item.PhoneIconRead source for the API
packages/design-system/src/components/organization/ListItem/ListItemActionIcons/ListItemActionIcons.tsx:41
List.Item.MessageIconRead source for the API
packages/design-system/src/components/organization/ListItem/ListItemActionIcons/ListItemActionIcons.tsx:48
List.DisclosureListDisclosureProps
packages/design-system/src/components/organization/List/ListDisclosure/ListDisclosure.tsx:43
| Prop | Type | Presence | Notes |
|---|---|---|---|
title | React.ReactNode | Required | Collapsed trigger title. |
expandedTitle | React.ReactNode | Optional | Trigger title shown while expanded. Defaults to `title`. |
description | React.ReactNode | Optional | Collapsed supporting copy. |
expandedDescription | React.ReactNode | Optional | Supporting copy shown while expanded. Defaults to `description`. |
children | React.ReactNode | Optional | |
renderChildren | (() => React.ReactNode) | undefined | Optional | Lazily creates revealed rows when the panel is rendered. |
open | boolean | undefined | Optional | Controlled open state. |
defaultOpen | boolean | undefined | Optional | Initial open state for uncontrolled usage.Source default: false |
onOpenChange | ((open: boolean) => void) | undefined | Optional | Called whenever the trigger changes open state. |
className | string | undefined | Optional | |
testId | string | undefined | Optional | Test selector for the wrapper; the trigger and panel take `-trigger` and `-panel` from it. |
List.SectionListSectionProps
packages/design-system/src/components/organization/List/ListSection/ListSection.tsx:10
| Prop | Type | Presence | Notes |
|---|---|---|---|
title | string | Required | Group title rendered as the labeled band. |
surface | DividerSurface | undefined | Optional | Band treatment, matching Divider. Defaults to `surface` for in-card grouping.Source default: 'surface' |
children | React.ReactNode | Required |
Only explicit destructured parameter initializers are extracted. Other runtime defaults remain in implementation source.
Overview
The container for stacked List.Item rows — it draws an automatic hairline between adjacent rows
and groups them with List.Section.
When to use
Reach for List any time you render a vertical run of rows that share separators — activity feeds,
settings, action lists. The container owns the dividers, so a row's own divider prop is ignored
inside a List. See the List.Item docs for the
row parts (leading, title, value, chevron, progress, selection).
- Sections whose bodies stay collapsed until tapped? Use
Accordion(independent chrome) orList.Disclosurefor a single inline "show more" that shares these separators. - A self-contained block of grouped content (heading + body + actions), not a row run? Use
Card.
Component specification
$schema
../../../specs/component-spec.schema.jsonParts
- Id
- root
- Label
- Root
- Description
- List surface that owns separators between adjacent rows.
- Required
- true
- Id
- item
- Label
- List.Item
- Description
- Base row with leading, title, description, value, and trailing slots.
- Id
- section
- Label
- List.Section
- Description
- Labeled band that groups rows.
- Id
- disclosure
- Label
- List.Disclosure
- Description
- Show-more row that reveals extra rows inline. The trigger centers its label and chevron.
- Id
- selection
- Label
- List.Item.Selection
- Description
- Selection row with a check or radio control, trailing by default or replacing the leading icon via selectionPlacement='leading'.
- Id
- progress
- Label
- List.Item.Progress
- Description
- Row with inline or trailing progress.
- Id
- stat
- Label
- List.Item.Stat
- Description
- Compact label and value row.
- Id
- empty
- Label
- List.Item.Empty
- Description
- Placeholder row for an empty list.
- Id
- icon
- Label
- List.Item.Icon
- Description
- Leading icon helper for a row.
Allowed Design Choices
- Variants
- Container
- Label
- Container
- Description
- The single list surface; rows come from List.Item helpers.
- Sizes
Variants
- Id
- container
- Label
- Container
- Description
- Row container with automatic separators.
- Platforms
- ios
- android
- web
Sizes
None specifiedMeasurements
- Id
- row-min-height
- Label
- Rich row minimum height
- Kind
- exact
- Token
- --cds-size-80
- Value
- 80
- Unit
- px
- Applies To
- item
- Id
- compact-row-min-height
- Label
- Compact row minimum height
- Kind
- exact
- Token
- --cds-size-48
- Value
- 48
- Unit
- px
- Applies To
- item
- stat
- Id
- selection-row-min-height
- Label
- Selection row minimum height, copy only
- Kind
- at-least
- Token
- --cds-size-64
- Value
- 64
- Unit
- px
- Applies To
- selection
- Id
- row-gap
- Label
- Row content gap
- Kind
- exact
- Token
- --cds-space-12
- Value
- 12
- Unit
- px
- Applies To
- item
- Id
- row-inset
- Label
- Row horizontal inset
- Kind
- exact
- Token
- --cds-space-20
- Value
- 20
- Unit
- px
- Applies To
- item
Layout
- Alignment
- Leading, body, value, and trailing align on the row center line.
- Flow
- Rows stack vertically; the container inserts a hairline between adjacent rows and expands sections into labeled bands.
- Notes
- Use SectionHeader for a heading that stands alone outside a list.
- Use Accordion for independent expandable panels.
Typography And Color
- Typography
- Label
- Title
- Description
- Row titles use the body ramp.
- Token
- --cds-type-body-size
- Label
- Description
- Description
- Row descriptions use the body-small ramp.
- Token
- --cds-type-body-small-size
- Colors
- Label
- Text
- Description
- Row text uses primary text color.
- Token
- --cds-text-primary
- Label
- Separator
- Description
- Adjacent rows are divided with the divider color.
- Token
- --cds-divider
States
- Id
- default
- Label
- Default
- Description
- Static rows separated by hairlines.
- Id
- pressable
- Label
- Pressable
- Description
- A row with onPress becomes a tap target, usually with a chevron.
- Id
- selected
- Label
- Selected
- Description
- A selection row reflects its selected state.
- Id
- disabled
- Label
- Disabled
- Description
- A dimmed row that cannot be pressed; a disabled selection row still announces its selection state.
Behavior
- Label
- Owns separators
- Description
- The container draws separators, so a row's own divider is ignored inside a List.
- Label
- Grouping
- Description
- List.Section expands into a labeled band followed by its divider-off rows.
- Label
- Section-aware disclosure separators
- Description
- Revealed rows inside List.Disclosure get separators like the root, but never adjacent to a Divider, so a section header's own hairline is not doubled.
- Label
- Tag-only sizing
- Description
- A row whose only trailing content is a tag keeps the plain row's height: the tag substitutes for the value text, not for a leading tile, so it does not promote the row to the rich 80px accessory height. Adding a chevron or custom trailing alongside the tag does.
- Label
- Selection placement
- Description
- selectionPlacement='leading' renders the selection control in the leading slot, replacing the leading icon — the iOS edit-mode treatment for icon-led rows. Default stays trailing.
Accessibility
- Label
- List semantics
- Description
- The container exposes role=list and owns a role=listitem wrapper for each content row; section dividers are labels rather than counted rows. Set ariaLabel to name the list. Standalone row components do not claim listitem semantics.
- Label
- Row targets
- Description
- Pressable rows are buttons with their own testId and accessible name.
Content Adaptation
- Label
- Row helpers
- Description
- Selection, Progress, Stat, Empty, and Icon helpers shape rows for different content.
- Label
- Truncation
- Description
- Titles and values truncate to one line while descriptions can wrap.
Motion Haptics
- Motion
- Label
- Disclosure
- Description
- List.Disclosure animates revealed rows inline; base rows do not animate.
- Haptics
- Label
- Row haptic
- Description
- Pressable and selection rows request feedback through their own behavior.