DataGrid

Data grids are used to organize lists of high density data.

A advanced data grid component that supports sorting, selections, filters and pagination.

Import#

import { DataGrid, DataGridPagination } from '@saas-ui/pro'

Usage#

DataGrid uses @tanstack/react-table v8 internally, and supports all useTable props, you can find the docs here.

Basic DataGrid#

function ListPage() {
const columns = React.useMemo(() => {
return [
{
accessorKey: 'name',
header: 'Name',
size: 200,
},
{
accessorKey: 'email',
header: 'Email',
},
{
accessorKey: 'company',
header: 'Company',
},
{
accessorKey: 'country',
header: 'Country',
},
{
accessorKey: 'employees',
header: 'Employees',
isNumeric: true,
},
{
id: 'action',
disableSortBy: true,
disableGlobaFilter: true,
header: '',
cell: () => (
<>
<Button size="xs">Edit</Button>
</>
),
size: 100,
},
]
}, [])
return (
<Page title="Customers" height="400px">
<DataGrid
columns={columns}
data={dataTable.data}
isSortable
isSelectable
isHoverable
>
<DataGridPagination />
</DataGrid>
</Page>
)
}

With BulkActions#

function ListPage() {
const [selections, setSelections] = React.useState([])
const columns = React.useMemo(() => {
return [
{
accessorKey: 'name',
header: 'Name',
size: 200,
},
{
accessorKey: 'email',
header: 'Email',
},
{
accessorKey: 'company',
header: 'Company',
},
{
accessorKey: 'country',
header: 'Country',
},
{
accessorKey: 'employees',
header: 'Employees',
isNumeric: true,
},
{
id: 'action',
disableSortBy: true,
disableGlobaFilter: true,
header: '',
cell: () => (
<>
<Button size="xs">Edit</Button>
</>
),
size: 100,
},
]
}, [])
return (
<Page
title="Customers"
height="400px"
position="relative"
overflow="hidden"
>
<BulkActions
selections={selections}
actions={
<>
<Button colorScheme="white" variant="subtle">
Delete
</Button>
</>
}
></BulkActions>
<DataGrid
columns={columns}
data={dataTable.data}
isSortable
isSelectable
isHoverable
onSelectedRowsChange={setSelections}
>
<DataGridPagination />
</DataGrid>
</Page>
)
}

Clickable rows#

Cells with a href property will render the cell value in an a. Using the DataGrid onRowClick handler you can trigger a click event on the link whenever the row is clicked.

function ListPage() {
const [selections, setSelections] = React.useState([])
const columns = React.useMemo(() => {
return [
{
accessorKey: 'name',
header: 'Name',
size: 200,
meta: {
href: ({ id }) => `#customers/${id}`,
},
},
{
accessorKey: 'email',
header: 'Email',
},
{
accessorKey: 'company',
header: 'Company',
},
{
accessorKey: 'country',
header: 'Country',
},
{
accessorKey: 'employees',
header: 'Employees',
meta: {
isNumeric: true,
},
},
{
id: 'action',
disableSortBy: true,
disableGlobaFilter: true,
header: '',
cell: () => (
<>
<Button size="xs">Edit</Button>
</>
),
size: 200,
},
]
}, [])
return (
<Page
title="Customers"
height="400px"
position="relative"
overflow="hidden"
sx={{
'& tbody tr:hover': {
cursor: 'pointer',
},
}}
>
<BulkActions
selections={selections}
actions={
<>
<Button colorScheme="white" variant="subtle">
Delete
</Button>
</>
}
></BulkActions>
<DataGrid
columns={columns}
data={dataTable.data}
isSortable
isSelectable
isHoverable
onSelectedRowsChange={setSelections}
onRowClick={(row, e) => {
// Find the first A and trigger a click.
const link = e.currentTarget.querySelector('td a')
link && link.click()
}}
>
<DataGridPagination />
</DataGrid>
</Page>
)
}

Remote data#

By default all sorting, filtering and pagination is handled locally by react-table to work with remote data use this example as a reference.

function ListPage() {
const [selections, setSelections] = React.useState([])
const [sort, setSort] = React.useState<SortingRule<ExampleData>[]>([])
const [page, setPage] = React.useState(0)
const { data } = useQuery(['customers', sort, page], () => {
// fetch...
})
const columns = React.useMemo(() => {
return [
{
accessorKey: 'name',
header: 'Name',
size: 200,
meta: {
href: ({ id }) => `#customers/${id}`,
},
},
{
accessorKey: 'email',
header: 'Email',
},
{
accessorKey: 'company',
header: 'Company',
},
{
accessorKey: 'country',
header: 'Country',
},
{
accessorKey: 'employees',
header: 'Employees',
meta: {
isNumeric: true,
},
},
{
id: 'action',
disableSortBy: true,
disableGlobaFilter: true,
header: '',
cell: () => (
<>
<Button size="xs">Edit</Button>
</>
),
width: '100px',
},
]
}, [])
return (
<Page
title="Customers"
height="400px"
position="relative"
overflow="hidden"
sx={{
'& tbody tr:hover': {
cursor: 'pointer',
},
}}
>
<BulkActions
selections={selections}
actions={
<>
<Button colorScheme="white" variant="subtle">
Delete
</Button>
</>
}
/>
<DataGrid
columns={columns}
data={dataTable.data}
isSortable
isSelectable
isHoverable
onSelectedRowsChange={setSelections}
onRowClick={(row, e) => {
// Find the first A and trigger a click.
const link = e.currentTarget.querySelector('td a')
link && link.click()
}}
manualSortBy
onSortchange={setSort}
pageCount={data.total}
initialState={{
pageSize: 1,
}}
>
<DataGridPagination onChange={({ pageIndex }) => setPage(pageIndex)} />
</DataGrid>
</Page>
)
}

Access internal state#

You can access the react-table TableInstance by passing a ref to DataGrid. Check out the react-table documentation for all properties.

function InternalState() {
const gridRef = useRef(null)
return (
<Page
title="Customers"
height="400px"
toolbar={
<Toolbar>
<ToolbarButton
onClick={() => {
gridRef.current.toggleAllRowsSelected()
}}
label="Select all rows"
variant="primary"
/>
</Toolbar>
}
>
<DataGrid
instanceRef={gridRef}
columns={dataGrid.columns.concat()}
data={dataGrid.data.concat()}
isSelectable
/>
</Page>
)
}

Typescript#

To add typesafety for the meta properties, you need to add react-table-config.d.ts to your src. To use the default DataGrid config you can simply re-export the config from @saas-ui/pro.

// Copy to: src/types/react-table-config.d.ts
export * from '@saas-ui/pro/src/data-grid/react-table-config.d'
interface ExampleData {
id: string
name: string
email: string
}
const columns: Column<ExampleData>[] = [
{
accessorKey: 'id',
header: 'Id',
},
{
accessorKey: 'name',
header: 'Name',
},
{
accessorKey: 'email',
header: 'Email',
},
]
const data: ExampleData[] = [{
{
id: 1,
name: 'TaShya Charles',
email: 'urna.nec.luctus@icloud.couk'
},
{
id: 2,
name: 'Donovan Mosley',
email: 'lacinia.mattis.integer@icloud.couk',
},
}]
<DataGrid<ExampleData> columns={columns} data={data} />

Props#

DataGrid Props#

Accepts all Box properties.

columnsrequired

Type
ColumnDef<Data, any>[]

datarequired

Type
Data[]

aggregationFns

Type
Record<string, AggregationFn<any>>

autoResetAll

Type
boolean

autoResetExpanded

Type
boolean

autoResetPageIndex

Type
boolean

children

Description

DataGrid children

Type
ReactNode

className

Description

The table class name attribute

Type
string

columnResizeMode

Type
ColumnResizeMode

debugAll

Type
boolean

debugColumns

Type
boolean

debugHeaders

Type
boolean

debugRows

Type
boolean

debugTable

Type
boolean

defaultColumn

Type
Partial<ColumnDef<Data, unknown>>

enableColumnFilters

Type
boolean

enableColumnResizing

Type
boolean

enableExpanding

Type
boolean

enableFilters

Type
boolean

enableGlobalFilter

Type
boolean

enableGrouping

Type
boolean

enableHiding

Type
boolean

enableMultiRemove

Type
boolean

enableMultiRowSelection

Type
boolean | ((row: Row<Data>) => boolean)

enableMultiSort

Type
boolean

enablePinning

Type
boolean

enableRowSelection

Type
boolean | ((row: Row<Data>) => boolean)

enableSorting

Type
boolean

enableSortingRemoval

Type
boolean

enableSubRowSelection

Type
boolean | ((row: Row<Data>) => boolean)

filterFns

Type
Record<string, FilterFn<any>>

filterFromLeafRows

Type
boolean

getColumnCanGlobalFilter

Type
((column: Column<Data, unknown>) => boolean)

getExpandedRowModel

Type
((table: Table<any>) => () => RowModel<any>)

getFacetedMinMaxValues

Type
((table: Table<Data>, columnId: string) => () => [number, number])

getFacetedRowModel

Type
((table: Table<Data>, columnId: string) => () => RowModel<Data>)

getFacetedUniqueValues

Type
((table: Table<Data>, columnId: string) => () => Map<any, number>)

getFilteredRowModel

Type
((table: Table<any>) => () => RowModel<any>)

getGroupedRowModel

Type
((table: Table<any>) => () => RowModel<any>)

getIsRowExpanded

Type
((row: Row<Data>) => boolean)

getPaginationRowModel

Type
((table: Table<any>) => () => RowModel<any>)

getRowCanExpand

Type
((row: Row<Data>) => boolean)

getRowId

Type
((originalRow: Data, index: number, parent?: Row<Data>) => string)

getSortedRowModel

Type
((table: Table<any>) => () => RowModel<any>)

getSubRows

Type
((originalRow: Data, index: number) => Data[])

globalFilterFn

Type
FilterFnOption<Data>

groupedColumnMode

Type
false | "reorder" | "remove"

initialState

Type
Partial<VisibilityTableState & ColumnOrderTableState & ColumnPinningTableState & FiltersTableState & ... 5 more ... & RowSelectionTableState>

instanceRef

Description

The React Table instance reference

Type
Ref<Table<Data>>

isHoverable

Description

Enable row hover styles

Type
boolean

isMultiSortEvent

Type
((e: unknown) => boolean)

isSelectable

Description

Enable row selection

Type
boolean

isSortable

Description

Enable sorting on all columns

Type
boolean

manualExpanding

Type
boolean

manualFiltering

Type
boolean

manualGrouping

Type
boolean

manualPagination

Type
boolean

manualSorting

Type
boolean

maxMultiSortColCount

Type
number

mergeOptions

Type
((defaultOptions: TableOptions<Data>, options: Partial<TableOptions<Data>>) => TableOptions<Data>)

meta

Type
TableMeta<Data>

noResults

Description

No results component

Type
FC<any>

onColumnFiltersChange

Type
OnChangeFn<ColumnFiltersState>

onColumnOrderChange

Type
OnChangeFn<ColumnOrderState>

onColumnPinningChange

Type
OnChangeFn<ColumnPinningState>

onColumnSizingChange

Type
OnChangeFn<ColumnSizingState>

onColumnSizingInfoChange

Type
OnChangeFn<ColumnSizingInfoState>

onColumnVisibilityChange

Type
OnChangeFn<VisibilityState>

onExpandedChange

Type
OnChangeFn<ExpandedState>

onGlobalFilterChange

Type
OnChangeFn<any>

onGroupingChange

Type
OnChangeFn<GroupingState>

onPaginationChange

Type
OnChangeFn<PaginationState>

onResetFilters

Description

Callback fired when clear filters is clicked.

Type
(() => void)

onRowClick

Description

Callback fired when a row is clicked.

Type
((row: Row<Data>, e: MouseEvent<Element, MouseEvent>, meta?: any) => void)

onRowSelectionChange

Type
OnChangeFn<RowSelectionState>

onSelectedRowsChange

Description

Triggers whenever the row selection changes. @params rows The selected row id'

Type
((rows: string[]) => void)

onSortChange

Description

Triggers when sort changed. Use incombination with manualSortBy to enable remote sorting.

Type
((columns: ColumnSort[]) => void)

onSortingChange

Type
OnChangeFn<SortingState>

onStateChange

Type
((updater: Updater<TableState>) => void)

pageCount

Description

Use this for controlled pagination.

Type
number

paginateExpandedRows

Type
boolean

ref

Type
ForwardedRef<HTMLTableElement>

renderFallbackValue

Type
any

sortDescFirst

Type
boolean

sortingFns

Type
Record<string, SortingFn<any>>

state

Type
Partial<TableState>

DataGridPagination Props#

Accepts Box properties.

onChange

Type
((props: { pageIndex: number; pageSize: number; }) => void)

Was this helpful?