DataGrid
Headless spreadsheet grid for React Native — useDataGrid + DataGrid with FlashList virtualization, pinned columns, every cell variant, sheet editors, status transitions, grouping, change tracking, paging, color rules and gallery mode.
Installation
pnpm dlx @docyrus/cli add @docyrus/rn-data-gridpnpm add @tanstack/react-table @shopify/flash-list react-native-svg jsonata @react-querybuilder/core expo-clipboard (optional)The native grid mirrors the web API 1:1: a headless controller (useDataGrid) owns the TanStack table and all grid state, and DataGrid renders whatever it returns. Mobile idioms replace desktop ones — editors open in bottom sheets, long-press enters selection mode, long-press on a header opens the column actions, and rows are virtualized with FlashList v2.
Usage
Headless (recommended — same as web)
import {
DataGrid,
DataGridToolbar,
getDataGridSelectColumn,
useDataGrid,
type ColumnDef
} from '@/components/docyrus-native/data-grid';
type Employee = { id: string; name: string; status: string; salary: number; hireDate: string };
const columns: ColumnDef<Employee>[] = [
getDataGridSelectColumn<Employee>(),
{ accessorKey: 'name', header: 'Name', size: 160, meta: { label: 'Name', cell: { variant: 'short-text' } } },
{
accessorKey: 'status',
header: 'Status',
meta: {
label: 'Status',
cell: {
variant: 'status',
options: [
{ label: 'Active', value: 'active', color: 'green' },
{ label: 'On Leave', value: 'on-leave', color: 'amber' },
{ label: 'Sick', value: 'sick', parent: 'on-leave', forceDescription: true },
{ label: 'Closed', value: 'closed', isFinalOption: true, forceFollowupDate: true }
]
}
}
},
{ accessorKey: 'salary', header: 'Salary', meta: { label: 'Salary', cell: { variant: 'currency', currency: 'USD' } } },
{ accessorKey: 'hireDate', header: 'Hire date', meta: { label: 'Hire date', cell: { variant: 'date' } } }
];
export function EmployeesGrid() {
const [data, setData] = useState<Employee[]>(initialRows);
const grid = useDataGrid({
data,
columns,
getRowId: row => row.id,
onDataChange: setData,
enableSearch: true,
enableChangeTracking: true,
onChangesSave: async (changes) => api.updateMany(changes),
pagingMode: 'standard',
pageSize: 50,
rowColorRules: [{ formula: 'status = "closed"', color: 'red-100' }],
initialState: { columnPinning: { left: ['select', 'name'] } },
onRowsDelete: rows => api.delete(rows.map(row => row.id)),
meta: {
onStatusUpdate: input => api.statusUpdate(input),
onOpenRelation: ({ relatedId }) => router.push(`/records/${relatedId}`)
}
});
return (
<View className="flex-1">
<DataGridToolbar table={grid.table} />
<DataGrid {...grid} actions={[{ label: 'Archive', onAction: rows => archive(rows) }]} />
</View>
);
}Convenience (data + columns, native-only)
Without a table prop, DataGrid creates the controller internally. Every useDataGrid option is accepted, plus the legacy controlled sorting / columnFilters pairs and onDataUpdate.
<DataGrid data={tasks} columns={taskColumns} onDataChange={setTasks} stretchColumns height={320} />Interaction model
| Gesture | Result |
|---|---|
| Tap a cell | Selection mode → toggle the row. Email / phone / url → contact sheet (Compose email · Call · Send message · Open link · Edit). Checkbox / switch → toggles in place. tableMeta.onRowClick set → called with the row. Editable cell → editor sheet. Otherwise → row detail sheet. |
| Long-press a row | Selects it and enters selection mode (the selection bar appears). |
| Tap a header | Cycles sort asc → desc → none. |
| Long-press a header | Column actions: sort, pin / unpin, move left / right, group by, "Show autonumber" (relation), tableMeta.columnHeaderActions(columnId), hide. |
| Pull down | onRefresh. |
useDataGrid
function useDataGrid<TData>(options: UseDataGridProps<TData>): UseDataGridReturn<TData>;Options
Every TanStack TableOptions<TData> key (except getCoreRowModel / pageCount) is spread into the table — data, columns, getRowId, state, initialState, onColumnVisibilityChange, onColumnOrderChange, onColumnPinningChange, onColumnSizingChange, onGroupingChange, onExpandedChange, onPaginationChange, manualPagination, manualSorting, manualFiltering, rowCount, enableRowSelection, meta, … sorting, columnFilters and rowSelection are grid-owned (read state.* when supplied, else internal) and their on*Change callbacks receive the resolved value.
| Option | Type | Default | Description |
|---|---|---|---|
data | TData[] | — | Rows (required). |
columns | ColumnDef<TData>[] | — | Column definitions; meta.cell (CellOpts) picks the cell variant (required). |
onDataChange | (data: TData[]) => void | — | Receives the next data array after every cell write / discard. |
onRowAdd | () => Partial<CellPosition> | Promise<Partial<CellPosition> | null | void> | null | void | — | Enables the "Add row" footer; the returned position is scrolled to. |
onRowsAdd | (count: number) => void | Promise<void> | — | Accepted for web parity. |
onRowsDelete | (rows: TData[], rowIndices: number[]) => void | Promise<void> | — | Enables the selection bar's Delete (through tableMeta.onRowsDelete). |
onFilesUpload | (params: { files: NativeFile[]; rowIndex: number; columnId: string }) => Promise<FileCellData[]> | — | Makes file / image cells editable. |
onFilesDelete | (params: { fileIds: string[]; rowIndex: number; columnId: string }) => void | Promise<void> | — | File removal from the file editor. |
rowHeight | RowHeightValue | 'short' | Initial row height (re-seeded when the prop changes). |
onRowHeightChange | (rowHeight: RowHeightValue) => void | — | Row height change notification. |
displayMode | 'table' | 'gallery' | 'table' | Initial display mode (re-seeded when the prop changes). |
onDisplayModeChange | (mode: DataGridDisplayMode) => void | — | Display mode change notification. |
enableSearch | boolean | false | Find-in-grid (searchState); DataGrid renders the find bar. |
enableGrouping | boolean | true | Groupable variants get a normalized getGroupingValue (dates bucket by local day). |
readOnly | boolean | false | Disables every write. |
enableChangeTracking | boolean | false | Buffers edits: tinted cells + change bar with Save / Cancel. |
onChangesSave | (changes: RowChange[], data: TData[]) => void | Promise<void> | — | Save from the change bar. |
onChangesDiscard | () => void | — | Cancel from the change bar (data is restored through onDataChange). |
getRowLabel | (row: TData, rowIndex: number) => string | — | Row label for the change list and row detail title. |
maxSearchMatches | number | 500 | Find-in-grid match cap. |
rowColorRules | DataGridRowColorRule[] | — | JSONata row background rules (evaluated async). |
cellColorRules | DataGridCellColorRule[] | — | JSONata cell background rules. |
pagingMode | 'virtual-scroll' | 'standard' | 'virtual-scroll' | 'standard' = client pagination + paging footer. Switching at runtime re-seeds the page size. |
pageSize | number | 50 | Page size in 'standard' mode. |
overscan, measureRows, dir, autoFocus, enableSingleCellSelection, enableColumnSelection, enablePaste, onPaste, maxSelectCells | — | — | Accepted and ignored (desktop-only). |
Return value
| Key | Type | Description |
|---|---|---|
table | Table<TData> | TanStack table (sorted / filtered / grouped / expanded / paginated models). |
tableMeta | TableMeta<TData> | Meta passed to cells (see below). |
columns | ColumnDef<TData>[] | The input columns. |
rowHeight | RowHeightValue | Current row height. |
displayMode | DataGridDisplayMode | Current display mode. |
focusedCell | CellPosition | null | Last tapped / navigated cell. |
editingCell | CellPosition | null | Cell whose editor sheet is open. |
searchState | SearchState | null | { searchQuery, onSearchQueryChange, onSearch, searchMatches, matchIndex, searchOpen, onSearchOpenChange, onNavigateToNextMatch, onNavigateToPrevMatch } when enableSearch. |
onRowAdd | (() => Promise<Partial<CellPosition> | null>) | undefined | Wrapped onRowAdd. |
changedCellsByRowId | Map<string, Set<string>> | null | Changed cells (change tracking only). |
changedRowCount | number | Rows with pending changes. |
onChangesSave | (() => Promise<void>) | undefined | Change tracking only. |
onChangesDiscard | (() => void) | undefined | Change tracking only. |
changeMapRef | RefObject<Map<string, ChangeMapEntry<TData>>> | undefined | Pending change map. |
getRowLabel | ((row, rowIndex) => string) | undefined | Passed through. |
rowColorMap | Map<string, string> | Row id → colour. |
cellColorMap | Map<string, Map<string, string>> | Row id → column id → colour. |
pagingMode | DataGridPagingMode | undefined | Passed through. |
selectedRows | TData[] | Selected originals. |
selectedRowCount | number | Selected row count. |
TableMeta
tableMeta spreads options.meta and adds the grid-owned members. Supply the host-side members through meta.
| Member | Type | Source | Description |
|---|---|---|---|
onDataUpdate | (update: CellUpdate | CellUpdate[]) => void | grid | Write one or many cells. |
onRowsDelete | (rowIndices: number[]) => void | Promise<void> | grid | Present when onRowsDelete option is set. |
onRowSelect | (rowId: string, checked: boolean) => void | grid | Toggle a row. |
onCellClick / onCellEditingStart / onCellEditingStop | functions | grid | Focus / open / close the editor sheet. |
getIsCellChanged | (rowId, columnId) => boolean | grid | Change tracking lookup. |
getVisualRowIndex | (rowId) => number | undefined | grid | 1-based leaf index (skips group rows). |
rowHeight / onRowHeightChange | grid | Read by DataGridRowHeightMenu. | |
displayMode / onDisplayModeChange | grid | Read by DataGridDisplayMenu. | |
focusedCell / editingCell / readOnly | grid | Current state. | |
onFilesUpload / onFilesDelete | option | File cells. | |
formatDate / formatDateTime / formatNumber | formatters | meta › DateFormatProvider / NumberFormatProvider (e.g. DocyrusTenantProvider) › cell fallback (toLocale* / Intl.NumberFormat) | Tenant formatting. |
onRowClick | (row: TData) => void | meta | Row tap instead of the built-in detail sheet. |
onStatusUpdate | (input: { rowIndex; columnId; value; secondaryValue?; description?; followupDate? }) => Promise<void> | meta | Enables the status note / follow-up step. |
loadCellOptions | (column, { search, page, pageSize, signal }) => Promise<{ items; hasMore? }> | meta | Async, paged, abortable options for relation / user / enum editors. |
columnOptions / onColumnOptionsChange / onColumnOptionsReset | meta | Per-column overrides (showAutonumber). | |
columnHeaderActions | (columnId) => DataGridColumnHeaderAction[] | meta | Extra header long-press actions. |
onOpenRelation / getRelationHref | (args: RelationNavigationArgs) => void / string | meta | Relation "open" affordance (onOpenRelation wins; the href opens with Linking). |
emailClient | RestApiClient | meta (useDocyrusDataGrid wires its client) | Email cell "Compose email" opens the grid-hosted EmailComposeDialog pre-addressed to the cell value (web parity). |
messageClient | RestApiClient | meta (useDocyrusDataGrid wires its client) | Phone cell "Send message" opens the grid-hosted InstantMessageComposeDialog (SMS / WhatsApp). |
onComposeEmail | (address: string, row: TData) => void | meta | Native. Handle the email action yourself (wins over emailClient; without either → mailto:). |
onSendMessage | (phone: string, row: TData) => void | meta | Native. Handle the message action yourself (wins over messageClient; without either → sms:). |
DataGrid
DataGridProps<TData> = DataGridHeadlessProps<TData> | DataGridConvenienceProps<TData>.
Props (headless — spread useDataGrid())
| Prop | Type | Default | Description |
|---|---|---|---|
table | Table<TData> | — | From useDataGrid. Selects the headless path. |
tableMeta | TableMeta<TData> | — | From useDataGrid. |
columns | ColumnDef<TData>[] | — | From useDataGrid. |
rowHeight | RowHeightValue | — | From useDataGrid (36 / 56 / 76 / 96 dp, 1–4 lines). |
displayMode | DataGridDisplayMode | — | 'gallery' renders DataGridGallery. |
focusedCell / editingCell | CellPosition | null | — | From useDataGrid. |
searchState | SearchState | null | — | Renders the find bar; matches are tinted and scrolled to. |
onRowAdd | () => Promise<Partial<CellPosition> | null> | — | "Add row" footer. |
changedCellsByRowId, changedRowCount, onChangesSave, onChangesDiscard, changeMapRef | — | Change bar + tinted cells. | |
getRowLabel | (row, rowIndex) => string | — | Change list + detail title. |
rowColorMap / cellColorMap | Map | — | Colour rules. |
pagingMode | 'virtual-scroll' | 'standard' | — | 'standard' shows DataGridPaginationFooter. |
actions | DataGridAction<TData>[] | — | Selection bar actions. |
onClearFilters | () => void | resets column filters + search | Empty-state "Clear filters". |
height | number | 'auto' | fill parent | Fixed height in dp. The grid is flex-1 otherwise — inside a ScrollView (unbounded height) pass a number. |
stretchColumns | boolean | false | Grow columns to the viewport width. |
addRowLabel | string | "Add row" | Footer label. |
cardConfig | DataGridCardConfig<TData> | — | Legacy 3-slot card config (adapted). |
galleryCardConfig | DataGalleryCardConfig<TData> | — | Gallery card config (wins over cardConfig). |
galleryDisplayConfig | DataGalleryDisplayConfig | DEFAULT_DATA_GALLERY_DISPLAY_CONFIG | Gallery display config. |
onCardClick | (record: TData, rowIndex: number) => void | onRowClick / detail sheet | Gallery card press. |
isLoading | boolean | false | Skeleton while there are no rows. |
isReloading | boolean | false | Spinner overlay; rows stay mounted. |
onRefresh | () => void | — | Pull-to-refresh. |
refreshing | boolean | isReloading | Pull-to-refresh spinner. |
emptyText | string | "No data" / "No results found" | Empty-state title. |
striped | boolean | false | Alternate row tint. |
showSummary | boolean | false | Row count + display mode chips. |
className | string | — | Container classes. |
selectedRows / selectedRowCount | — | Accepted and ignored (derived from rowSelection). |
Props (convenience — no table)
All useDataGrid options plus every view prop above, and:
| Prop | Type | Default | Description |
|---|---|---|---|
sorting / onSortingChange | SortingState / (sorting) => void | — | Controlled sorting. |
columnFilters / onColumnFiltersChange | ColumnFiltersState / (filters) => void | — | Controlled filters (values are DataGridFilterValue). |
onDataUpdate | (update: CellUpdate | CellUpdate[]) => void | — | Called for every cell write. |
enableGrouping | boolean | false | Legacy default (the hook defaults to true). |
DataGridAction
| Field | Type | Description |
|---|---|---|
key | string | Stable key (defaults to label). |
label | string | Button label. |
icon | ReactNode | Leading icon. |
variant | 'default' | 'destructive' | Button colour. |
disabled | boolean | Disable the button. |
onAction | (selectedRows: TData[], rowIndices?: number[]) => void | Press handler (web signature + native row indices). |
render | (selectedRows: TData[]) => ReactNode | Custom renderer (wins over the button). |
Cell variants (CellOpts)
| Variant | Options | Display | Editor |
|---|---|---|---|
short-text / long-text | — | Text, clamped to the row-height line count | Text / textarea field |
email / phone / url | — | Link text | Contact sheet → Edit → email / phone / url field |
number / currency / percent | min, max, step, decimalPrecision, thousandSeparator, currency, symbolPosition | tableMeta.formatNumber or Intl.NumberFormat | Number / money / percent field |
select / enum | options, display: 'badge' | 'text' (enum: appSlug, dataSourceSlug, fieldSlug) | Colour badge or dot + text | Searchable list (enum without options → loadCellOptions) |
status | options (parent, isFinalOption, forceDescription, forceFollowupDate), display | "Main › Sub" badges, final marker | Two-level list → note / follow-up step → onStatusUpdate |
multi-select / tag-select | options | Chips (+N) | Multi list with Save / Clear |
user / user-multi-select | options (avatarUrl, initials) | Avatar(s) + name (raw { id, firstname, lastname, photo } supported) | Avatar list (async via loadCellOptions when no options) |
relation | dataSourceId, relationAppSlug, relationDataSourceSlug, displayField, iconField, showAutonumber | Icon / logo, autonumber, label, open affordance | Async paged list (loadCellOptions); writes { id, name } |
checkbox / switch | trueLabel, falseLabel | Box / pill | Toggles in place |
date / datetime / time / date-range | — | tableMeta.formatDate / formatDateTime or locale fallback | Date / datetime / time / range pickers |
rating | max, icon: RatingIconName | Icons | Rating field |
duration | — | HH:MM:SS | Text input; HH:MM = hours:minutes (web parsing) |
color / icon / currency-code | — | Swatch / icon / code | Colour / icon / currency pickers |
file / image | maxFileSize, maxFiles, accept, multiple | File name / thumbnails | Upload / remove through onFilesUpload / onFilesDelete (read-only without them) |
uuid | showCopyButton | Mono text (long-press copies) or copy button — optional expo-clipboard, share-sheet fallback | — |
chart | chartType: 'sparkline' | 'bar', dataKey, color, expandedCellContent | SVG sparkline / bars (+ expand sheet) | — |
sparkline | color, dataKey | Deprecated alias of chart | — |
Columns whose header is a function (e.g. getDataGridSelectColumn, getDataGridActionsColumn) render through flexRender, like web. Column width is the TanStack size (falls back to the deprecated meta.width).
Toolbar & menus
Every menu is a compact chip that opens a bottom sheet (web: popover / dropdown). All take table and the common props below unless noted.
| Common prop | Type | Default | Description |
|---|---|---|---|
table | Table<TData> | — | The grid's TanStack table. |
disabled | boolean | false | Disable the trigger. |
className | string | — | Trigger chip classes. |
| Component | Extra props | Description |
|---|---|---|
DataGridToolbar | enableFilter (true), enableSort (true), enableRowHeight (true), enableFields (true), enableView (true), enableDisplayMode (false), enableGroup (false), startContent, endContent, contentClassName; enableSearch / enablePaste / enableRowAdd / enableRowsDelete / enableUndoRedo accepted and ignored | Horizontally scrollable row of the menus. |
DataGridFilterMenu | getAsyncOptions?: (column) => AsyncOptionsConfig | undefined | Column filter chips (operator + value). |
DataGridAdvancedFilter | group: RuleGroupType | undefined, onChange: (group | undefined) => void | AND/OR query-builder draft editor, emits on Apply. |
DataGridSortMenu | — | Multi-column sort. |
DataGridGroupMenu | defaultRowGroupingColumn?: string | Row grouping. |
DataGridRowHeightMenu | — | short / medium / tall / extra-tall. |
DataGridFieldsMenu | enableReorder (true), enablePinning (true) | Visibility, order, pin-left. |
DataGridDisplayMenu | — | Table ↔ gallery. |
DataGridViewMenu | storageKey?: string | Local saved views (sync 'local' store). |
DataGridExportMenu | onExport?: (rows, format, columnScope) => void, isExporting, fileName ('export') | CSV / Excel / JSON / Markdown; built-in writer + share sheet without onExport. |
DataGridSearch | searchQuery, onSearchQueryChange, onSearch?, searchMatches?, matchIndex?, onNavigateToNextMatch?, onNavigateToPrevMatch?, searchOpen?, onSearchOpenChange?, placeholder?, autoFocus? (no table) | Find-in-grid bar. |
DataGridSidePanel
Container for useDocyrusDataGrid's vertical-tabs view picker (sidePanel). Web renders a fixed <aside> column; native is a full-width strip on phones (the vertical-tabs DataGridViewSelect opens its view list as a bottom sheet) and a side column on tablets.
| Prop | Type | Default | Description |
|---|---|---|---|
header | ReactNode | — | Header above the body (strings render as a caption). |
footer | ReactNode | — | Footer below the body. |
width | number | 224 | Column width in dp (web: Tailwind class 'w-56'). |
columnBreakpoint | number | 768 | Native. Window width at which the column layout kicks in. |
layout | 'strip' | 'column' | derived | Native. Force a layout. |
className | string | — | Root classes. |
children | ReactNode | — | Panel body. |
Components
| Component | Description |
|---|---|
DataGrid | Grid view (headless or convenience). |
DataGridSidePanel | Side panel container (strip on phones, column on tablets). |
DataGridGallery | In-grid gallery (DataGalleryCard in a responsive FlashList). |
DataGridPaginationFooter | Paging footer driven by table.getState().pagination (pageSizeOptions). |
DataGridChangeActionBar | Change tracking bar with pending-change list. |
DataGridColumnHeader | Header cell (tap sort, long-press actions). |
DataGridCellEditor | Editor sheet for editingCell. |
DataGridSkeleton / DataGridSkeletonGrid / DataGridSkeletonToolbar | Loading placeholders. |
DataGridSelectHeader / DataGridSelectCell | Checkbox header / cell. |
DataGridCell | Standalone read-only cell (value, cellOpts, rowHeight, tableMeta?, row?, columnId?, backgroundColor?, className?) — native-only. |
DataGridCellContent | Unwrapped cell content renderer — native-only. |
Exports
| Export | Kind |
|---|---|
useDataGrid | Hook |
getDataGridSelectColumn, getDataGridActionsColumn | Column factories |
adaptLegacyCardConfig, getIsCellEditable | Helpers |
copyToClipboard(text), isClipboardAvailable() | Clipboard (optional expo-clipboard, share-sheet fallback; resolves 'clipboard' | 'share') |
applyViewToTable, captureViewSnapshot, getManagedColumns, getColumnLabel, getGeneratedViewId, moveColumn, reorderColumn, canMoveColumn, pinColumnLeft, pinColumnRight, unpinColumn, SYSTEM_COLUMN_IDS | View utils |
dataGridFilterFn, getFilterFn, isDataGridFilterValue, matchesDataGridFilter | Filter helpers |
DATA_GRID_DEFAULT_PAGE_SIZE, DATA_GRID_PAGE_SIZE_OPTIONS, isSavedDataGridView | Constants / guards |
Type Exports
| Type | Description |
|---|---|
UseDataGridProps<TData> / UseDataGridReturn<TData> | Hook options / return. |
DataGridProps<TData>, DataGridHeadlessProps<TData>, DataGridConvenienceProps<TData>, DataGridViewProps<TData> | Grid props. |
DataGridAction<TData> | Selection bar action. |
CellOpts, CellVariant, CellSelectOption, CellUserOption, CellOptionIconComponent, RatingIconName | Cell configuration. |
CellUpdate, CellChange, RowChange, CellPosition, ChangeMapEntry, FileCellData, SearchState | Grid state. |
RowHeightValue, DataGridDisplayMode, DataGridPagingMode, DataGridCardConfig | Layout. |
DataGridRowColorRule, DataGridCellColorRule, DataGridColumnOptions, DataGridColumnHeaderAction, RelationNavigationArgs | Rules / column options. |
SavedDataGridView, ICollectionFilterGroup, ICollectionFilterRule, ICollectionListParams, ICollectionOrderBy | Views / collection params. |
FilterOperator, FilterValue, DataGridFilterValue | Filter values. |
DataGridCellProps, DataGridCellContentProps, DataGridGalleryProps, DataGridPaginationFooterProps, DataGridChangeActionBarProps, DataGridColumnHeaderProps, DataGridCellEditorProps, DataGridSidePanelProps, DataGridAdvancedFilterProps, DataGridToolbarProps, DataGridSearchProps, DataGridSortMenuProps, DataGridFilterMenuProps, DataGridFieldsMenuProps, DataGridGroupMenuProps, DataGridRowHeightMenuProps, DataGridDisplayMenuProps, DataGridViewMenuProps, DataGridExportMenuProps | Component props. |
DataGridExportFormat, DataGridExportColumnScope | Export menu unions. |
ColumnDef | Re-exported from @tanstack/react-table. |
Translation keys
Copy goes through useUiTranslation() with the web ui.dataGrid.* keys (addRow, emptyTitle, emptyFilteredTitle, clearFilters, selectAll, selectRow, clearSelection, contextMenuDeleteRows, contextMenuClear, save, saving, cancel, item, itemsChanged, changesPending, cellEmpty, searchStatus, noStatusFound, statusNote, statusFollowup, statusUpdateFailed, openRelation, copyId, copyFailed, copiedToClipboard, sortAsc, sortDesc, removeSort, pinToLeft, unpinFromLeft, moveColumnLeft, moveColumnRight, groupByColumn, showAutonumber, hideColumn, tableView, galleryView, pagination.*) plus ui.common.cancel, ui.emailComposer.compose, ui.instantMessageComposer.compose, ui.formField.fileSource*. Native-only keys: ui.dataGrid.searchOptions, noOptions, call, openLink, edit, tapToEdit, rowDetails, rowCount.
Migration from the previous native DataGrid
- Headless first.
useDataGrid+<DataGrid {...grid} />is the primary API.<DataGrid data columns />still works (convenience path). - Built-in toolbar removed. The grid no longer renders its own filter / sort / group / row-height / display toolbar — compose
DataGridToolbarand the menus above it.enableSearchrenders the find bar (web find-in-grid) instead of a clientglobalFilter. - Row tap calls
tableMeta.onRowClickwhen supplied, else opens the editor sheet for editable cells, else the row detail sheet (email / phone / url cells open the contact sheet; checkbox / switch toggle in place). Long-press still selects. - Summary chips ("N rows" / mode) are opt-in via
showSummary. DataGridProps/DataGridActionmoved fromtypes.tstodata-grid.tsx(still exported from the barrel).DataGridAction.onActionis optional and receives(rows, rowIndices?).onRowsDelete(rows, indices)is now wired (selection bar Delete).onDataUpdatereceives a single update or an array.rowHeightadds'extra-tall';heightaccepts'auto'; the default is now fill-parent instead of intrinsic.- Column width: use TanStack
size;meta.widthis a deprecated fallback. - Date / number cells format through
DateFormatProvider/NumberFormatProvider(ortableMeta.format*) — no moretoISOString()output. DataGridCellacceptsrowHeightas a preset or pixels and optionaltableMeta/row/columnId.sparklineis a deprecated alias of{ variant: 'chart', chartType: 'sparkline' }.- The old internal
components/*files andlib/data-grid-utils.tswere removed.
DataGallery
Card gallery for React Native — a TanStack-table-driven FlashList of rich cards (5 variants, 8 field slots, cover styles, density, responsive columns) with toolbar, search, selection bar and paging. API-aligned with the web DataGallery.
DataGridViewSelect
Saved-view switcher for a data grid — pill tabs, dropdown or picker sheet, active-view actions, a full-screen view editor with 11 sections and a manage-views sheet. Same API as the web component.