Skip to content

Editable grid

import { Aside } from ‘@astrojs/starlight/components’;

A brand-themed, editable spreadsheet grid for your artifact. Access via sdk.grid(name, options).

Renders a live table users can edit in place — backed by a ShareOut table (default) or a connected Google Sheet. Link the SDK + stylesheet, call render() — no grid markup or custom styling required.

<script src="https://shareout.site/sdk/shareout.js"></script>
<link rel="stylesheet" href="https://shareout.site/sdk/shareout.css">
<div id="app"></div>
<script>
const sdk = await ShareOut.create();
await sdk.grid('inventory', { editable: true }).render('#app');
</script>

Cell edits, new rows, and deletes persist to the inventory table automatically.

sdk.grid(name: string, options?: {
source?: 'table' | 'sheets'; // default 'table'
columns?: GridColumn[]; // optional; inferred from rows when omitted
editable?: boolean; // default true
pageSize?: number; // default 100
height?: string; // e.g. '420px'
// Sheets source only:
spreadsheetId?: string;
spreadsheetUrl?: string;
range?: string; // e.g. 'A1:F'
sheetName?: string;
}): Grid
interface GridColumn {
field: string;
title: string;
type: 'text' | 'number' | 'boolean' | 'date';
editable?: boolean;
}
// Mount the editable UI (lazy-loads the grid bundle on first call)
render(target: string | HTMLElement): Promise<GridController>
// Data API — usable without rendering a UI
load(range?: { offset?: number; limit?: number }): Promise<{ rows; columns; hasMore }>
setCell(rowId: string, field: string, value: unknown): Promise<void>
addRow(data?: Record<string, unknown>): Promise<GridRow>
deleteRow(rowId: string): Promise<void>
exportCsv(): Promise<string>
// Tear down a mounted grid
destroy(): void

render() returns a controller: { table, addRow(data?), destroy() } (table is the underlying Tabulator instance for advanced use).

Backed by sdk.table(name) — durable, queryable, up to 100k rows. A grid and your other table code share the same storage.

const grid = sdk.grid('tasks', {
columns: [
{ field: 'title', title: 'Task', type: 'text' },
{ field: 'done', title: 'Done', type: 'boolean' },
{ field: 'due', title: 'Due', type: 'date' },
],
});
await grid.render('#app');

Omit columns to infer them from the first page of rows (id, createdAt, updatedAt are hidden).

Display and edit a connected Google Sheet inside your artifact. Reuses the Sheets connector — see Google Sheets for setup.

const grid = sdk.grid('sales', {
source: 'sheets',
spreadsheetId: '1AbC...',
range: 'A1:F',
});
if (!(await sdk.sheets.isConnected())) {
await sdk.sheets.authorize();
}
await grid.render('#app');
  • Reads via sdk.sheets.fetch (header row → columns). Cell edits write back to the exact A1 cell via sdk.sheets.update; new rows via append.
  • Write-back is direct, last-writer-wins — there is no diff/merge sync engine.
  • The first sheet row is treated as the header; data starts at row 2.

The grid maps to ShareOut design tokens (--so-*) automatically. Link shareout.css so the tokens are defined.

  • No formula engine, multi-sheet tabs, or pivots.
  • No live multi-cursor collaboration yet.
  • Table source paginates (1000 rows/query, 100k/table) — large grids load by page.