ListView
Show a collection of items as a list, with optional per-row controls.
A <ListView> shows a collection of items as rows in a list. Each row can carry its own controls, such as a <Button> or an <ActionMenu>, so users can act on an item without leaving the page.
Use it for collections people work through, like a notification feed or a list of uploaded files.
Anatomy
- List: The container that holds all rows.
- Item: A single row representing one entry of the collection.
- Text value: The primary text of a row.
- Description: Optional secondary text below the text value, like a timestamp or a file size. One per row, and it takes inline markup, so several facts can share a line: "Updated 3 days ago · 2.1 MB".
- Actions: Optional trailing controls for the row, such as a button or a row menu.
Appearance
The appearance of a component can be customized using the variant and size props. These props adjust the visual style and dimensions of the component, available values are based on the active theme.
| Property | Type | Description |
|---|---|---|
variant | default | The available variants of this component. |
size | - | The available sizes of this component. |
Usage
Reach for a <ListView> when the user works through a collection one entry at a time, acting on a row where it sits instead of opening it. Typical cases:
- Notification and activity feeds: a stream of events the user scans, then dismisses or mutes per row.
- Resource lists: files, documents, or team members, each with rename, share, and delete behind a row menu.
- Connections and integrations: linked accounts or services the user reviews and disconnects individually.
A row is one item, not a record split into fields. A <ListView> gives you a text column and a trailing control, with nothing aligned between rows, so there is no way to scan a column or sort by one. Once the user needs to compare entries against each other (a status column, a size to sort by, dates to line up), reach for a <Table>.
A <ListView> also has no selection. Rows are operated where they sit, and nothing is staged or submitted. To have the user choose from a set, see <ListView> vs. <SelectList>.
Row text
Author a row's primary text with <TextValue>, or pass a bare string. Secondary text goes in a <Description>, one per row.
To emphasise part of a row's text, nest <Text as="span"> inside <TextValue> or <Description> rather than adding a <Text> of its own:
<ListView.Item id="deploy" textValue="Deploy succeeded">
<TextValue>
Deploy{' '}
<Text as="span" weight="bold">
succeeded
</Text>
</TextValue>
</ListView.Item>Row actions
Keep the action users reach for most often visible as an icon button and group the rest behind an <ActionMenu>. More than two visible buttons per row turns the list into a wall of controls that competes with the text people are scanning.
Pick a glyph that says what happens to the row, like Archive, Check, or BellOff. An X means "close this" everywhere else in Marigold, and a row's action doesn't close anything. Rare or irreversible commands like deleting belong in the menu, as an <ActionMenu.Item variant="destructive">, not behind a one-click icon button.
When no single action stands out, or the available actions differ from row to row, drop the visible button and use the menu on its own.
A row has a single cell for trailing controls, so wrap two or more in a <ButtonGroup>. Left loose, they claim the same cell and stack. That cell takes Button-family controls only. A <Badge> or status pill has no slot yet. It sits in the trailing cell only while that cell is empty. Add a control to the row and the grid pushes it onto a new full-width line under the description, where it reads as part of the row's text.
Empty state
Pass an <EmptyState> to the emptyState prop so a list with nothing to show still explains itself instead of rendering as a blank surface.
No resources yet
<ListView> vs. <SelectList>
The two render a similar stack of rich rows, so the choice comes down to selection. A <SelectList> is a form field: rows are selectable, the selection is its value, and that value submits and validates with the rest of the form. A <ListView> has no selection. Every row carries its own controls instead, and each one acts the moment it is used.
If the user is choosing something and that choice has to travel anywhere, use a <SelectList>.
Do
Use <ListView> to present a collection the user works through, like a
notification feed or a list of files.
Don't
Don't use <ListView> for a choice that gets submitted with a form,
that's what <SelectList> is for.
Accessibility
- Arrow keys move focus between rows,
Tabreaches the controls inside the focused row. - Give the list an
aria-label, oraria-labelledbywhen a heading nearby already names it. - Set
textValueon a row whose text isn't a plain string, screen readers use it as the row's accessible name.
<Title> normally renders a real heading. Inside a row it renders as a <span> instead, so a heading-like row doesn't add an entry to the page's heading outline.
Props
ListView
Prop
Type
Accessibility props (4)
Prop
Type
DOM event handlers (64)
Prop
Type
ListView.Item
Prop
Type
DOM event handlers (63)
Prop
Type
Alternative components
- List: Use for a static list of text with no per-row controls.
- SelectList: Use when the selection becomes a submitted form value.
- Select: Use for a compact single/multi-select form field.
- Table: Use when each row is a record with multiple columns of structured data to compare, not a flat list of operable items.
- Menu: Use for a set of commands that close the surface on activation.
- Card: Use to present one item, like an event or a product, as a self-contained visual unit.