Skip to content

DataGrid

The main virtualized data grid component. Handles sorting, filtering, flash highlighting, and column management.

import { DataGrid } from '@askturret/grid';
import '@askturret/grid/styles.css';
const users = [
{ id: 1, name: 'Alice', email: '[email protected]' },
{ id: 2, name: 'Bob', email: '[email protected]' },
];
const columns = [
{ field: 'name', header: 'Name' },
{ field: 'email', header: 'Email' },
];
<DataGrid data={users} columns={columns} rowKey="id" />
PropTypeDefaultDescription
dataT[]requiredData array to display
columnsColumnDef<T>[]requiredColumn definitions
rowKeykeyof T | (row: T) => stringrequiredUnique row identifier
emptyMessagestring'No data'Message when data is empty
compactbooleanfalseReduce row height for dense displays
showFilterbooleanfalseShow filter input
filterPlaceholderstring'Filter...'Filter input placeholder
filterFields(keyof T)[]all columnsFields to search
classNamestring-Additional CSS class
stickyHeaderbooleantrueMake header sticky
virtualizeboolean | 'auto''auto'Force virtualization mode
rowHeightnumber36Row height in pixels
onRowClick(row: T) => void-Row click handler
disableFlashbooleanfalseDisable flash highlighting
resizablebooleanfalseEnable column resizing
reorderablebooleanfalseEnable column reordering
columnWidthsRecord<string, number>-Controlled column widths
onColumnResize(field: string, width: number) => void-Column resize callback
columnOrderstring[]-Controlled column order
onColumnReorder(newOrder: string[]) => void-Column reorder callback
minColumnWidthnumber50Minimum column width
maxColumnWidthnumber500Maximum column width
interface ColumnDef<T> {
field: keyof T | string;
header: string;
width?: string;
align?: 'left' | 'right' | 'center';
sortable?: boolean;
flashOnChange?: boolean;
formatter?: (value: unknown, row: T) => ReactNode;
cellClass?: (value: unknown, row: T) => string;
resizable?: boolean;
reorderable?: boolean;
minWidth?: number;
maxWidth?: number;
}

Click column headers to sort. Columns are sortable by default.

const columns = [
{ field: 'name', header: 'Name', sortable: true },
{ field: 'price', header: 'Price', sortable: true },
{ field: 'actions', header: 'Actions', sortable: false },
];

Enable the filter input with showFilter:

<DataGrid
data={users}
columns={columns}
rowKey="id"
showFilter
filterPlaceholder="Search..."
filterFields={['name', 'email']} // Only search these fields
/>

The filter uses trigram indexing for fast substring matching on large datasets.

Cells flash green (increase) or red (decrease) when numeric values change:

const columns = [
{ field: 'symbol', header: 'Symbol' },
{ field: 'price', header: 'Price', flashOnChange: true },
{ field: 'volume', header: 'Volume', flashOnChange: true },
];

::: tip Adaptive Mode Flash highlighting automatically disables when FPS drops below 55 to maintain performance. :::

Drag column borders to resize:

// Uncontrolled
<DataGrid
data={data}
columns={columns}
rowKey="id"
resizable
/>
// Controlled
const [widths, setWidths] = useState({ name: 200, email: 300 });
<DataGrid
data={data}
columns={columns}
rowKey="id"
resizable
columnWidths={widths}
onColumnResize={(field, width) =>
setWidths(prev => ({ ...prev, [field]: width }))
}
/>

Drag column headers to reorder:

// Uncontrolled
<DataGrid
data={data}
columns={columns}
rowKey="id"
reorderable
/>
// Controlled
const [order, setOrder] = useState(['name', 'email', 'age']);
<DataGrid
data={data}
columns={columns}
rowKey="id"
reorderable
columnOrder={order}
onColumnReorder={setOrder}
/>

The grid automatically virtualizes when row count exceeds 100. Force virtualization mode:

<DataGrid
data={largeDataset}
columns={columns}
rowKey="id"
virtualize={true} // Always virtualize
rowHeight={32} // Custom row height
/>

Format cell values with the formatter prop:

const columns = [
{ field: 'symbol', header: 'Symbol' },
{
field: 'price',
header: 'Price',
formatter: (value) => `$${value.toFixed(2)}`,
},
{
field: 'change',
header: 'Change',
formatter: (value, row) => (
<span className={value >= 0 ? 'green' : 'red'}>
{value >= 0 ? '+' : ''}{value.toFixed(2)}%
</span>
),
},
];

Apply conditional classes to cells:

const columns = [
{
field: 'status',
header: 'Status',
cellClass: (value) => {
if (value === 'active') return 'status-active';
if (value === 'pending') return 'status-pending';
return '';
},
},
];
<DataGrid
data={users}
columns={columns}
rowKey="id"
onRowClick={(user) => {
console.log('Selected:', user);
navigate(`/users/${user.id}`);
}}
/>

Reduce row height for dense displays:

<DataGrid
data={data}
columns={columns}
rowKey="id"
compact
/>