List
Structured containers for related content, with flush, plain, numbered, and horizontal layout variants.
Overview
<List> renders a structured container for related content, with consistent spacing, borders, and
typography through Chassis's design token system. Beyond plain items, it supports interactive
elements, custom content, and composition with other components.
Basic usage
<List> and <ListItem> build an unordered list, establishing the spacing, borders, and
typography the rest of this doc builds on.
- Cras justo odio
- Dapibus ac facilisis in
- Morbi leo risus
- Porta ac consectetur ac
- Vestibulum at eros
import { List, ListItem } from '@chassis-ui/react'
export const Example = () => {
return (
<List>
<ListItem>Cras justo odio</ListItem>
<ListItem>Dapibus ac facilisis in</ListItem>
<ListItem>Morbi leo risus</ListItem>
<ListItem>Porta ac consectetur ac</ListItem>
<ListItem>Vestibulum at eros</ListItem>
</List>
)
}Data-driven usage
Pass an items array to render the list from data instead of composing <ListItem> children.
Each item accepts label, href, color, active, and disabled.
import { List } from '@chassis-ui/react'
export const Example = () => {
return (
<List
items={[
{ label: 'Dashboard', href: '#', active: true },
{ label: 'Profile', href: '#' },
{ label: 'Settings', href: '#' },
{ label: 'Billing', href: '#', disabled: true }
]}
/>
)
}Each item's color remaps it to one of the context colors below.
- Default item
- Primary item
- Success item
- Danger item
- Warning item
import { List } from '@chassis-ui/react'
export const Example = () => {
return (
<List
items={[
{ label: 'Default item' },
{ label: 'Primary item', color: 'primary' },
{ label: 'Success item', color: 'success' },
{ label: 'Danger item', color: 'danger' },
{ label: 'Warning item', color: 'warning' }
]}
/>
)
}Active items
Add the active boolean prop to a <ListItem> to mark it as the current selection. An active
item gets an aria-current="true" attribute automatically.
- Cras justo odio
- Dapibus ac facilisis in
- Morbi leo risus
- Porta ac consectetur ac
- Vestibulum at eros
import { List, ListItem } from '@chassis-ui/react'
export const Example = () => {
return (
<List>
<ListItem active>Cras justo odio</ListItem>
<ListItem>Dapibus ac facilisis in</ListItem>
<ListItem>Morbi leo risus</ListItem>
<ListItem>Porta ac consectetur ac</ListItem>
<ListItem>Vestibulum at eros</ListItem>
</List>
)
}Disabled items
Add the disabled boolean prop to a <ListItem> to render it disabled. A disabled item gets an
aria-disabled="true" attribute automatically.
The disabled state only changes the visual appearance. For interactive elements like links, additional JavaScript is needed to fully disable interaction behavior.
- Cras justo odio
- Dapibus ac facilisis in
- Morbi leo risus
- Porta ac consectetur ac
- Vestibulum at eros
import { List, ListItem } from '@chassis-ui/react'
export const Example = () => {
return (
<List>
<ListItem disabled>Cras justo odio</ListItem>
<ListItem>Dapibus ac facilisis in</ListItem>
<ListItem>Morbi leo risus</ListItem>
<ListItem>Porta ac consectetur ac</ListItem>
<ListItem>Vestibulum at eros</ListItem>
</List>
)
}Links and buttons
Set href or component="button" to create actionable list items with hover, disabled, and active
states. href renders an <a>, as it does on every component that takes one. This applies the
.list-action modifier class, separating interactive states from standard read-only items. Use
href when the action navigates to a new location, and component="button" when it triggers an
in-page behavior — a native <button>'s disabled
attribute both visually styles the element and prevents interaction, while an <a> only gets the
visual .disabled styling and needs additional JavaScript to fully prevent interaction.
Because <a>/<button> elements aren't valid children of a <ul>/<ol>, <List> automatically
renders its root as a <div> instead whenever an item is interactive (an interactive data-driven
item, or a <ListItem> child that renders an <a> or <button>, through href, component or
its asChild element) — pass component explicitly if you need to override that.
import { List, ListItem } from '@chassis-ui/react'
export const Example = () => {
return (
<List>
<ListItem href="#" active>
Cras justo odio
</ListItem>
<ListItem href="#">Dapibus ac facilisis in</ListItem>
<ListItem href="#">Morbi leo risus</ListItem>
<ListItem href="#">Porta ac consectetur ac</ListItem>
<ListItem href="#" disabled>
Vestibulum at eros
</ListItem>
</List>
)
}The same markup with component="button" instead:
import { List, ListItem } from '@chassis-ui/react'
export const Example = () => {
return (
<List>
<ListItem component="button" active>
Cras justo odio
</ListItem>
<ListItem component="button">Dapibus ac facilisis in</ListItem>
<ListItem component="button">Morbi leo risus</ListItem>
<ListItem component="button">Porta ac consectetur ac</ListItem>
<ListItem component="button" disabled>
Vestibulum at eros
</ListItem>
</List>
)
}Layout variations
Flush list
Add the flush boolean prop to remove outer borders and rounded corners, rendering list items
edge-to-edge in a parent container (e.g., a card).
- Cras justo odio
- Dapibus ac facilisis in
- Morbi leo risus
- Porta ac consectetur ac
- Vestibulum at eros
import { List, ListItem } from '@chassis-ui/react'
export const Example = () => {
return (
<List flush>
<ListItem>Cras justo odio</ListItem>
<ListItem>Dapibus ac facilisis in</ListItem>
<ListItem>Morbi leo risus</ListItem>
<ListItem>Porta ac consectetur ac</ListItem>
<ListItem>Vestibulum at eros</ListItem>
</List>
)
}Plain layout
Add the plain boolean prop for a minimal list that removes outer borders, rounded corners, and
horizontal padding — a compact fit for content areas like search results or content feeds.
- Cras justo odio
- Dapibus ac facilisis in
- Morbi leo risus
- Porta ac consectetur ac
- Vestibulum at eros
import { List, ListItem } from '@chassis-ui/react'
export const Example = () => {
return (
<List plain>
<ListItem>Cras justo odio</ListItem>
<ListItem>Dapibus ac facilisis in</ListItem>
<ListItem>Morbi leo risus</ListItem>
<ListItem>Porta ac consectetur ac</ListItem>
<ListItem>Vestibulum at eros</ListItem>
</List>
)
}Both flush and plain remove outer borders and rounded corners. plain also removes
horizontal padding, for a more compact appearance.
Numbered lists
Add the numbered boolean prop to sequentially number list items via CSS counters rather than
browser defaults. Pair it with component="ol" for semantic correctness.
- A list item
- A list item
- A list item
import { List, ListItem } from '@chassis-ui/react'
export const Example = () => {
return (
<List component="ol" numbered>
<ListItem>A list item</ListItem>
<ListItem>A list item</ListItem>
<ListItem>A list item</ListItem>
</List>
)
}Horizontal layout
Add layout="horizontal" to switch a list from column to row layout across all breakpoints.
Adjacent items share a single border edge, and outer corners stay rounded while inner corners are
squared off.
Responsive variants use container queries —
each layout="{breakpoint}:horizontal" value activates at or above the specified container width.
Wrap the list in a .contains-inline container to establish the container context.
layout="horizontal" cannot be combined with flush — the flush variant removes the inline
borders that separate items in the horizontal layout.
- Cras justo odio
- Dapibus ac facilisis in
- Morbi leo risus
- Cras justo odio
- Dapibus ac facilisis in
- Morbi leo risus
- Cras justo odio
- Dapibus ac facilisis in
- Morbi leo risus
- Cras justo odio
- Dapibus ac facilisis in
- Morbi leo risus
import { List, ListItem } from '@chassis-ui/react'
export const Example = () => {
return (
<div className="contains-inline">
<List className="mb-md" layout="horizontal">
<ListItem>Cras justo odio</ListItem>
<ListItem>Dapibus ac facilisis in</ListItem>
<ListItem>Morbi leo risus</ListItem>
</List>
<List className="mb-md" layout="sm:horizontal">
<ListItem>Cras justo odio</ListItem>
<ListItem>Dapibus ac facilisis in</ListItem>
<ListItem>Morbi leo risus</ListItem>
</List>
<List className="mb-md" layout="md:horizontal">
<ListItem>Cras justo odio</ListItem>
<ListItem>Dapibus ac facilisis in</ListItem>
<ListItem>Morbi leo risus</ListItem>
</List>
<List layout="lg:horizontal">
<ListItem>Cras justo odio</ListItem>
<ListItem>Dapibus ac facilisis in</ListItem>
<ListItem>Morbi leo risus</ListItem>
</List>
</div>
)
}Apply the .flex-fill or .flex-grow-1 utility classes to list items to stretch them across the
full list width — .flex-fill shares the available width equally, while .flex-grow-1 grows from
each item's natural content width.
- Cras justo odio
- Dapibus ac facilisis in
- Vestibulum at eros
import { List, ListItem } from '@chassis-ui/react'
export const Example = () => {
return (
<List layout="horizontal">
<ListItem className="flex-fill">Cras justo odio</ListItem>
<ListItem className="flex-fill">Dapibus ac facilisis in</ListItem>
<ListItem className="flex-fill">Vestibulum at eros</ListItem>
</List>
)
}Contextual classes
Use the color prop to style list items with a stateful background and color.
- Dapibus ac facilisis in
- A simple primary list item
- A simple secondary list item
- A simple success list item
- A simple danger list item
- A simple warning list item
- A simple info list item
import { List, ListItem } from '@chassis-ui/react'
export const Example = () => {
return (
<List>
<ListItem>Dapibus ac facilisis in</ListItem>
{(['primary', 'secondary', 'success', 'danger', 'warning', 'info'] as const).map((color) => (
<ListItem color={color} key={color}>
A simple {color} list item
</ListItem>
))}
</List>
)
}The same color prop works on <a>/<button> list items, adding hover styles not present on
plain items, alongside active to mark a current selection among them.
import { List, ListItem } from '@chassis-ui/react'
export const Example = () => {
return (
<List>
<ListItem href="#">Dapibus ac facilisis in</ListItem>
{(['primary', 'secondary', 'success', 'danger', 'warning', 'info'] as const).map((color) => (
<ListItem href="#" color={color} key={color}>
A simple {color} list action
</ListItem>
))}
</List>
)
}Context color alone provides only a visual indication, which isn't conveyed to assistive
technology users. Make sure information denoted by the color is either obvious from the content
itself (e.g. the visible text), or included through alternative means, such as additional text
hidden with the .visually-hidden class.
Context styles
<List> also accepts color together with a variant of solid, outline, or smooth to
color the whole list container based on the design system's color palette.
- Cras justo odio
- Dapibus ac facilisis in
- Vestibulum at eros
- Cras justo odio
- Dapibus ac facilisis in
- Vestibulum at eros
- Cras justo odio
- Dapibus ac facilisis in
- Vestibulum at eros
- Cras justo odio
- Dapibus ac facilisis in
- Vestibulum at eros
import { Grid, List, ListItem } from '@chassis-ui/react'
export const Example = () => {
return (
<Grid columns={{ base: 1, md: 2 }} gap="lg">
<div>
<List color="primary">
<ListItem>Cras justo odio</ListItem>
<ListItem>Dapibus ac facilisis in</ListItem>
<ListItem>Vestibulum at eros</ListItem>
</List>
</div>
<div>
<List color="primary" variant="solid" flush className="rounded">
<ListItem>Cras justo odio</ListItem>
<ListItem>Dapibus ac facilisis in</ListItem>
<ListItem>Vestibulum at eros</ListItem>
</List>
</div>
<div>
<List color="primary" variant="smooth" flush className="rounded">
<ListItem>Cras justo odio</ListItem>
<ListItem>Dapibus ac facilisis in</ListItem>
<ListItem>Vestibulum at eros</ListItem>
</List>
</div>
<div>
<List color="primary" variant="outline">
<ListItem>Cras justo odio</ListItem>
<ListItem>Dapibus ac facilisis in</ListItem>
<ListItem>Vestibulum at eros</ListItem>
</List>
</div>
</Grid>
)
}With badges
Add badges to a list item to show unread counts, activity, and more.
- Cras justo odio14
- Dapibus ac facilisis in2
- Morbi leo risus1
import { Badge, List, ListItem } from '@chassis-ui/react'
export const Example = () => {
return (
<List>
<ListItem className="d-flex justify-content-between align-items-center">
Cras justo odio
<Badge color="primary" className="rounded-full">
14
</Badge>
</ListItem>
<ListItem className="d-flex justify-content-between align-items-center">
Dapibus ac facilisis in
<Badge color="primary" className="rounded-full">
2
</Badge>
</ListItem>
<ListItem className="d-flex justify-content-between align-items-center">
Morbi leo risus
<Badge color="primary" className="rounded-full">
1
</Badge>
</ListItem>
</List>
)
}Custom content
A list item accepts nearly any content, including for linked items, with the help of flexbox utilities.
List item heading
3 days agoDonec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.
Donec id elit non mi porta.List item heading
3 days agoDonec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.
Donec id elit non mi porta.List item heading
3 days agoDonec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.
Donec id elit non mi porta.import { List, ListItem } from '@chassis-ui/react'
export const Example = () => {
return (
<List>
<ListItem href="#" active>
<div className="d-flex w-100 justify-content-between">
<h5 className="mb-xs">List item heading</h5>
<small>3 days ago</small>
</div>
<p className="mb-xs">
Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius
blandit.
</p>
<small>Donec id elit non mi porta.</small>
</ListItem>
<ListItem href="#">
<div className="d-flex w-100 justify-content-between">
<h5 className="mb-xs">List item heading</h5>
<small className="fg-subtle">3 days ago</small>
</div>
<p className="mb-xs">
Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius
blandit.
</p>
<small className="fg-subtle">Donec id elit non mi porta.</small>
</ListItem>
<ListItem href="#">
<div className="d-flex w-100 justify-content-between">
<h5 className="mb-xs">List item heading</h5>
<small className="fg-subtle">3 days ago</small>
</div>
<p className="mb-xs">
Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius
blandit.
</p>
<small className="fg-subtle">Donec id elit non mi porta.</small>
</ListItem>
</List>
)
}Checkboxes and radios
Place a checkbox or radio within a list item and customize it as needed.
import { Checkbox, List, ListItem } from '@chassis-ui/react'
export const Example = () => {
return (
<List>
<ListItem>
<Checkbox label="Cras justo odio" />
</ListItem>
<ListItem>
<Checkbox label="Dapibus ac facilisis in" defaultSelected />
</ListItem>
<ListItem>
<Checkbox label="Morbi leo risus" defaultSelected />
</ListItem>
<ListItem>
<Checkbox label="orta ac consectetur ac" />
</ListItem>
<ListItem>
<Checkbox label="Vestibulum at eros" />
</ListItem>
</List>
)
}Since <Checkbox> always renders a <label> as its root element, the .list-item class applies
directly to it too, for a large hit area. Because a bare <label> isn't a valid <ul> child either,
pass component="div" to <List> here — the same rule covered in
Links and buttons above.
import { Checkbox, List } from '@chassis-ui/react'
export const Example = () => {
return (
<List component="div">
<Checkbox className="list-item" label="Cras justo odio" />
<Checkbox className="list-item" label="Dapibus ac facilisis in" defaultSelected />
<Checkbox className="list-item" label="Morbi leo risus" defaultSelected />
<Checkbox className="list-item" label="orta ac consectetur ac" />
<Checkbox className="list-item" label="Vestibulum at eros" />
</List>
)
}API
List
| Prop | Type | Default |
|---|---|---|
asChild? | boolean | — |
Render the single child element in place of this component's own element, with this
component's classes, props and ref merged onto it: <Button asChild><Link href="/login">Log
in</Link></Button>. The alternative to component for React Server Components — an element
can be passed from the server to this package's client components, a component reference
(component={Link}) can't. | ||
className? | string | — |
| A string of all className you want applied to the component. | ||
color? | ContextColor | — |
| Sets the color of the component to one of Chassis context colors. | ||
component? | ElementType | — |
Component used for the root node. Either a string to use a HTML element or a component.
Defaults to 'ul', unless an item (a data-driven item with href, or a <ListItem> child
rendering an <a>/<button> through component or asChild) is interactive — a bare
<a>/<button> isn't a valid direct child of <ul>/<ol>, so the default switches to
'div' instead. Pass component explicitly to opt out of this. | ||
flush? | boolean | — |
Remove outer borders and rounded corners to render list items edge-to-edge in a parent component (e.g., <Card>). | ||
items? | ListItemDef[] | — |
| Array of item definitions for data-driven rendering. When provided, children are ignored. | ||
layout? | "horizontal" | "sm:horizontal" | "md:horizontal" | "lg:horizontal" | "xl:horizontal" | "2xl:horizontal" | — |
| Specify a layout type. | ||
numbered? | boolean | — |
Number list items sequentially using CSS counters. Pair with component="ol" for semantic correctness. | ||
plain? | boolean | — |
| Remove outer borders, rounded corners, and horizontal padding for a minimal, edge-to-edge appearance. | ||
ref? | any | — |
variant? | ContextStyle | — |
Applies a .solid, .outline, or .smooth context style. Only meaningful together with color. | ||
ListItem
| Prop | Type | Default |
|---|---|---|
active? | boolean | — |
| Toggle the active state for the component. | ||
asChild? | boolean | — |
Render the single child element in place of this component's own element, with this
component's classes, props and ref merged onto it: <Button asChild><Link href="/login">Log
in</Link></Button>. The alternative to component for React Server Components — an element
can be passed from the server to this package's client components, a component reference
(component={Link}) can't. | ||
className? | string | — |
| A string of all className you want applied to the component. | ||
color? | ContextColor | — |
| Sets the color of the component to one of Chassis context colors. | ||
component? | ElementType | — |
| Component used for the root node. Either a string to use a HTML element or a component. | ||
disabled? | boolean | — |
| Toggle the disabled state for the component. | ||
href? | string | — |
The href attribute specifies the URL of the page the link goes to. Renders an <a> in place
of the <li>, unless component or asChild chose the element. Inside a List, the list
renders a <div> around it in place of the <ul>. | ||
ref? | any | — |
ListItemDef
Shape of each entry in List's items array (data-driven rendering).
| Prop | Type | Default |
|---|---|---|
active? | boolean | — |
| Marks the item as active. | ||
color? | ContextColor | — |
| Sets the color of the item. | ||
disabled? | boolean | — |
| Marks the item as disabled. | ||
href? | string | — |
| Makes the item a link. | ||
id? | string | number | — |
Stable key for the rendered item. Falls back to the item's index in items. | ||
label | ReactNode | — |
| Item label content. | ||