List

Render rows of data in a bordered CSS grid with configurable columns and optional column groups.

List is a client component ("use client") that renders a data grid built from Box and Text: an optional group header row, a column header row, and one row per data item. Use it for compact tables of records. Each cell renders a component you supply per column.

NameCityRole
Ada Lovelace
London
Admin
Grace Hopper
New York
Editor
Alan Turing
Manchester
Viewer

Import#

typescript
import { List } from "@reactberry/system/blocks";

Usage#

typescript
import { List } from "@reactberry/system/blocks";
import { Text } from "@reactberry/system/elements";

const users = [
  { id: "u1", name: "Ada Lovelace", city: "London", role: "Admin" },
  { id: "u2", name: "Grace Hopper", city: "New York", role: "Editor" },
];

const grid = [
  { label: "ID", width: "4rem", key: "id", align: "center", component: (p: any) => <Text>{p.id}</Text> },
  { label: "Name", width: "1fr", key: "name", component: (p: any) => <Text fontWeight="600">{p.name}</Text> },
  { label: "City", width: "10rem", key: "city", group: "Details", component: (p: any) => <Text>{p.value}</Text> },
  { label: "Role", width: "8rem", key: "role", group: "Details", component: (p: any) => <Text>{p.value}</Text> },
];

export default function UserList() {
  return <List data={users} grid={grid} rowHeight="2.5rem" onRowClick={(item) => console.log(item.name)} />;
}

Examples#

Column groups#

Give columns the same group value to show them under a shared header row.

Shipping
CustomerCityCountryTotal
Ada Lovelace
London
UK
$120.00
Grace Hopper
New York
US
$84.50

Selection#

Pass selected and onSelect to toggle rows. Row data is filtered to the keys in grid, so the grid needs an id column for selection to work.

FileSize
Roadmap.pdf
2.4 MB
Invoice-0321.pdf
180 KB
Brand-guide.fig
12 MB
0 of 3 selected

API#

List#

PropTypeDefaultDescription
data
DataItem[]
[]

Row objects.

grid
(GridColumn | GroupedColumn)[]
[…

Column definitions. Columns with the same group share a header.

gap
string
xxxsmall

Gap and bottom padding of the group header row.

selected
string[]
[]

Ids of selected rows.

onSelect
((id: string) => void)
—

Called with the row's id on click.

onRowClick
((item: DataItem) => void)
—

Called when a row is clicked. Receives the row item, filtered to the keys used in grid.

rowHeight
string
2rem

Fixed height and max height of each row. Default is "2rem".

All other props are spread onto the group header row only, so they have no effect when no columns are grouped. The default grid is a three-column id / name / empty setup.

GridColumn#

PropTypeDefaultDescription
label*
string | ReactNode
—

Header content.

width*
string
—

Grid track size, such as "8rem" or "1fr".

key*
string | string[]
—

Data key(s) to keep and pass to component as value. With an array, value is an object containing each key.

component*
ComponentType<any>
—

Cell renderer. Receives the row's kept fields as props plus value.

align
any
"start"

Cell and header alignment.

minWidth
string
—

Applied to each cell.

maxWidth
string
—

Applied to each cell.

autoWidth
boolean
—

Measures content to size the column.

group
string
—

Columns sharing a value are grouped under one header.

columnProps
any
—

Spread onto the column header.

cellProps
any
—

Spread onto each cell.

groupProps
any
—

Spread onto the group header when this is the first column of its group.

Accessibility#

  • Rows are clickable div elements with cursor="pointer" when a handler is set. They are not focusable and have no keyboard handling or ARIA grid roles.
  • Selected rows are marked only by a check mark emoji at the start of every cell; there is no other selected styling or ARIA state.

Notes#

  • Row data is filtered to the keys listed in grid before rendering. Selection, onSelect, onRowClick and cell components only see those fields; without an id column, id is undefined.
  • autoWidth columns are measured after mount and on horizontal window resize (debounced 250ms), using up to 20 rows plus the header and adding 24px. Measurement queries cells by a global class name, so multiple List instances with autoWidth on one page can affect each other.
  • Group headers read groupProps from the first column in the group. The groupProps field on a GroupedColumn object is not used.
  • The module also exports createColumnGroup(groupHeader, columns, groupProps?), which returns a GroupedColumn, and the types DataItem, ListProps, GridColumn and GroupedColumn. These are not re-exported from @reactberry/system/blocks, and the package does not expose deep import paths, so they are not currently importable by consumers. Use the group field on columns instead.