Data Table A captioned table with sortable columns, loading rows and an empty message.
This week’s orders Order Customer Coffee Bags Status A-1042 Linh Tran Ethiopia Guji 2 Roasting A-1041 Sam Okafor Colombia Huila 1 Shipped A-1039 Ana Ruiz Kenya Nyeri 3 Delivered A-1036 Minh Pham Ethiopia Guji 1 Delivered
'use client' ;
import { Badge, DataTable } from '@brand-studio/ui' ;
interface Order { id : string ; customer : string ; coffee : string ; bags : number ; status : 'Roasting' | 'Shipped' | 'Delivered' }
const orders : Order [] = [
{ id: 'A-1042' , customer: 'Linh Tran' , coffee: 'Ethiopia Guji' , bags: 2 , status: 'Roasting' },
{ id: 'A-1041' , customer: 'Sam Okafor' , coffee: 'Colombia Huila' , bags: 1 , status: 'Shipped' },
{ id: 'A-1039' , customer: 'Ana Ruiz' , coffee: 'Kenya Nyeri' , bags: 3 , status: 'Delivered' },
{ id: 'A-1036' , customer: 'Minh Pham' , coffee: 'Ethiopia Guji' , bags: 1 , status: 'Delivered' },
];
export default function DataTableDemo () {
return (
< div style = {{ width: '100%' , maxWidth: 620 }}>
< DataTable
caption = "This week’s orders"
rows = {orders}
rowKey = {( order ) => order.id}
columns = {[
{ key: 'id' , header: 'Order' },
{ key: 'customer' , header: 'Customer' , sortValue : ( order ) => order.customer },
{ key: 'coffee' , header: 'Coffee' },
{ key: 'bags' , header: 'Bags' , align: 'end' , sortValue : ( order ) => order.bags },
{ key: 'status' , header: 'Status' , cell : ( order ) => < Badge tone = {order.status === 'Roasting' ? 'accent' : 'neutral' }>{order.status}</ Badge > },
]}
/>
</ div >
);
} View code
Installation
Command Manual
pnpm npm yarn bun
pnpm add @brand-studio/ui npm install @brand-studio/ui yarn add @brand-studio/ui Install the peer dependencies npm install react react-dom Import the stylesheet once import '@brand-studio/ui/styles.css' ; Wrap your app in a brand theme import { BrandTheme, DataTable } from '@brand-studio/ui' ;
import brand from './brand.json' ;
< BrandTheme palette = {brand.tokens} mode = "system" >
{ /* your app */ }
</ BrandTheme >
Usage
import { DataTable } from '@brand-studio/ui' ;
< DataTable
caption = "This week’s orders"
rows = {orders}
rowKey = {( order ) => order.id}
columns = {[
{ key: 'customer' , header: 'Customer' , sortValue : ( order ) => order.customer },
{ key: 'bags' , header: 'Bags' , align: 'end' , sortValue : ( order ) => order.bags },
]}
/>
Examples
Loading and empty
Pass loading while rows load and empty for what to show when there are none.
Loading Order Customer Status
Refunds Order Customer Status No refunds this month Refunds you issue show up here.
Issue a refund
'use client' ;
import { Button, DataTable, EmptyState } from '@brand-studio/ui' ;
const columns = [{ key: 'id' , header: 'Order' }, { key: 'customer' , header: 'Customer' }, { key: 'status' , header: 'Status' }];
export default function DataTableStates () {
return (
< div style = {{ display: 'grid' , gap: 20 , width: '100%' , maxWidth: 560 }}>
< DataTable caption = "Loading" rows = {[]} rowKey = {() => '' } columns = {columns} loading />
< DataTable caption = "Refunds" rows = {[]} rowKey = {() => '' } columns = {columns} empty = {< EmptyState title = "No refunds this month" description = "Refunds you issue show up here." action = {< Button tone = "secondary" >Issue a refund</ Button >} />} />
</ div >
);
} View code
Accessibility
A real <table> with a <caption> and column headers. hideCaption keeps the caption for screen readers only.
Sortable headers are buttons, and the sorted column carries aria-sort.
On narrow screens the table scrolls sideways inside its own frame. The frame is focusable and named by the caption, so keyboard users can scroll it too.
loading sets aria-busy on the table.
API Reference
Prop Type Default captionstring– columnsTableColumn<object>[]– rowsobject[]– rowKey(row: object) => string– loading?boolean– empty?React.ReactNode– hideCaption?boolean– className?string–