Buttons
Data Display
Layout
Navigation
Table
Show rows of data in columns, with sticky headers and columns, selectable rows and borders.
React
| Product | Category | Price |
|---|---|---|
| Laptop | Electronics | $999.99 |
| Coffee maker | Home appliances | $49.99 |
| Desk chair | Furniture | $150.00 |
| Total | $1,199.98 | |
import { Table } from "@isbatak/react-ui/table"
export function TableDemo() {
return (
<Table.Root>
<Table.Header>
<Table.Row>
<Table.ColumnHeader>Product</Table.ColumnHeader>
<Table.ColumnHeader>Category</Table.ColumnHeader>
<Table.ColumnHeader textAlign="end">Price</Table.ColumnHeader>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>Laptop</Table.Cell>
<Table.Cell>Electronics</Table.Cell>
<Table.Cell textAlign="end">$999.99</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>Coffee maker</Table.Cell>
<Table.Cell>Home appliances</Table.Cell>
<Table.Cell textAlign="end">$49.99</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>Desk chair</Table.Cell>
<Table.Cell>Furniture</Table.Cell>
<Table.Cell textAlign="end">$150.00</Table.Cell>
</Table.Row>
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.Cell colSpan={2}>Total</Table.Cell>
<Table.Cell textAlign="end">$1,199.98</Table.Cell>
</Table.Row>
</Table.Footer>
<Table.Caption>Prices include tax.</Table.Caption>
</Table.Root>
)
}A native <table> with the table recipe on each part. The tables in these docs are this component.
Usage
import { Table } from "@isbatak/react-ui/table"
export function TableDemo() {
return (
<Table.Root>
<Table.Header>
<Table.Row>
<Table.ColumnHeader>Product</Table.ColumnHeader>
<Table.ColumnHeader>Category</Table.ColumnHeader>
<Table.ColumnHeader textAlign="end">Price</Table.ColumnHeader>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>Laptop</Table.Cell>
<Table.Cell>Electronics</Table.Cell>
<Table.Cell textAlign="end">$999.99</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>Coffee maker</Table.Cell>
<Table.Cell>Home appliances</Table.Cell>
<Table.Cell textAlign="end">$49.99</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>Desk chair</Table.Cell>
<Table.Cell>Furniture</Table.Cell>
<Table.Cell textAlign="end">$150.00</Table.Cell>
</Table.Row>
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.Cell colSpan={2}>Total</Table.Cell>
<Table.Cell textAlign="end">$1,199.98</Table.Cell>
</Table.Row>
</Table.Footer>
<Table.Caption>Prices include tax.</Table.Caption>
</Table.Root>
)
}<Table.Root>
<Table.Header>
<Table.Row>
<Table.ColumnHeader />
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell />
</Table.Row>
</Table.Body>
<Table.Footer />
<Table.Caption />
</Table.Root>Examples
Sizes
Set size to sm, md or lg to change the text size and row height. The default is md.
| Size | Text |
|---|---|
| sm | Extra small text with tight rows |
| Size | Text |
|---|---|
| md | Small text, the default |
| Size | Text |
|---|---|
| lg | Medium text with roomy rows |
import { Table } from "@isbatak/react-ui/table"
import { Stack } from "styled-system/jsx"
export function TableSizesDemo() {
return (
<Stack gap="8" w="full">
<Table.Root size="sm">
<Table.Header>
<Table.Row>
<Table.ColumnHeader>Size</Table.ColumnHeader>
<Table.ColumnHeader>Text</Table.ColumnHeader>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>sm</Table.Cell>
<Table.Cell>Extra small text with tight rows</Table.Cell>
</Table.Row>
</Table.Body>
</Table.Root>
<Table.Root size="md">
<Table.Header>
<Table.Row>
<Table.ColumnHeader>Size</Table.ColumnHeader>
<Table.ColumnHeader>Text</Table.ColumnHeader>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>md</Table.Cell>
<Table.Cell>Small text, the default</Table.Cell>
</Table.Row>
</Table.Body>
</Table.Root>
<Table.Root size="lg">
<Table.Header>
<Table.Row>
<Table.ColumnHeader>Size</Table.ColumnHeader>
<Table.ColumnHeader>Text</Table.ColumnHeader>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>lg</Table.Cell>
<Table.Cell>Medium text with roomy rows</Table.Cell>
</Table.Row>
</Table.Body>
</Table.Root>
</Stack>
)
}Borders
Rows have a bottom border by default. Set showColumnBorder to add borders between columns, and showRowBorder={false}
to remove the row borders.
| Region | Q1 | Q2 |
|---|---|---|
| Europe | 1,204 | 1,388 |
| Americas | 980 | 1,102 |
| Region | Q1 | Q2 |
|---|---|---|
| Europe | 1,204 | 1,388 |
| Americas | 980 | 1,102 |
import { Table } from "@isbatak/react-ui/table"
import { Stack } from "styled-system/jsx"
export function TableBordersDemo() {
return (
<Stack gap="8" w="full">
<Table.Root showColumnBorder>
<Table.Header>
<Table.Row>
<Table.ColumnHeader>Region</Table.ColumnHeader>
<Table.ColumnHeader>Q1</Table.ColumnHeader>
<Table.ColumnHeader>Q2</Table.ColumnHeader>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>Europe</Table.Cell>
<Table.Cell>1,204</Table.Cell>
<Table.Cell>1,388</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>Americas</Table.Cell>
<Table.Cell>980</Table.Cell>
<Table.Cell>1,102</Table.Cell>
</Table.Row>
</Table.Body>
</Table.Root>
<Table.Root showRowBorder={false}>
<Table.Header>
<Table.Row>
<Table.ColumnHeader>Region</Table.ColumnHeader>
<Table.ColumnHeader>Q1</Table.ColumnHeader>
<Table.ColumnHeader>Q2</Table.ColumnHeader>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>Europe</Table.Cell>
<Table.Cell>1,204</Table.Cell>
<Table.Cell>1,388</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>Americas</Table.Cell>
<Table.Cell>980</Table.Cell>
<Table.Cell>1,102</Table.Cell>
</Table.Row>
</Table.Body>
</Table.Root>
</Stack>
)
}Interactive
Set interactive to highlight rows on hover and show a pointer. Pass selected to Table.Row to mark a row as
selected; it sets aria-selected and uses colorPalette.subtle.
| Invoice | Customer | Status |
|---|---|---|
| INV-001 | Acme | Paid |
| INV-002 | Globex | Pending |
| INV-003 | Initech | Overdue |
import { Table } from "@isbatak/react-ui/table"
export function TableInteractiveDemo() {
return (
<Table.Root interactive>
<Table.Header>
<Table.Row>
<Table.ColumnHeader>Invoice</Table.ColumnHeader>
<Table.ColumnHeader>Customer</Table.ColumnHeader>
<Table.ColumnHeader>Status</Table.ColumnHeader>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>INV-001</Table.Cell>
<Table.Cell>Acme</Table.Cell>
<Table.Cell>Paid</Table.Cell>
</Table.Row>
<Table.Row selected>
<Table.Cell>INV-002</Table.Cell>
<Table.Cell>Globex</Table.Cell>
<Table.Cell>Pending</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>INV-003</Table.Cell>
<Table.Cell>Initech</Table.Cell>
<Table.Cell>Overdue</Table.Cell>
</Table.Row>
</Table.Body>
</Table.Root>
)
}Sticky header and columns
Set stickyHeader to keep the header in view while the table scrolls, and highlightedHeader to give it a background.
Pass sticky="start" or sticky="end" to Table.ColumnHeader and Table.Cell to pin a column; it fades into the rows
it covers and follows the text direction. Put the table in a scroll container, and set --table-sticky-offset when the
header should stop below something else, such as a site header.
| Name | Team | Location | Role | Status |
|---|---|---|---|---|
| Ada Lovelace | Engineering | London | Lead | Active |
| Grace Hopper | Platform | Arlington | Principal | Active |
| Alan Turing | Research | Manchester | Fellow | Away |
| Katherine Johnson | Analytics | Hampton | Senior | Active |
| Linus Torvalds | Kernel | Portland | Maintainer | Active |
| Margaret Hamilton | Flight software | Boston | Director | Away |
| Dennis Ritchie | Languages | Murray Hill | Staff | Active |
| Barbara Liskov | Systems | Cambridge | Professor | Active |
import { Table } from "@isbatak/react-ui/table"
import { styled } from "styled-system/jsx"
export function TableStickyDemo() {
return (
<styled.div overflow="auto" maxH="64" w="full" borderWidth="1px" borderRadius="l2">
<Table.Root stickyHeader highlightedHeader minW="2xl" whiteSpace="nowrap">
<Table.Header>
<Table.Row>
<Table.ColumnHeader sticky="start">Name</Table.ColumnHeader>
<Table.ColumnHeader>Team</Table.ColumnHeader>
<Table.ColumnHeader>Location</Table.ColumnHeader>
<Table.ColumnHeader>Role</Table.ColumnHeader>
<Table.ColumnHeader sticky="end">Status</Table.ColumnHeader>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell sticky="start">Ada Lovelace</Table.Cell>
<Table.Cell>Engineering</Table.Cell>
<Table.Cell>London</Table.Cell>
<Table.Cell>Lead</Table.Cell>
<Table.Cell sticky="end">Active</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell sticky="start">Grace Hopper</Table.Cell>
<Table.Cell>Platform</Table.Cell>
<Table.Cell>Arlington</Table.Cell>
<Table.Cell>Principal</Table.Cell>
<Table.Cell sticky="end">Active</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell sticky="start">Alan Turing</Table.Cell>
<Table.Cell>Research</Table.Cell>
<Table.Cell>Manchester</Table.Cell>
<Table.Cell>Fellow</Table.Cell>
<Table.Cell sticky="end">Away</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell sticky="start">Katherine Johnson</Table.Cell>
<Table.Cell>Analytics</Table.Cell>
<Table.Cell>Hampton</Table.Cell>
<Table.Cell>Senior</Table.Cell>
<Table.Cell sticky="end">Active</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell sticky="start">Linus Torvalds</Table.Cell>
<Table.Cell>Kernel</Table.Cell>
<Table.Cell>Portland</Table.Cell>
<Table.Cell>Maintainer</Table.Cell>
<Table.Cell sticky="end">Active</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell sticky="start">Margaret Hamilton</Table.Cell>
<Table.Cell>Flight software</Table.Cell>
<Table.Cell>Boston</Table.Cell>
<Table.Cell>Director</Table.Cell>
<Table.Cell sticky="end">Away</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell sticky="start">Dennis Ritchie</Table.Cell>
<Table.Cell>Languages</Table.Cell>
<Table.Cell>Murray Hill</Table.Cell>
<Table.Cell>Staff</Table.Cell>
<Table.Cell sticky="end">Active</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell sticky="start">Barbara Liskov</Table.Cell>
<Table.Cell>Systems</Table.Cell>
<Table.Cell>Cambridge</Table.Cell>
<Table.Cell>Professor</Table.Cell>
<Table.Cell sticky="end">Active</Table.Cell>
</Table.Row>
</Table.Body>
</Table.Root>
</styled.div>
)
}Recipe
| Variant | Values | Default |
|---|---|---|
size | sm, md, lg | md |
showRowBorder | true, false | true |
showColumnBorder | true, false | |
interactive | true | |
stickyHeader | true | |
highlightedHeader | true |
| Variable | Default | Description |
|---|---|---|
--table-border-color | colors.border | The row and column border color |
--table-row-hover-bg | colors.bg.muted | The background of a hovered interactive row |
--table-row-selected-bg | colorPalette.subtle | The background of a selected row |
--table-sticky-offset | 0 | How far from the top the sticky header stops |