GroupedList
Things grouped in one well: card rows with media, a title, a line and a value, under optional titles with a … menu, and a dashed row that adds one more.
import { GroupedList } from "@butteryui/react";Demo
When to use it
Use it for
- A short set of records an overview page shows whole: warehouses, payout accounts, this week's roasts
- Groups of rows that each lead to their own page
Not for
- Many rows to sort, filter or select: use DataTable
- Navigation between pages: use Sidebar
Examples
Roast plan
This week's roasts by day, each day with a dashed row that adds one more.
- Guji, Ethiopia24 bags120 kg
- House espresso40 bags200 kg
- Huila, Colombia18 bags90 kg
Stock by warehouse
Green coffee on hand: the total, then each warehouse's lots linking to their pages, each warehouse renamed or archived from its … menu.
- All warehouses2,140 kg
Variants and states
Groups in one well
Rows that lead somewhere are links and lift on hover; the first group has no title.
- All warehousesGreen coffee on hand2,140 kg
People, with long names
A title too long for its row ends in an ellipsis; a long line wraps under it.
- Marguerite Okonkwo-Lindqvist, head of purchasingCorner Bakery Cooperative · 12 kg every other Monday, ground for filter, delivered before opening€1,240
- Tomás FerreiraBlue Door Café€380
Props
GroupedList
It also takes ComponentPropsWithRef<"div">.
GroupedList.Add
| Prop | Type | Default | Description |
|---|---|---|---|
labelrequired | string | What it adds, such as "Add a roast", shown beside a plus. |
It also takes Omit<ComponentPropsWithRef<"button">, "children">.
GroupedList.Group
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | The group's title over its rows, which names their list. Leave it out for rows that need none. | |
actions | ReactNode | Actions on the whole group in a "…" menu at the end of its title's row, as Menu.Items. | |
actionsLabel | string | Names the "…" button. Defaults to "Actions for" and the title. |
It also takes Omit<ComponentPropsWithRef<"div">, "title">.
GroupedList.Item
| Prop | Type | Default | Description |
|---|---|---|---|
titlerequired | string | What the row is, such as a roast's name. | |
description | ReactNode | A line under the title in text-secondary. | |
media | ReactNode | Something before the text, such as an InitialsTile or an Avatar. | |
value | ReactNode | A value at the row's end, such as a count or an amount, in tabular figures. | |
href | string | Makes the row a link to its page. | |
onClick | ((event: MouseEvent<HTMLElement>) => void) | Makes the row a button, or runs as its link is followed, where a router can take over. |
Accessibility
Each group's rows are a list named by its title. A row with href is a link and one with onClick a button, named by its text; the … button is named Actions for the group. The add row is a button named by its label.
| Keys | What they do |
|---|---|
| Enter | Follows a row that's a link |
| Enter or Space | Presses a row that's a button or the add row, or opens a group's … menu |
| Escape | Closes the open … menu and puts focus back on its button |
Motion
It appears with a `Presence` preset and leaves faster than it came, in about 60% of the time.
With reduced motion: A group's … button still shrinks to 97% while it's pressed, but at once instead of easing, and its menu fades in and out over 100ms without growing from the button.
Layout
It takes its container's width as a well padded 4px, its groups and rows 4px apart. Each row is a card at least 48px tall, the whole card its hit area: its title truncates with the full text in its title, its line wraps under it, and its value keeps its width in tabular figures; a group's title truncates the same way beside its 28px … button, and the add row is 48px tall.
Related
See it in the roastery demo's payouts, roast plan and settings.