Skip to Content
Lists and empty states

Lists and empty states

Build readable collections with native list structure and separate primary and secondary actions.

Interactive example React 19 · local alpha

recent

Ready

No archived notes

Archived notes will appear here.

Usage

The example assumes the stylesheet and a Theme are already present.

import { List, ListItem, SectionHeader, EmptyState, Button, } from "@pane-ui/react"; <> <SectionHeader id="recent" level={3} meta="1 collection"> recent </SectionHeader> <List aria-labelledby="recent" animate> <ListItem title="Coastal walk" description="24 photos" action={{ type: "link", href: "/collections/coast" }} actions={<Button aria-label="Save Coastal walk">Save</Button>} /> </List> <EmptyState title="No archived collections" description="Archived collections appear here." /> </>;

API

Prop / exportType / defaultPurpose
List.animateboolean; default falseOpt-in row entrance with cumulative delay capped at 240ms.
ListItem.titleReactNode; requiredMain row content, not the native title attribute.
description, leading, meta, actionsReactNode; optionalSupporting content and separate secondary controls.
actionListItemAction; optionalLink: type/link href/props; button: type/button props. Omitted is static.
SectionHeader.level, meta2 (default), 3 or 4; optional ReactNode metaSemantic heading level and supporting metadata.
EmptyState.titleReactNode; requiredNames its section.
EmptyState optional contentdescription/actions/icon: ReactNodeIcon is decorative; actions contain recovery controls.
EmptyState.headingLevel2, 3 (default), 4Set to match the surrounding document hierarchy.
Native props / refsList: ul; ListItem: li; SectionHeader: heading; EmptyState: sectionListItem ref remains li even with an interactive primary action.

Behavior and composition

Place ListItem directly inside List. SectionHeader belongs outside the ul; associate it with aria-labelledby when useful. The list keeps an explicit list role even when bullets are removed. Stable React keys preserve row identity; entrance animation runs when rows mount, not every data update.

A link action needs a real href and retains browser navigation and modifier clicks. A button action defaults to type button; use its props for native handlers, disabled or a concise aria-label. Keep title, description, leading and meta presentational when inside a primary link/button. Put secondary buttons and menus in actions so controls remain siblings rather than nested.

EmptyState is a named section, not a live region. Distinguish first-use emptiness from zero filter results and offer an appropriate next action. Filtering, selection, virtualization and result announcements are application-owned. If a mutation removes the focused row, restore focus to a surviving control such as search.

Last updated on