Skip to main content

DataGridTable

The core data grid component that renders the table structure, headers, rows, cells, and inline editing UI. DataGridTable is typically used internally by OGrid, but can also be used standalone for custom layouts.

Import

import { DataGridTable } from '@alaarab/ogrid-react-radix';
// or
import { DataGridTable } from '@alaarab/ogrid-react-fluent';
// or
import { DataGridTable } from '@alaarab/ogrid-react-material';

Props (React)

DataGridTable receives IOGridDataGridProps<T> which includes:

PropTypeDefaultDescription
itemsT[]RequiredArray of data items to render (paginated subset).
columns(IColumnDef<T> | IColumnGroupDef<T>)[]RequiredColumn definitions (flat or grouped).
getRowId(item: T) => RowIdRequiredFunction to extract a unique ID from each row item.
sortBystringundefinedCurrently sorted column ID.
sortDirection'asc' | 'desc'undefinedSort direction.
onSortChange(field: string, direction: 'asc' | 'desc') => voidundefinedCallback when user clicks a sortable column header.
filtersIFilters{}Active filter values (column ID to FilterValue).
onFiltersChange(filters: IFilters) => voidundefinedCallback when filters are applied or cleared.
visibleColumnsSet<string>All columnsSet of visible column IDs.
onVisibilityChange(columnId: string, visible: boolean) => voidundefinedCallback when column visibility changes.
onSetVisibleColumns(columns: Set<string>) => voidundefinedBulk-set all visible columns (used by Select All / Clear All).
editablebooleanfalseEnable inline cell editing.
cellSelectionbooleantrueEnable spreadsheet-like cell selection (active cell, range, fill handle, clipboard).
onCellValueChanged(event: ICellValueChangedEvent<T>) => voidundefinedCallback when a cell value is committed after edit.
rowSelectionRowSelectionMode'none'Row selection mode: 'none', 'single', or 'multiple'.
selectedRowsSet<RowId>new Set()Set of selected row IDs.
onSelectionChange(event: IRowSelectionChangeEvent<T>) => voidundefinedCallback when row selection changes.
showRowNumbersbooleanfalseShow Excel-style row numbers column at the start (1, 2, 3...).
statusBarboolean | IStatusBarPropsfalseShow status bar below the grid with row counts and aggregations.
emptyState{ message?: ReactNode; render?: () => ReactNode }undefinedCustom empty state when no rows are available.
density'compact' | 'normal' | 'comfortable''normal'Cell spacing/padding preset.
suppressHorizontalScrollbooleanfalseSuppress horizontal scrolling (overflow-x hidden).
virtualScrollIVirtualScrollConfigundefinedEnable virtual scrolling for large datasets.
columnReorderbooleanfalseEnable drag-and-drop column reordering.
dataSourceIDataSource<T>undefinedServer-side data source (for filter options and people search).
onCellError(error: Error, errorInfo: ErrorInfo) => voidundefinedError boundary callback for cell rendering errors.
aria-labelstringundefinedAccessible label for the grid.
aria-labelledbystringundefinedID of element that labels the grid.

Usage

Basic Example (React)

import { DataGridTable } from '@alaarab/ogrid-react-radix';
import type { IColumnDef } from '@alaarab/ogrid-react-radix';

interface Product {
id: number;
name: string;
price: number;
}

const columns: IColumnDef<Product>[] = [
{ columnId: 'name', name: 'Product Name', type: 'text' },
{ columnId: 'price', name: 'Price', type: 'numeric' },
];

const data: Product[] = [
{ id: 1, name: 'Widget', price: 29.99 },
{ id: 2, name: 'Gadget', price: 49.99 },
];

function MyGrid() {
return (
<DataGridTable
items={data}
columns={columns}
getRowId={(item) => item.id}
aria-label="Product catalog"
/>
);
}

With Sorting and Filtering (React)

import { DataGridTable } from '@alaarab/ogrid-react-radix';
import { useState } from 'react';

function MyGrid() {
const [sortBy, setSortBy] = useState<string>('name');
const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc');
const [filters, setFilters] = useState<IFilters>({});

const handleSortChange = (field: string, direction: 'asc' | 'desc') => {
setSortBy(field);
setSortDirection(direction);
};

return (
<DataGridTable
items={data}
columns={columns}
getRowId={(item) => item.id}
sortBy={sortBy}
sortDirection={sortDirection}
onSortChange={handleSortChange}
filters={filters}
onFiltersChange={setFilters}
/>
);
}

Angular Usage

In Angular Material/Radix packages, DataGridTable accepts a single propsInput property:

import { Component } from '@angular/core';
import { OGridService } from '@alaarab/ogrid-angular';
import { DataGridTableComponent } from '@alaarab/ogrid-angular-material';

@Component({
selector: 'app-my-grid',
standalone: true,
imports: [DataGridTableComponent],
template: `
<ogrid-datagrid-table [propsInput]="gridProps" />
`
})
export class MyGridComponent {
ogridService = new OGridService<Product>();
gridProps = this.ogridService.getDataGridProps();
}

In Angular PrimeNG, DataGridTable uses individual @Input() properties matching the React prop names.

Vue Usage

In Vue Vuetify/PrimeVue packages, DataGridTable accepts a single :grid-props prop:

<template>
<DataGridTable :grid-props="gridProps" />
</template>

<script setup lang="ts">
import { DataGridTable } from '@alaarab/ogrid-vue-vuetify';
import { useOGrid } from '@alaarab/ogrid-vue';

const { dataGridProps: gridProps } = useOGrid({ /* ... */ });
</script>

In Vue Radix, DataGridTable uses individual props via defineProps<IOGridProps>() (like React).

Accessibility

DataGridTable implements WCAG 2.1 AA standards with comprehensive keyboard navigation and screen reader support.

ARIA Attributes

The grid uses semantic HTML with proper ARIA roles:

<div role="grid" aria-label="Product catalog" aria-rowcount="1000">
<table>
<thead>
<tr role="row">
<th role="columnheader" aria-sort="ascending" scope="col">
Product Name
</th>
</tr>
</thead>
<tbody>
<tr role="row" aria-rowindex="1">
<td role="gridcell" tabindex="-1">Widget</td>
</tr>
</tbody>
</table>
</div>
AttributeElementPurpose
role="grid"Grid wrapperIdentifies the grid container for screen readers
role="row"<tr>Identifies table rows
role="columnheader"<th>Identifies column headers
role="gridcell"<td>Identifies data cells
aria-labelGrid wrapperProvides accessible name (pass via aria-label prop)
aria-rowcountGrid wrapperTotal number of rows in dataset (server-side pagination)
aria-rowindex<tr>Row's position in the full dataset (1-indexed)
aria-sort<th>Current sort state: "ascending", "descending", or "none"
aria-colindex<th>, <td>Column's position (1-indexed)
tabindex="-1"<td>Enables programmatic focus for keyboard navigation
aria-readonly<td>Indicates whether cell is editable ("false" when editable: true)

Keyboard Navigation

Complete Excel-style keyboard navigation:

Arrow Keys:

  • to - Move active cell one cell in the direction pressed
  • Ctrl+↑ / Ctrl+↓ - Jump to first/last row
  • Ctrl+← / Ctrl+ to - Jump to first/last column
  • Home / End - Jump to start/end of row
  • Ctrl+Home / Ctrl+End - Jump to first/last cell in grid

Selection:

  • Shift+Arrows - Extend cell selection range
  • Ctrl+A - Select all cells
  • Space (on checkbox column) - Toggle row selection

Editing:

  • Enter or F2 - Start editing active cell
  • Escape - Cancel editing and revert
  • Enter (while editing) - Commit and move down
  • Tab (while editing) - Commit and move right

Clipboard:

  • Ctrl+C / Cmd+C - Copy selected cells
  • Ctrl+X / Cmd+X - Cut selected cells
  • Ctrl+V / Cmd+V - Paste
  • Delete - Clear selected cells

Undo/Redo:

  • Ctrl+Z / Cmd+Z - Undo last edit
  • Ctrl+Y / Cmd+Shift+Z - Redo

Context Menu:

  • Shift+F10 - Open context menu for active cell

See the Accessibility Guide for complete keyboard shortcuts.

Focus Management

  • Focus visible: :focus-visible styles show a 2px solid outline (--ogrid-accent) only when navigating via keyboard
  • Focus restoration: After closing dialogs or exiting edit mode, focus returns to the active cell
  • Tab order: Logical tab order through interactive elements (header buttons, editable cells)

Screen Reader Support

Screen readers announce:

  • Cell navigation: "Product Name, cell, row 1, column 2"
  • Sort changes: "Sorted by Product Name, ascending"
  • Edit mode: "Editing Product Name, row 1, column 2"
  • Value changes: "Product Name changed from Widget to Gadget"

Tested with NVDA, JAWS, VoiceOver, and Narrator.

High Contrast Mode

All colors use CSS custom properties with system color fallbacks for Windows High Contrast Mode:

  • Focus indicators use system Highlight color
  • Borders use system ButtonText color
  • Text remains visible in all contrast themes

Usage Example

import { OGrid } from '@alaarab/ogrid-react-radix';

function AccessibleGrid() {
return (
<OGrid
data={products}
columns={columns}
getRowId={(item) => item.id}
aria-label="Product catalog"
rowSelection="multiple"
editable={true}
/>
);
}

For complete accessibility documentation, see the Accessibility Guide.

See Also