Buttons
Data Display
Layout
Navigation
Grid table
A table laid out with CSS grid, for column sizes a native table can't express and rows built from any element.
React
import { GridTable } from "@isbatak/react-ui/grid-table"
export function GridTableDemo() {
return (
<GridTable.Root columns="minmax(8rem, 2fr) minmax(6rem, 1fr) auto">
<GridTable.Header>
<GridTable.HeaderRow>
<GridTable.ColumnHeader>File</GridTable.ColumnHeader>
<GridTable.ColumnHeader>Owner</GridTable.ColumnHeader>
<GridTable.ColumnHeader justifyContent="flex-end">Size</GridTable.ColumnHeader>
</GridTable.HeaderRow>
</GridTable.Header>
<GridTable.Body>
<GridTable.Row>
<GridTable.Cell>brand-guidelines.pdf</GridTable.Cell>
<GridTable.Cell>Design</GridTable.Cell>
<GridTable.Cell justifyContent="flex-end">4.2 MB</GridTable.Cell>
</GridTable.Row>
<GridTable.Row>
<GridTable.Cell>roadmap-2027.key</GridTable.Cell>
<GridTable.Cell>Product</GridTable.Cell>
<GridTable.Cell justifyContent="flex-end">18.9 MB</GridTable.Cell>
</GridTable.Row>
<GridTable.Row>
<GridTable.Cell>invoice-0042.csv</GridTable.Cell>
<GridTable.Cell>Finance</GridTable.Cell>
<GridTable.Cell justifyContent="flex-end">12 KB</GridTable.Cell>
</GridTable.Row>
</GridTable.Body>
</GridTable.Root>
)
}The same look as Table, built from divs with table roles. The columns come from one grid
template, and rows use subgrid, so every row lines up with the header however the columns are sized.
Usage
import { GridTable } from "@isbatak/react-ui/grid-table"
export function GridTableDemo() {
return (
<GridTable.Root columns="minmax(8rem, 2fr) minmax(6rem, 1fr) auto">
<GridTable.Header>
<GridTable.HeaderRow>
<GridTable.ColumnHeader>File</GridTable.ColumnHeader>
<GridTable.ColumnHeader>Owner</GridTable.ColumnHeader>
<GridTable.ColumnHeader justifyContent="flex-end">Size</GridTable.ColumnHeader>
</GridTable.HeaderRow>
</GridTable.Header>
<GridTable.Body>
<GridTable.Row>
<GridTable.Cell>brand-guidelines.pdf</GridTable.Cell>
<GridTable.Cell>Design</GridTable.Cell>
<GridTable.Cell justifyContent="flex-end">4.2 MB</GridTable.Cell>
</GridTable.Row>
<GridTable.Row>
<GridTable.Cell>roadmap-2027.key</GridTable.Cell>
<GridTable.Cell>Product</GridTable.Cell>
<GridTable.Cell justifyContent="flex-end">18.9 MB</GridTable.Cell>
</GridTable.Row>
<GridTable.Row>
<GridTable.Cell>invoice-0042.csv</GridTable.Cell>
<GridTable.Cell>Finance</GridTable.Cell>
<GridTable.Cell justifyContent="flex-end">12 KB</GridTable.Cell>
</GridTable.Row>
</GridTable.Body>
</GridTable.Root>
)
}<GridTable.Root columns="2fr 1fr auto">
<GridTable.Header>
<GridTable.HeaderRow>
<GridTable.ColumnHeader />
</GridTable.HeaderRow>
</GridTable.Header>
<GridTable.Body>
<GridTable.Row>
<GridTable.Cell />
</GridTable.Row>
</GridTable.Body>
</GridTable.Root>columns is a grid-template-columns value, set on the root as --grid-template-columns. The default fits as many
10rem columns as there is room for.
Examples
Sticky header and columns
The root scrolls, so give it a maxH and stickyHeader keeps the header in view. Pass sticky="start" or
sticky="end" to GridTable.ColumnHeader and GridTable.Cell to pin a column.
import { GridTable } from "@isbatak/react-ui/grid-table"
export function GridTableStickyDemo() {
return (
<GridTable.Root
columns="repeat(5, minmax(9rem, 1fr))"
stickyHeader
highlightedHeader
maxH="64"
borderWidth="1px"
borderRadius="l2"
whiteSpace="nowrap"
>
<GridTable.Header>
<GridTable.HeaderRow>
<GridTable.ColumnHeader sticky="start">Service</GridTable.ColumnHeader>
<GridTable.ColumnHeader>Region</GridTable.ColumnHeader>
<GridTable.ColumnHeader>Instances</GridTable.ColumnHeader>
<GridTable.ColumnHeader>Uptime</GridTable.ColumnHeader>
<GridTable.ColumnHeader sticky="end">Status</GridTable.ColumnHeader>
</GridTable.HeaderRow>
</GridTable.Header>
<GridTable.Body>
<GridTable.Row>
<GridTable.Cell sticky="start">api-gateway</GridTable.Cell>
<GridTable.Cell>eu-west-1</GridTable.Cell>
<GridTable.Cell>3</GridTable.Cell>
<GridTable.Cell>99.98%</GridTable.Cell>
<GridTable.Cell sticky="end">Healthy</GridTable.Cell>
</GridTable.Row>
<GridTable.Row>
<GridTable.Cell sticky="start">auth-service</GridTable.Cell>
<GridTable.Cell>us-east-1</GridTable.Cell>
<GridTable.Cell>5</GridTable.Cell>
<GridTable.Cell>99.95%</GridTable.Cell>
<GridTable.Cell sticky="end">Healthy</GridTable.Cell>
</GridTable.Row>
<GridTable.Row>
<GridTable.Cell sticky="start">billing-worker</GridTable.Cell>
<GridTable.Cell>eu-west-1</GridTable.Cell>
<GridTable.Cell>2</GridTable.Cell>
<GridTable.Cell>99.40%</GridTable.Cell>
<GridTable.Cell sticky="end">Degraded</GridTable.Cell>
</GridTable.Row>
<GridTable.Row>
<GridTable.Cell sticky="start">search-index</GridTable.Cell>
<GridTable.Cell>ap-south-1</GridTable.Cell>
<GridTable.Cell>4</GridTable.Cell>
<GridTable.Cell>99.99%</GridTable.Cell>
<GridTable.Cell sticky="end">Healthy</GridTable.Cell>
</GridTable.Row>
<GridTable.Row>
<GridTable.Cell sticky="start">media-encoder</GridTable.Cell>
<GridTable.Cell>us-west-2</GridTable.Cell>
<GridTable.Cell>6</GridTable.Cell>
<GridTable.Cell>99.90%</GridTable.Cell>
<GridTable.Cell sticky="end">Healthy</GridTable.Cell>
</GridTable.Row>
<GridTable.Row>
<GridTable.Cell sticky="start">notifications</GridTable.Cell>
<GridTable.Cell>eu-central-1</GridTable.Cell>
<GridTable.Cell>3</GridTable.Cell>
<GridTable.Cell>98.70%</GridTable.Cell>
<GridTable.Cell sticky="end">Degraded</GridTable.Cell>
</GridTable.Row>
<GridTable.Row>
<GridTable.Cell sticky="start">reports</GridTable.Cell>
<GridTable.Cell>us-east-1</GridTable.Cell>
<GridTable.Cell>1</GridTable.Cell>
<GridTable.Cell>99.99%</GridTable.Cell>
<GridTable.Cell sticky="end">Healthy</GridTable.Cell>
</GridTable.Row>
<GridTable.Row>
<GridTable.Cell sticky="start">webhooks</GridTable.Cell>
<GridTable.Cell>eu-west-1</GridTable.Cell>
<GridTable.Cell>2</GridTable.Cell>
<GridTable.Cell>99.97%</GridTable.Cell>
<GridTable.Cell sticky="end">Healthy</GridTable.Cell>
</GridTable.Row>
</GridTable.Body>
</GridTable.Root>
)
}Interactive and borders
interactive highlights rows on hover, selected on GridTable.Row marks a row, and showColumnBorder adds borders
between columns. size and showRowBorder work as they do on Table.
import { GridTable } from "@isbatak/react-ui/grid-table"
export function GridTableInteractiveDemo() {
return (
<GridTable.Root columns="1fr 1fr 1fr" interactive showColumnBorder>
<GridTable.Header>
<GridTable.HeaderRow>
<GridTable.ColumnHeader>Branch</GridTable.ColumnHeader>
<GridTable.ColumnHeader>Author</GridTable.ColumnHeader>
<GridTable.ColumnHeader>Checks</GridTable.ColumnHeader>
</GridTable.HeaderRow>
</GridTable.Header>
<GridTable.Body>
<GridTable.Row>
<GridTable.Cell>main</GridTable.Cell>
<GridTable.Cell>ivica</GridTable.Cell>
<GridTable.Cell>Passing</GridTable.Cell>
</GridTable.Row>
<GridTable.Row selected>
<GridTable.Cell>feat/toc</GridTable.Cell>
<GridTable.Cell>ivica</GridTable.Cell>
<GridTable.Cell>Running</GridTable.Cell>
</GridTable.Row>
<GridTable.Row>
<GridTable.Cell>fix/drawer</GridTable.Cell>
<GridTable.Cell>ana</GridTable.Cell>
<GridTable.Cell>Failing</GridTable.Cell>
</GridTable.Row>
</GridTable.Body>
</GridTable.Root>
)
}Recipe
| Variant | Values | Default |
|---|---|---|
size | sm, md, lg | md |
showRowBorder | true, false | true |
showColumnBorder | true, false | |
interactive | true | |
stickyHeader | true | |
highlightedHeader | true |
The variables are the same as Table's, plus --grid-template-columns.