Skip to content

What is @ts-zen/datagrid?

A headless behavior library for building accessible, interactive data grids in React.

The Problem

TanStack Table is excellent at managing data logic: sorting, filtering, grouping, pagination, column visibility. But it doesn't handle user interaction: keyboard navigation, cell selection, inline editing, clipboard operations.

Building these behaviors from scratch means:

  • Implementing W3C ARIA Grid Pattern correctly
  • Managing roving tabindex for keyboard navigation
  • Handling selection with Shift+Click, Ctrl+A, and range extension
  • Coordinating edit mode with focus management
  • Testing with screen readers

The Solution

@ts-zen/datagrid provides the behavior layer. You get:

FeatureWhat it does
FocusArrow key navigation, Tab handling, roving tabindex
SelectionCell, row, range selection with keyboard/mouse modifiers
EditingEnter edit mode, commit/cancel, sync validation
ClipboardCtrl+C/V with proper serialization
AccessibilityARIA attributes, live region announcements

How It Works

Parallel composition, not wrapping.

tsx
import { useTable } from "@tanstack/react-table";
import { useGridBehavior, useCellBehavior } from "@ts-zen/react-datagrid";

function DataGrid({ data, columns }) {
  // TanStack Table handles data
  const table = useTable({ data, columns });

  // @ts-zen handles behavior
  const grid = useGridBehavior({
    rows: table.getRowModel().rows,
    columns: table.getVisibleLeafColumns(),
  });

  return (
    <div {...grid.props}>
      {table.getRowModel().rows.map((row) => (
        <div key={row.id}>
          {row.getVisibleCells().map((cell) => (
            <Cell key={cell.id} grid={grid} cell={cell} />
          ))}
        </div>
      ))}
    </div>
  );
}

function Cell({ grid, cell }) {
  const behavior = useCellBehavior(grid, cell.row.id, cell.column.id);

  return (
    <div {...behavior.props} className={behavior.isFocused ? "ring-2" : ""}>
      {cell.getValue()}
    </div>
  );
}

Both libraries operate on the same data but with orthogonal responsibilities:

  • TanStack Table: "which rows to show and in what order"
  • @ts-zen/datagrid: "how the user interacts with those rows"

Packages

PackageDescription
@ts-zen/datagrid-coreFramework-agnostic state machine. Pure transitions, no React.
@ts-zen/react-datagridReact hooks + Zustand integration. The main package.
@ts-zen/react-datagrid-kitPre-built features: column resize, keyboard presets.

Next Steps

Released under the MIT License.