DataTable
DataTable provides advanced functionality over Table, including sorting, pagination, column pinning, row selection, filtering, and row expansion.
function DataTableDemo() { interface Person { firstName: string; lastName: string; gender: string; age: number; address: string; city: string; isSubscribed: boolean; birthday: string; } const data = [...Array.from({ length: 100 })].map(() => ({ firstName: faker.name.firstName(), lastName: faker.name.lastName(), gender: faker.name.sex(), age: faker.datatype.number(80), address: faker.address.streetAddress(), city: faker.address.city(), isSubscribed: faker.datatype.boolean(), birthday: faker.date.past().toLocaleDateString('en-US'), })); const columns: DataTableColumnDef<Person>[] = [ { header: 'First Name', accessorKey: 'firstName', }, { header: 'Last Name', accessorKey: 'lastName', }, { header: 'Gender', accessorKey: 'gender', }, { header: 'Age', accessorKey: 'age', }, { header: 'Address', accessorKey: 'address', }, { header: 'City', accessorKey: 'city', }, { header: 'Subscribed', accessorKey: 'isSubscribed', }, { header: 'Birthday', accessorKey: 'birthday', }, ]; return <DataTable columns={columns} data={data} />; }
Usage
note
DataTable leverages Typescript to provide type safety. The column definition for the table should
follow the @tanstack/react-table
ColumnDef
type, exported as DataTableColumnDef
from Manifest.
Custom Cell Rendering
To render arbitrary non-string values, use the createDataTableColumnHelper
function, which is an
alias to
createColumnHelper function
from @tanstack/react-table
.
function CustomCellRendering() { interface Shipment { shipmentId: string; status: string; carrier: string; rate: string; origin: string; destination: string; pickupDate: string; } const columnHelper = createDataTableColumnHelper<Shipment>(); const data = [...Array.from({ length: 100 })].map(() => ({ shipmentId: faker.random.numeric(6), status: faker.helpers.arrayElement(['Pending', 'Booked']), carrier: `${faker.name.firstName()}'s Trucking`, rate: faker.commerce.price(), origin: faker.address.city(), destination: faker.address.state(), pickupDate: faker.date.future().toLocaleDateString('en-US'), })); const columns = [ columnHelper.accessor('shipmentId', { header: 'Shipment ID', cell: (id) => <Link href="#">{id.getValue()}</Link>, }), columnHelper.accessor('status', { header: 'Status', cell: (status) => status.getValue() === 'Pending' ? ( <Pill colorScheme="red" icon={<Clock />} label={status.getValue()} /> ) : ( <Pill colorScheme="indigo" icon={<ClipboardWithCheck />} label={status.getValue()} /> ), }), { header: 'Carrier', accessorKey: 'carrier', }, columnHelper.accessor('rate', { id: 'rate', header: 'Rate', cell: (rate) => <span>${rate.getValue()}</span>, }), { header: 'Origin', accessorKey: 'origin', }, { header: 'Destination', accessorKey: 'destination', }, { header: 'Pickup Date', accessorKey: 'pickupDate', }, ]; return <DataTable columns={columns} data={data} />; }
Sticky Header
Enable sticky header with enableStickyHeader
prop.
function DataTableDemo() { const data = [...Array.from({ length: 100 })].map(() => ({ name: faker.name.fullName(), age: faker.datatype.number(100), email: faker.internet.email(), address: faker.address.streetAddress(), isSubscribed: faker.datatype.boolean(), city: faker.address.city(), state: faker.address.state(), birthday: faker.date.past().toLocaleDateString('en-US'), })); const columns = [ { header: 'Name', accessorKey: 'name', }, { header: 'Age', accessorKey: 'age', }, { header: 'Email Address', accessorKey: 'email', }, { header: 'Address', accessorKey: 'address', }, { header: 'Subscribed', accessorKey: 'isSubscribed', }, { header: 'City', accessorKey: 'city', }, { header: 'State', accessorKey: 'state', }, { header: 'Birthday', accessorKey: 'birthday', }, ]; return ( <DataTable enableStickyHeader columns={columns} css={{ '.manifest-data-table__container': { maxHeight: 250 } }} data={data} initialState={{ pagination: { pageSize: 25, pageIndex: 0 } }} /> ); }
Column pinning
Pin columns to left
and right
using initiateState
prop
function DataTableDemo() { const data = [...Array.from({ length: 100 })].map(() => ({ name: faker.name.fullName(), age: faker.datatype.number(100), email: faker.internet.email(), address: faker.address.streetAddress(), isSubscribed: faker.datatype.boolean(), city: faker.address.city(), state: faker.address.state(), birthday: faker.date.past().toLocaleDateString('en-US'), })); const columns = [ { header: 'Name', accessorKey: 'name', }, { header: 'Age', accessorKey: 'age', }, { header: 'Email Address', accessorKey: 'email', }, { header: 'Address', accessorKey: 'address', }, { header: 'Subscribed', accessorKey: 'isSubscribed', }, { header: 'City', accessorKey: 'city', }, { header: 'State', accessorKey: 'state', }, { header: 'Birthday', accessorKey: 'birthday', }, ]; return ( <DataTable columns={columns} data={data} initialState={{ columnPinning: { left: ['email'], right: ['state'] } }} /> ); }
Loading
Indicate loading state with isLoading
prop
Row Expansion
Enable row expansion with enableRowExpansion
prop
function DataTableDemo() { interface Person { firstName: string; lastName: string; age: number; address: string; phoneNumber: string; } const columns: DataTableColumnDef<Person>[] = [ { header: 'First Name', accessorKey: 'firstName', }, { header: 'Last Name', accessorKey: 'lastName', }, { header: 'Age', accessorKey: 'age', }, { header: 'Address', accessorKey: 'address', }, { header: 'Phone Number', accessorKey: 'phoneNumber', }, ]; const data = [...Array.from({ length: 5 })].map(() => ({ firstName: faker.name.firstName(), lastName: faker.name.lastName(), age: faker.datatype.number(80), address: faker.address.streetAddress(), phoneNumber: faker.phone.number(), subRows: [...Array.from({ length: faker.datatype.number(4) })].map(() => ({ firstName: faker.name.firstName(), lastName: faker.name.lastName(), age: faker.datatype.number(80), address: faker.address.streetAddress(), phoneNumber: faker.phone.number(), })), })); return <DataTable enableExpanding columns={columns} data={data} />; }
Props
as?The root element to be rendered