Row data
Row data is whatever you pass to <SvGrid data={...}>. It is a
ReadonlyArray<TData> where TData is your row type. Any shape works;
the grid does not require a base class or interface.
Static
<script lang="ts">
const rows = [
{ id: '1', name: 'Ada', age: 36 },
{ id: '2', name: 'Linus', age: 54 },
]
</script>
<SvGrid data={rows} {columns} features={{}} />
Reactive
Use a Svelte 5 $state array. The grid re-derives its row model whenever
the array reference changes:
<script lang="ts">
let rows = $state<Person[]>([])
$effect(() => { fetchPeople().then((next) => (rows = next)) })
</script>
<SvGrid data={rows} {columns} features={{}} />
In-place mutation works too - rows.push(x) or rows[i] = y - because
$state arrays are deep-reactive.
Row identity (getRowId)
Without getRowId, the grid uses each row's array index as its id.
That's fine for static data, but selection / expansion / edit state
won't survive sorts, filters, or insertions.
For anything beyond a read-only grid, pass getRowId:
<SvGrid
data={rows}
{columns}
features={features}
getRowId={(row, index) => row.id}
/>
The function fires per row at row-model build time. Return any stable
string - a database PK, a UUID, a slug. The same id then flows into
onRowSelectionChange, onCellValueChange, api.getCellValue(...),
and every other API surface that takes a row id.
Available on both the <SvGrid> wrapper and the headless
createSvGrid({ getRowId }) core.
Empty state
The grid renders the emptyMessage prop when data.length === 0:
<SvGrid data={[]} {columns} features={{}} emptyMessage="No people found." />
Loading state
Pass loading to overlay a spinner / skeleton (the wrapper has a built-in
overlay layer):
<SvGrid {data} {columns} features={{}} loading={isFetching} />
For controlled skeleton-row UX in virtualized server-side grids, see demos/09-server-side.svelte.