Skip to content
buttery

v1.0.0

Source on GitHub

Version 1.0.0

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.

Tuesday
  • Guji, Ethiopia24 bags120 kg
  • House espresso40 bags200 kg
Thursday
  • 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.

Variants and states

Groups in one well

Rows that lead somewhere are links and lift on hover; the first group has no title.

People, with long names

A title too long for its row ends in an ellipsis; a long line wraps under it.

Wholesale buyers who reorder every fortnight without a reminder
  • 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

PropTypeDefaultDescription
label

required

stringWhat it adds, such as "Add a roast", shown beside a plus.

It also takes Omit<ComponentPropsWithRef<"button">, "children">.

GroupedList.Group

PropTypeDefaultDescription
titlestringThe group's title over its rows, which names their list. Leave it out for rows that need none.
actionsReactNodeActions on the whole group in a "…" menu at the end of its title's row, as Menu.Items.
actionsLabelstringNames the "…" button. Defaults to "Actions for" and the title.

It also takes Omit<ComponentPropsWithRef<"div">, "title">.

GroupedList.Item

PropTypeDefaultDescription
title

required

stringWhat the row is, such as a roast's name.
descriptionReactNodeA line under the title in text-secondary.
mediaReactNodeSomething before the text, such as an InitialsTile or an Avatar.
valueReactNodeA value at the row's end, such as a count or an amount, in tabular figures.
hrefstringMakes 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.

KeysWhat they do
EnterFollows a row that's a link
Enter or SpacePresses a row that's a button or the add row, or opens a group's … menu
EscapeCloses 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.

See it in the roastery demo's payouts, roast plan and settings.