Patterns
Spreadsheet Navigation
When to use:
users move across a dense matrix with the keyboard.
Composition notes:
Keep row and cell coordinates explicit and define wrap behavior intentionally.
Trade-offs:
Powerful keyboard control, but higher integration complexity than a static table.
import {
DataGrid,
DataGridCell,
DataGridRow,
DataGridRowGroup,
} from '@vega-ui/react';
import './examples.css';
const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
const rota = [
{ name: 'Maya Chen', shifts: ['Day', 'Day', 'Off', 'Night', 'Night'] },Sparse Planner Grid
When to use:
the visual layout contains intentional gaps.
Composition notes:
Render only the cells that exist: missing columns are skipped by vertical movement on their own. Reserve exclude for cells that stay visible but must not take focus.
Trade-offs:
Navigation follows the real data without extra bookkeeping, but every row must still use the same column indexes for the same meaning.
import { useState } from 'react';
import {
DataGrid,
DataGridCell,
DataGridRow,
DataGridRowGroup,
Text,
} from '@vega-ui/react';
import './examples.css';
const year = 2026;
const months = Array.from({ length: 12 }, (_, month) => month);Controlled Active Cell
When to use:
the parent flow needs to sync grid position with other UI.
Composition notes:
Own active state in the parent. Changing active moves only the tab stop; focus a cell through apiRef when an outside control should move focus too.
Trade-offs:
More control, but more state coordination work.
import { useRef, useState } from 'react';
import {
Button,
DataGrid,
DataGridCell,
DataGridRow,
DataGridRowGroup,
Text,
type DataGridApiRef,
} from '@vega-ui/react';
import './examples.css';
Comparison
Quick Decision Rule
Choose DataGrid when keyboard navigation between individual cells is part of the core interaction.
DataGrid vs Table
Use DataGrid when:
- cells need active focus management
- spreadsheet-like interaction matters
Use Table when:
- the content is mostly static
- semantic table reading matters more than cell navigation
DataGrid vs DataGridSelectable
Use DataGrid when:
- basic navigation is enough
- selection should stay out of the grid layer
Use DataGridSelectable when:
- row or cell selection behavior is part of the UX
DataGrid vs DataGridPicker
Use DataGrid when:
- the main concern is navigation across a grid
Use DataGridPicker when:
- the grid is used as a picker surface rather than as a general cell-navigation system
Choose This Component When
- keyboard movement between cells is intentional
- the grid behaves more like an interaction model than a static table
- derived selection or picker layers would be premature
Do Not Choose This Component When
- semantic
Tableis enough - the user does not need active-cell navigation
- selection or picking flows are better handled by derived grid families
Troubleshooting
Keyboard Navigation Feels Wrong
Symptom
The active cell moves in a way that does not match the visible grid.
Likely Cause
Wrap mode or exclusion rules do not match the rendered layout.
How To Verify
- inspect
wrap - inspect
exclude - compare the visible matrix to the keyboard path
Fix
- align exclusion rules with the real sparse cells
- choose the correct
wrapmode for the product flow
Active Cell Does Not Sync With The Parent
Symptom
The UI appears to change active cell, but the parent state lags or diverges.
Likely Cause
Controlled active state is not using one source of truth.
How To Verify
- inspect
active - inspect
onChangeActive
Fix
- own
activein one parent state source - pass the same source to
DataGrid
Interactive Content Inside Cells Breaks Keyboard Flow
Symptom
Buttons or custom widgets inside a cell interfere with grid navigation.
Likely Cause
The cell content now competes with the grid’s own focus model.
How To Verify
- tab into the grid
- navigate with the keyboard
- test interaction inside the cell content
Fix
- simplify cell content first
- reintroduce interactive controls only when the keyboard model still holds