DataGridLite

Data grid with cell focus, pinned columns, sorting, and selection.

Overview

  • Use DataGridLite for cell-level keyboard navigation. Use Table when row-level reading and selection are enough.

Aliases

grid, cell navigation table

When to use

  • Use DataGridLite when users need to move cell by cell with the keyboard but do not need full spreadsheet editing.
  • Use pinned columns when the first column must remain visible during horizontal scrolling.

When not to use

  • Do not use DataGridLite when a regular data table is enough.
  • Do not use it for inline editing, column resizing, or virtualization.

Structural parts

grid scroll region

shell

Overflow shell for the grid surface.

column header row

header

Column names and sort controls.

grid cell

cell

Focusable cell surface within the grid.

Public interface

Props
NameTypeDefaultDescription
columnsTableColumn[]—Column definitions shared with the broader table model.
rowsTableRow[]—Grid rows, each with a stable id.
captionstring—Visible grid caption.
descriptionstring—Supporting context for the grid.
size'sm' | 'md''md'Chooses grid density.
sortablebooleanfalseEnables sortable headers.
selectablebooleanfalseShows row selection checkboxes.
pinnedColumnsnumber0Number of leading columns pinned during horizontal scroll.
activeCell{ row: number; col: number }—Controlled active cell coordinates.
emptyTitlestring'No rows'Title shown when the grid has no rows.
emptyDescriptionstring''Optional empty-state guidance.
sortBystring—Controlled active sort key.
sortDirection'asc' | 'desc''asc'Controlled sort direction.
selectedRowIdsstring[]—Controlled selected row IDs.
onActiveCellChange(detail: { activeCell: { row: number; col: number } }) => void—Runs when the focused cell changes.
onSortChange(detail: { sortBy: string; sortDirection: "asc" | "desc" }) => void—Runs when sorting changes.
onSelectionChange(detail: { ids: string[] }) => void—Runs when row selection changes.
themeThemeContract—Sets the theme used to resolve component styles.
Events
NamePayloadDescription
activecellchange{ activeCell: { row: number; col: number } }Fires when the active cell changes.
sortchange{ sortBy: string; sortDirection: "asc" | "desc" }Fires when sorting changes.
selectionchange{ ids: string[] }Fires when row selection changes.
Slots
NameDescription
defaultDataGridLite is data-driven and does not expose custom cell slots.

Variants, sizes, and states

Variants

  • sortable: Headers expose sort behavior
  • selectable: Rows expose selection controls
  • pinned: Leading columns stay visible

Sizes

  • sm: Dense grid
  • md: Default grid density

States

  • active: Focused cell
  • selected: Selected row
  • sorted: Column sort active

Accessibility

Semantics

  • Uses grid semantics with an active cell and real column/row structure.

Keyboard

  • Arrow keys move the active cell. Home and End jump across the active row.

Screen readers

  • Focused cell context, selection state, and sorting remain explicit through grid semantics.

Checklist

  • Verify that the control has an accessible name.
  • Verify that keyboard focus is visible in every state and size.
  • Identify disabled, selected, and error states with text or symbols as well as color.

Tokens and CSS variables

root

--dk-grid-gap
clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)

caption

--dk-grid-caption-color
#16181c
--dk-grid-caption-size
clamp(1.778rem, 1.6296rem + 0.658vw, 2.222rem)
--dk-grid-caption-weight
650

description

--dk-grid-description-color
#16181c
--dk-grid-description-size
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)

shell

--dk-grid-shell-bg
#f2f5fb
--dk-grid-shell-fg
#16181c
--dk-grid-shell-border
#95989d
--dk-grid-shell-radius
clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)
--dk-grid-shell-shadow
0 1px 2px rgba(0, 0, 0, 0.04)
--dk-grid-shell-min-width
640px

headerCell

--dk-grid-header-bg
#f2f5fb
--dk-grid-header-fg
#16181c
--dk-grid-header-size
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)
--dk-grid-header-weight
700
--dk-grid-row-block-size
52px
--dk-grid-inline-padding
clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)

sortButton

--dk-grid-sort-fg
#2072e4
--dk-grid-sort-target
44px
--dk-grid-sort-size
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)

bodyRow

--dk-grid-row-bg
transparent
--dk-grid-row-hover-bg
#e5e8ed

cell

--dk-grid-cell-bg
#f2f5fb
--dk-grid-cell-fg
#16181c
--dk-grid-cell-active-bg
#d7e9ff
--dk-grid-cell-active-fg
#000f4d
--dk-grid-cell-size
clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)
--dk-grid-cell-target
44px

checkbox

--dk-grid-checkbox-target
44px

empty

--dk-grid-empty-fg
#16181c
--dk-grid-empty-title-size
clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)

Implementation notes

  • DataGridLite does not provide cell editing, column resizing, or virtualization.

Examples

Starter

Cell-focused data review

A keyboard-friendly grid for structured review work.

<DataGridLite columns={columns} rows={rows} caption="Release grid" sortable={true} />

Common patterns

Pinned leading column

Keep the identity column visible while moving through wider data.

<DataGridLite columns={columns} rows={rows} pinnedColumns={1} selectable={true} />

Edge cases

Controlled active cell

Control the active cell when the broader app coordinates keyboard focus or companion panels.

<DataGridLite columns={columns} rows={rows} activeCell={activeCell} onActiveCellChange={(detail) => activeCell = detail.activeCell} />

Mathematical fixtures

Calculated fixtures; browser evidence is not collected. Layout estimates use declared text behavior and maximum token values.

default-md

pass

size=md

  • Evidence: mathematical
  • Coverage: complete (3 / 3 declared kinds evaluated)
  • Declared: contrast, target, layout
  • Evaluated: contrast, target, layout
  • Contrast: 98.5 Lc, 98.5 Lc
  • Target: 44 px
  • Layout: shell · single-line 0 px single-line estimate; 0 px minimum width
    320 px: pass 480 px: pass 760 px: pass

dense-sm

pass

size=sm

  • Evidence: mathematical
  • Coverage: complete (3 / 3 declared kinds evaluated)
  • Declared: contrast, target, layout
  • Evaluated: contrast, target, layout
  • Contrast: 98.5 Lc, 98.5 Lc
  • Target: 44 px
  • Layout: shell · single-line 0 px single-line estimate; 0 px minimum width
    320 px: pass 480 px: pass 760 px: pass

active-md

pass

size=md

  • Evidence: mathematical
  • Coverage: complete (3 / 3 declared kinds evaluated)
  • Declared: contrast, target, layout
  • Evaluated: contrast, target, layout
  • Contrast: 98.5 Lc, 89.9 Lc
  • Target: 44 px
  • Layout: shell · single-line 0 px single-line estimate; 0 px minimum width
    320 px: pass 480 px: pass 760 px: pass