Skip to content

@jsvision/datagrid / fromReactiveRows

Function: fromReactiveRows()

fromReactiveRows<T>(read, opts): GridDataSource<T>

Defined in: datagrid/src/data-source.ts:143

Build a reactive, write-through GridDataSource — the twin of fromRows for rows that are a function of other state (e.g. a master grid's focused record).

read supplies the current rows; it is evaluated inside the grid's reactive derivation, so the grid re-derives whenever a signal read touches changes. insert/remove delegate to caller writers that mutate the owning collection, so a structural edit on this source persists there. Omit a writer to make the source read-only for that operation — the grid's insertRow/deleteRows then no-op gracefully (cell edits still work via the in-place version path). complete feeds the footer honesty label (omit ⇒ complete).

The caller contract: read must return stable references into the owned model (not fresh objects each call) for cell edits to persist, and should stay cheap — the grid calls it once per row per re-derivation, so a filtering read over a large set is O(n²) per derivation.

Type Parameters

T

T

Parameters

read

() => readonly T[]

Returns the current rows (evaluated in the grid's reactive scope).

opts

rowKey (required identity), optional insert/remove write-through writers, and an optional complete completeness predicate.

complete?

() => boolean

insert?

(row, at?) => void

remove?

(keys) => void

rowKey

(row) => string | number

Returns

GridDataSource<T>

A reactive write-through GridDataSource.

Example

ts
import { signal } from '@jsvision/ui';
import { fromReactiveRows } from '@jsvision/datagrid';
interface Line { id: number; orderId: number }
const lines = signal<Line[]>([{ id: 1, orderId: 7 }]);
const focusedOrderId = 7;
const source = fromReactiveRows(() => lines().filter((l) => l.orderId === focusedOrderId), {
  rowKey: (l) => l.id,
  insert: (row, at) => { const n = lines().slice(); n.splice(at ?? n.length, 0, row); lines.set(n); },
  remove: (keys) => { const drop = new Set(keys); lines.set(lines().filter((l) => !drop.has(l.id))); },
});