components / datagridlite

DataGridLite

Grid-semantics data surface with cell focus, pinned leading columns, and shared sorting/selection behavior with Table.

Overview

What it is

This section explains the intent of the component before the implementation details.

  • DataGridLite is the keyboard-first sibling to Table when the interaction model needs cell-level focus rather than row-level scanning alone.
  • It shares much of the row and column model with Table while adopting grid semantics and active-cell movement.

Aliases

grid, cell navigation table

Decision guide

How to choose it

Use these notes to decide quickly whether this is the right DK component for the job.

Decision guide

  • Choose DataGridLite when the interaction should feel deliberate, documented, and reusable across product surfaces.
  • If the scenario is more specialized than the current DataGridLite contract, prefer a simpler component or build a dedicated workflow on top of the lower-level DK primitives.

Do

  • Keep the DataGridLite label, value, or status language direct enough to scan quickly.
  • Use the documented size and state recipes instead of inventing one-off variants in product code.

Do not

  • Do not hide the main purpose of DataGridLite behind decorative copy or overloaded surface treatments.
  • Do not stretch DataGridLite into a workflow it was not designed to handle just because the visuals are close.

Usage

When to use

Prefer these situations when choosing this component.

  • 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.

Usage

When not to use

These patterns are better served by a different component or a simpler surface.

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

Anti-patterns

  • Using DataGridLite as a generic layout container instead of a purpose-built interaction or content surface.
  • Forking the documented recipe in product code instead of extending the shared DK contract.

Migration notes

  • Migrate legacy datagridlite usage by mapping existing variants and states onto the documented DK props before porting any custom styling.
  • Treat the docs examples as the reference contract for accessibility and event behavior during adoption.

Anatomy

Structural parts

The anatomy explains which pieces matter to the recipe and accessibility model.

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.

API

Public interface

The docs contract distinguishes props, DOM events, and slots so integration behavior is explicit.

Props

NameTypeDefaultDescription
columnsTableColumn[]Column definitions shared with the broader table model.
rowsTableRow[]Grid rows, each with a stable id.
captionstringVisible grid caption.
descriptionstringSupporting 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.
sortBystringControlled active sort key.
sortDirection'asc' | 'desc''asc'Controlled sort direction.
selectedRowIdsstring[]Controlled selected row ids.
onActiveCellChange(detail: { activeCell: { row: number; col: number } }) => voidCallback fired when the focused cell changes.
onSortChange(detail: { sortBy: string; sortDirection: "asc" | "desc" }) => voidCallback fired when sorting changes.
onSelectionChange(detail: { ids: string[] }) => voidCallback fired when row selection changes.
themeThemeContractOverrides the compiled DK theme used to resolve tokens and recipes for this component.

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 in v1 and does not expose custom cell slots.

Recipes

Variants, sizes, and states

These notes summarize the intended recipe surface rather than exposing raw implementation detail first.

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: Cell currently focused
  • selected: Row currently selected
  • sorted: Column sort active

Accessibility

Accessibility contract

This is the behavior the component promises to assistive tech and keyboard users today.

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 the visible label or title still produces a clear accessible name.
  • Verify focus remains obvious in every supported state and size.
  • Verify disabled, selected, and error states do not rely on color alone.

Implementation

Tokens and slot vars

This section shows the representative compiled slot variables that the runtime consumes for the selected design system.

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 is intentionally not a spreadsheet. Use it when cell navigation matters but the workflow still fits a bounded product grid.

Implementation checklist

  • Use the public component API first and only drop to lower-level primitives when the component contract genuinely does not fit.
  • Keep theme overrides token-driven so proofs and recipes stay meaningful.
  • Verify the shipped examples and proof fixtures still represent the real product scenario you are implementing.

Examples

Copy-paste examples

Each example is intentionally practical, grouped by starter, common pattern, and edge-case coverage.

Examples
3
Depth
expanded

Starter

1 example

starter

Starter: cell-focused data review

A keyboard-friendly grid for structured review work.

Copy snippet

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

Common patterns

1 example

common

Common: pinned leading column

Keep the identity column visible while moving through wider data.

Copy snippet

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

Edge cases

1 example

edge

Edge: controlled active cell

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

Copy snippet

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

Verification

Curated proof fixtures

Proofs stay visible in the docs so the system shows what it can guarantee, not just what it can render.

default-md

pass

size=md

  • Contrast: 98.5 Lc, 98.5 Lc
  • Target: 44px
  • Layout: 0 / 320, 480, 760

dense-sm

pass

size=sm

  • Contrast: 98.5 Lc, 98.5 Lc
  • Target: 44px
  • Layout: 0 / 320, 480, 760

active-md

pass

size=md

  • Contrast: 98.5 Lc, 89.9 Lc
  • Target: 44px
  • Layout: 0 / 320, 480, 760