The example below loads live from Storybook; open it in Storybook for the controls.
Default
Section titled “Default”A ListItem has a leading visual (leading), a title, a subtitle (subtitle), short information at the end (meta) and an action or badge (trailing). The default row is static: it does not change on hover and is not a tab stop. Put rows in ListItem.List; the list is a <ul> and the rows are <li>.
- User 1Secondary textToday
import { Avatar, ListItem } from '@bigbang/ui';
export default function Default() { return ( <ListItem.List className="w-full max-w-md" aria-label="List"> <ListItem title="User 1" subtitle="Secondary text" meta="Today" leading={<Avatar name="User 1" decorative />} /> </ListItem.List> );}size sets the block padding: sm is 8 px, md is 12 px, lg is 16 px. lg also sets the title to 16 px. Give the list divided for separator lines. variant="outline" draws a border around the row and variant="muted" tints it.
- SmallSecondary text
- MediumSecondary text
- LargeSecondary text
import { Icon, ListItem } from '@bigbang/ui';
export default function Sizes() { return ( <ListItem.List divided className="w-full max-w-md" aria-label="List"> <ListItem size="sm" title="Small" subtitle="Secondary text" leading={<Icon name="settings" tone="subtle" />} /> <ListItem size="md" title="Medium" subtitle="Secondary text" leading={<Icon name="settings" tone="subtle" />} /> <ListItem size="lg" title="Large" subtitle="Secondary text" leading={<Icon name="settings" tone="subtle" />} /> </ListItem.List> );}Link rows
Section titled “Link rows”With render the whole row is one target: render={<a href="…" />}. On hover, press and focus the row is tinted with motion.stateLayer; keyboard focus shows a 2 px ring. selected marks the current page: a selected surface, a 2 px bar at the inline start and aria-current="true".
import { Icon, ListItem } from '@bigbang/ui';
export default function Links() { return ( <nav aria-label="Account" className="w-full max-w-md"> <ListItem.List> <ListItem title="Profile" leading={<Icon name="user" tone="subtle" />} trailing={<Icon name="chevron-right" tone="subtle" />} render={<a href="#profile" />} /> <ListItem title="Settings" subtitle="Account and appearance" leading={<Icon name="settings" tone="subtle" />} trailing={<Icon name="chevron-right" tone="subtle" />} selected render={<a href="#settings" />} /> <ListItem title="Notifications" subtitle="Email and app" leading={<Icon name="bell" tone="subtle" />} trailing={<Icon name="chevron-right" tone="subtle" />} render={<a href="#notifications" />} /> </ListItem.List> </nav> );}A separate action
Section titled “A separate action”When a row needs a button, keep the row static and put a Button in trailing. When the row is clickable, trailing must not hold a link or a button: nested interactive elements are invalid. The button is its own tab stop.
- First itemSecondary text
- Second itemSecondary text
- Third itemSecondary text
import { Button, Icon, ListItem } from '@bigbang/ui';
export default function TrailingAction() { return ( <ListItem.List divided className="w-full max-w-md" aria-label="List"> {['First item', 'Second item', 'Third item'].map((title) => ( <ListItem key={title} title={title} subtitle="Secondary text" leading={<Icon name="file" tone="subtle" />} trailing={ <Button size="sm" variant="tertiary"> Edit </Button> } /> ))} </ListItem.List> );}Disabled
Section titled “Disabled”disabled greys the row out. An interactive row leaves the tab order and ignores clicks (aria-disabled="true").
import { Icon, ListItem } from '@bigbang/ui';
export default function Disabled() { return ( <ListItem.List className="w-full max-w-md" aria-label="List"> <ListItem title="Settings" subtitle="Account and appearance" leading={<Icon name="settings" />} render={<a href="#settings" />} /> <ListItem title="Notifications" subtitle="Email and app" leading={<Icon name="bell" />} disabled render={<a href="#notifications" />} /> </ListItem.List> );}Light and dark mode
Section titled “Light and dark mode”ListItem takes every colour from surface, text and border tokens.
import { Icon, ListItem } from '@bigbang/ui';
export default function Links() { return ( <nav aria-label="Account" className="w-full max-w-md"> <ListItem.List> <ListItem title="Profile" leading={<Icon name="user" tone="subtle" />} trailing={<Icon name="chevron-right" tone="subtle" />} render={<a href="#profile" />} /> <ListItem title="Settings" subtitle="Account and appearance" leading={<Icon name="settings" tone="subtle" />} trailing={<Icon name="chevron-right" tone="subtle" />} selected render={<a href="#settings" />} /> <ListItem title="Notifications" subtitle="Email and app" leading={<Icon name="bell" tone="subtle" />} trailing={<Icon name="chevron-right" tone="subtle" />} render={<a href="#notifications" />} /> </ListItem.List> </nav> );}