Skip to content

TGrid interactions, columns, and writes

View as Markdown

TGrid projects the standalone GridActiveRow into the session’s RowsByLevel mapping. Each projection includes the row’s identity and kind-specific properties plus levelId, values, level, and runtime.

Data rows expose a complete typed values object for their level. Phantom, rollup, opening, closing, subtotal, and footer rows expose partial values. Consumers must narrow kind === "data" before treating values as a complete persisted record. levelId narrows the applicable row type in a multi-level definition.

const session = useTGridSession(definition);
const activeRow = useTGridActiveRow(session);
const task =
activeRow?.kind === "data" && activeRow.levelId === "tasks"
? activeRow.values
: null;

useTGridActiveRow(session) returns React state backed by the session subscription. The value changes when the cursor moves, the active row disappears, or its displayed values change. Render a detail region directly from it.

Non-React owners use session.activeRow() and session.subscribeActiveRow(listener). Snapshots preserve identity until active identity or displayed values change.

TGridActiveRow<RowsByLevel> is the exported projection type.

Active-row state describes the current row. Row activation reports each configured semantic command.

import { ROW_PRIMARY_MASTER_DETAIL_WITH_ACTIVATION } from "@sapporta/grid";
const definition = defineTGrid<RowsByLevel>({
rootLevel: "tasks",
interaction: ROW_PRIMARY_MASTER_DETAIL_WITH_ACTIVATION,
levels,
});
<TGrid
session={session}
onRowActivate={({ activeRow, trigger }) => {
if (activeRow.kind === "data" && activeRow.levelId === "tasks") {
navigate(`/tasks/${activeRow.values.id}/edit`);
}
}}
/>;

TGrid accepts onRowActivate. Non-React or shared session owners use session.onRowActivate(handler). Each event contains the typed activeRow and the normalized keyboard or pointer trigger. Repeated activation of the same row produces repeated events.

TGridRowActivatedEvent<RowsByLevel> is the exported event type.

The TGrid definition owns the interaction configuration. The callback does not enable gestures by itself. ROW_PRIMARY_MASTER_DETAIL_WITH_ACTIVATION enables Enter and double-click, reserves Enter for activation, and retains left/right hierarchy expansion. Custom configurations use activeRow.activation.startsOn.

SchemaTableGridView accepts an interaction configuration but does not expose active-row state or activation callbacks as props. Use useSchemaTableGrid(), then render TGrid with the returned session inside the application layout.

  • The table adapter composes ColumnSchema.kind with ColumnPreset draft parsers at cell commit.
  • Numeric drafts become finite numbers. Clearing a non-text cell becomes an explicit null. An untouched field remains absent from the patch. Empty text remains "".
  • Invalid editor text remains available to the editor and reaches the authoritative server validation boundary.
  • Select-backed columns preserve exact option identity, and render their value as plain text.
  • date and timestamp are separate presets, chosen from the column’s declared kind. A date cell renders 2026-08-23; a timestamp cell renders 2026-08-23 16:38 in the active workspace’s time zone and describes the full moment on hover.
  • The timestamp preset offers no date-picker editor. An <input type="date"> has nowhere to put the time component and would drop it on commit.
  • Cell renderers, activations, editors, copy handlers, and write handlers receive a path-bound GridLevelRuntime as context.level.
  • context.runtime contains grid-wide schema, events, registered levels, active-row state, and cross-path row operations.

Direct GridCore and ColumnPreset contracts live in the standalone Grid Reference.