@alaarab/ogrid-mcp 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +68 -0
  2. package/bundled-docs/api/README.md +94 -0
  3. package/bundled-docs/api/column-def.mdx +379 -0
  4. package/bundled-docs/api/components-column-chooser.mdx +310 -0
  5. package/bundled-docs/api/components-column-header-filter.mdx +363 -0
  6. package/bundled-docs/api/components-datagrid-table.mdx +316 -0
  7. package/bundled-docs/api/components-pagination-controls.mdx +344 -0
  8. package/bundled-docs/api/components-sidebar.mdx +427 -0
  9. package/bundled-docs/api/components-status-bar.mdx +309 -0
  10. package/bundled-docs/api/grid-api.mdx +299 -0
  11. package/bundled-docs/api/js-api.mdx +198 -0
  12. package/bundled-docs/api/ogrid-props.mdx +244 -0
  13. package/bundled-docs/api/types.mdx +640 -0
  14. package/bundled-docs/features/cell-references.mdx +225 -0
  15. package/bundled-docs/features/column-chooser.mdx +279 -0
  16. package/bundled-docs/features/column-groups.mdx +290 -0
  17. package/bundled-docs/features/column-pinning.mdx +282 -0
  18. package/bundled-docs/features/column-reordering.mdx +359 -0
  19. package/bundled-docs/features/column-types.mdx +181 -0
  20. package/bundled-docs/features/context-menu.mdx +216 -0
  21. package/bundled-docs/features/csv-export.mdx +227 -0
  22. package/bundled-docs/features/editing.mdx +377 -0
  23. package/bundled-docs/features/filtering.mdx +330 -0
  24. package/bundled-docs/features/formulas.mdx +381 -0
  25. package/bundled-docs/features/grid-api.mdx +311 -0
  26. package/bundled-docs/features/keyboard-navigation.mdx +236 -0
  27. package/bundled-docs/features/pagination.mdx +245 -0
  28. package/bundled-docs/features/performance.mdx +433 -0
  29. package/bundled-docs/features/row-selection.mdx +256 -0
  30. package/bundled-docs/features/server-side-data.mdx +291 -0
  31. package/bundled-docs/features/sidebar.mdx +234 -0
  32. package/bundled-docs/features/sorting.mdx +241 -0
  33. package/bundled-docs/features/spreadsheet-selection.mdx +201 -0
  34. package/bundled-docs/features/status-bar.mdx +205 -0
  35. package/bundled-docs/features/toolbar.mdx +284 -0
  36. package/bundled-docs/features/virtual-scrolling.mdx +624 -0
  37. package/bundled-docs/getting-started/installation.mdx +216 -0
  38. package/bundled-docs/getting-started/overview.mdx +151 -0
  39. package/bundled-docs/getting-started/quick-start.mdx +425 -0
  40. package/bundled-docs/getting-started/vanilla-js.mdx +191 -0
  41. package/bundled-docs/guides/accessibility.mdx +550 -0
  42. package/bundled-docs/guides/controlled-vs-uncontrolled.mdx +153 -0
  43. package/bundled-docs/guides/custom-cell-editors.mdx +201 -0
  44. package/bundled-docs/guides/framework-showcase.mdx +200 -0
  45. package/bundled-docs/guides/mcp-live-testing.mdx +291 -0
  46. package/bundled-docs/guides/mcp.mdx +172 -0
  47. package/bundled-docs/guides/migration-from-ag-grid.mdx +223 -0
  48. package/bundled-docs/guides/theming.mdx +211 -0
  49. package/dist/esm/bridge-client.d.ts +87 -0
  50. package/dist/esm/bridge-client.js +162 -0
  51. package/dist/esm/index.js +1060 -0
  52. package/package.json +43 -0
@@ -0,0 +1,425 @@
1
+ ---
2
+ sidebar_position: 3
3
+ title: Quick Start
4
+ description: Build a fully functional data grid in minutes
5
+ ---
6
+
7
+
8
+ # Quick Start
9
+
10
+ Build a sortable, filterable, editable data grid in under 50 lines.
11
+
12
+ ## Install
13
+
14
+ <Tabs groupId="framework">
15
+ <TabItem value="react" label="React" default>
16
+
17
+ <Tabs groupId="react-ui">
18
+ <TabItem value="radix" label="Radix (Default)" default>
19
+
20
+ ```bash
21
+ npm install @alaarab/ogrid-react-radix
22
+ ```
23
+
24
+ </TabItem>
25
+ <TabItem value="fluent" label="Fluent UI">
26
+
27
+ ```bash
28
+ npm install @alaarab/ogrid-react-fluent @fluentui/react-components
29
+ ```
30
+
31
+ </TabItem>
32
+ <TabItem value="material" label="Material UI">
33
+
34
+ ```bash
35
+ npm install @alaarab/ogrid-react-material @mui/material @emotion/react @emotion/styled
36
+ ```
37
+
38
+ </TabItem>
39
+ </Tabs>
40
+
41
+ </TabItem>
42
+ <TabItem value="angular" label="Angular">
43
+
44
+ <Tabs groupId="angular-ui">
45
+ <TabItem value="angular-material" label="Angular Material" default>
46
+
47
+ ```bash
48
+ npm install @alaarab/ogrid-angular-material @angular/material @angular/cdk
49
+ ```
50
+
51
+ </TabItem>
52
+ <TabItem value="angular-primeng" label="PrimeNG">
53
+
54
+ ```bash
55
+ npm install @alaarab/ogrid-angular-primeng primeng
56
+ ```
57
+
58
+ </TabItem>
59
+ </Tabs>
60
+
61
+ </TabItem>
62
+ <TabItem value="vue" label="Vue">
63
+
64
+ <Tabs groupId="vue-ui">
65
+ <TabItem value="vue-vuetify" label="Vuetify" default>
66
+
67
+ ```bash
68
+ npm install @alaarab/ogrid-vue-vuetify vuetify
69
+ ```
70
+
71
+ </TabItem>
72
+ <TabItem value="vue-primevue" label="PrimeVue">
73
+
74
+ ```bash
75
+ npm install @alaarab/ogrid-vue-primevue primevue
76
+ ```
77
+
78
+ </TabItem>
79
+ </Tabs>
80
+
81
+ </TabItem>
82
+ <TabItem value="js" label="Vanilla JS">
83
+
84
+ ```bash
85
+ npm install @alaarab/ogrid-js
86
+ ```
87
+
88
+ </TabItem>
89
+ </Tabs>
90
+
91
+ ## Full Example
92
+
93
+ <Tabs groupId="framework">
94
+ <TabItem value="react" label="React" default>
95
+
96
+ ```tsx
97
+
98
+ interface Employee {
99
+ id: number;
100
+ name: string;
101
+ department: string;
102
+ salary: number;
103
+ }
104
+
105
+ const data: Employee[] = [
106
+ { id: 1, name: 'Alice Johnson', department: 'Engineering', salary: 95000 },
107
+ { id: 2, name: 'Bob Smith', department: 'Marketing', salary: 72000 },
108
+ { id: 3, name: 'Carol Williams', department: 'Engineering', salary: 110000 },
109
+ { id: 4, name: 'David Brown', department: 'Sales', salary: 68000 },
110
+ { id: 5, name: 'Eva Martinez', department: 'Marketing', salary: 78000 },
111
+ ];
112
+
113
+ const columns: IColumnDef<Employee>[] = [
114
+ { columnId: 'name', name: 'Name', sortable: true },
115
+ {
116
+ columnId: 'department',
117
+ name: 'Department',
118
+ sortable: true,
119
+ filterable: { type: 'multiSelect', options: ['Engineering', 'Marketing', 'Sales'] },
120
+ },
121
+ {
122
+ columnId: 'salary',
123
+ name: 'Salary',
124
+ type: 'numeric',
125
+ sortable: true,
126
+ editable: true,
127
+ valueFormatter: (value) =>
128
+ new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value as number),
129
+ },
130
+ ];
131
+
132
+ export default function App() {
133
+ return (
134
+ <OGrid<Employee>
135
+ columns={columns}
136
+ data={data}
137
+ getRowId={(row) => row.id}
138
+ defaultPageSize={10}
139
+ defaultSortBy="name"
140
+ statusBar
141
+ aria-label="Employee directory"
142
+ />
143
+ );
144
+ }
145
+ ```
146
+
147
+ :::tip Switching UI libraries
148
+ The `OGrid` component has the same props across all React UI packages. To switch, just change the import:
149
+
150
+ - **Radix** (lightweight, default): `from '@alaarab/ogrid-react-radix'`
151
+ - **Fluent UI** (Microsoft 365 / SPFx): `from '@alaarab/ogrid-react-fluent'` — wrap in `<FluentProvider>`
152
+ - **Material UI** (MUI v7): `from '@alaarab/ogrid-react-material'` — wrap in `<ThemeProvider>`
153
+ :::
154
+
155
+ </TabItem>
156
+ <TabItem value="angular" label="Angular">
157
+
158
+ ```typescript
159
+
160
+ interface Employee {
161
+ id: number;
162
+ name: string;
163
+ department: string;
164
+ salary: number;
165
+ }
166
+
167
+ @Component({
168
+ standalone: true,
169
+ imports: [OGridComponent],
170
+ template: `<ogrid [props]="gridProps" />`
171
+ })
172
+ export class EmployeeGridComponent {
173
+ private readonly data: Employee[] = [
174
+ { id: 1, name: 'Alice Johnson', department: 'Engineering', salary: 95000 },
175
+ { id: 2, name: 'Bob Smith', department: 'Marketing', salary: 72000 },
176
+ { id: 3, name: 'Carol Williams', department: 'Engineering', salary: 110000 },
177
+ { id: 4, name: 'David Brown', department: 'Sales', salary: 68000 },
178
+ { id: 5, name: 'Eva Martinez', department: 'Marketing', salary: 78000 },
179
+ ];
180
+
181
+ private readonly columns: IColumnDef<Employee>[] = [
182
+ { columnId: 'name', name: 'Name', sortable: true },
183
+ {
184
+ columnId: 'department', name: 'Department', sortable: true,
185
+ filterable: { type: 'multiSelect', options: ['Engineering', 'Marketing', 'Sales'] },
186
+ },
187
+ {
188
+ columnId: 'salary', name: 'Salary', type: 'numeric', sortable: true, editable: true,
189
+ valueFormatter: (value) =>
190
+ new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value as number),
191
+ },
192
+ ];
193
+
194
+ gridProps = {
195
+ columns: this.columns,
196
+ data: this.data,
197
+ getRowId: (row: Employee) => row.id,
198
+ defaultPageSize: 10,
199
+ defaultSortBy: 'name',
200
+ statusBar: true,
201
+ };
202
+ }
203
+ ```
204
+
205
+ :::tip Switching UI libraries
206
+ Same component API across Angular packages. To switch, just change the import:
207
+
208
+ - **Radix (CDK)** (lightweight): `from '@alaarab/ogrid-angular-radix'`
209
+ - **Angular Material**: `from '@alaarab/ogrid-angular-material'`
210
+ - **PrimeNG**: `from '@alaarab/ogrid-angular-primeng'`
211
+
212
+ All components are standalone — no NgModule required.
213
+ :::
214
+
215
+ </TabItem>
216
+ <TabItem value="vue" label="Vue">
217
+
218
+ ```vue
219
+ <script setup lang="ts">
220
+
221
+ interface Employee {
222
+ id: number;
223
+ name: string;
224
+ department: string;
225
+ salary: number;
226
+ }
227
+
228
+ const data: Employee[] = [
229
+ { id: 1, name: 'Alice Johnson', department: 'Engineering', salary: 95000 },
230
+ { id: 2, name: 'Bob Smith', department: 'Marketing', salary: 72000 },
231
+ { id: 3, name: 'Carol Williams', department: 'Engineering', salary: 110000 },
232
+ { id: 4, name: 'David Brown', department: 'Sales', salary: 68000 },
233
+ { id: 5, name: 'Eva Martinez', department: 'Marketing', salary: 78000 },
234
+ ];
235
+
236
+ const columns: IColumnDef<Employee>[] = [
237
+ { columnId: 'name', name: 'Name', sortable: true },
238
+ {
239
+ columnId: 'department', name: 'Department', sortable: true,
240
+ filterable: { type: 'multiSelect', options: ['Engineering', 'Marketing', 'Sales'] },
241
+ },
242
+ {
243
+ columnId: 'salary', name: 'Salary', type: 'numeric', sortable: true, editable: true,
244
+ valueFormatter: (value) =>
245
+ new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value as number),
246
+ },
247
+ ];
248
+
249
+ const gridProps = {
250
+ columns,
251
+ data,
252
+ getRowId: (row: Employee) => row.id,
253
+ defaultPageSize: 10,
254
+ defaultSortBy: 'name',
255
+ statusBar: true,
256
+ };
257
+ </script>
258
+
259
+ <template>
260
+ <OGrid :gridProps="gridProps" />
261
+ </template>
262
+ ```
263
+
264
+ :::tip Switching UI libraries
265
+ Same component API across Vue packages. To switch, just change the import:
266
+
267
+ - **Radix (Headless UI)** (lightweight): `from '@alaarab/ogrid-vue-radix'`
268
+ - **Vuetify**: `from '@alaarab/ogrid-vue-vuetify'` — wrap in `<v-app>` for theming
269
+ - **PrimeVue**: `from '@alaarab/ogrid-vue-primevue'`
270
+ :::
271
+
272
+ </TabItem>
273
+ <TabItem value="js" label="Vanilla JS">
274
+
275
+ ```js
276
+
277
+ const grid = new OGrid(document.getElementById('grid'), {
278
+ columns: [
279
+ { columnId: 'name', name: 'Name', sortable: true },
280
+ {
281
+ columnId: 'department',
282
+ name: 'Department',
283
+ sortable: true,
284
+ filterable: { type: 'multiSelect', options: ['Engineering', 'Marketing', 'Sales'] },
285
+ },
286
+ {
287
+ columnId: 'salary',
288
+ name: 'Salary',
289
+ type: 'numeric',
290
+ sortable: true,
291
+ editable: true,
292
+ valueFormatter: (value) =>
293
+ new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value),
294
+ },
295
+ ],
296
+ data: [
297
+ { id: 1, name: 'Alice Johnson', department: 'Engineering', salary: 95000 },
298
+ { id: 2, name: 'Bob Smith', department: 'Marketing', salary: 72000 },
299
+ { id: 3, name: 'Carol Williams', department: 'Engineering', salary: 110000 },
300
+ { id: 4, name: 'David Brown', department: 'Sales', salary: 68000 },
301
+ { id: 5, name: 'Eva Martinez', department: 'Marketing', salary: 78000 },
302
+ ],
303
+ getRowId: (row) => row.id,
304
+ pageSize: 10,
305
+ editable: true,
306
+ });
307
+ ```
308
+
309
+ :::tip
310
+ The JS package uses a class-based imperative API. See the [Vanilla JS guide](./vanilla-js) for the full API including events, grid methods, and theming.
311
+ :::
312
+
313
+ </TabItem>
314
+ </Tabs>
315
+
316
+ ## What You Get
317
+
318
+ With just this code:
319
+
320
+ - **Sorting** -- click column headers to sort ascending/descending
321
+ - **Filtering** -- click the filter icon on Department to filter by value
322
+ - **Inline editing** -- double-click any salary cell to edit
323
+ - **Numeric formatting** -- `type: 'numeric'` right-aligns; `valueFormatter` displays currency
324
+ - **Pagination, keyboard nav, cell selection, status bar** -- all built in
325
+
326
+ ## Key Concepts
327
+
328
+ | Concept | Description |
329
+ |---------|-------------|
330
+ | `IColumnDef<T>` | Column config. `columnId` matches a key on `T` (or use `valueGetter`). |
331
+ | `getRowId` | Returns a unique `string \| number` per row for selection, editing, and re-rendering. |
332
+ | `layoutMode` | `'fill'` (default) fills container; `'content'` sizes to content. |
333
+
334
+ ## Using the Grid API
335
+
336
+ <Tabs groupId="framework">
337
+ <TabItem value="react" label="React" default>
338
+
339
+ ```tsx
340
+
341
+ function App() {
342
+ const gridRef = useRef<IOGridApi<Employee>>(null);
343
+
344
+ return (
345
+ <>
346
+ <button onClick={() => console.log(gridRef.current?.getColumnState())}>
347
+ Log State
348
+ </button>
349
+ <OGrid<Employee> ref={gridRef} columns={columns} data={data} getRowId={(row) => row.id} />
350
+ </>
351
+ );
352
+ }
353
+ ```
354
+
355
+ </TabItem>
356
+ <TabItem value="angular" label="Angular">
357
+
358
+ ```typescript
359
+
360
+ @Component({
361
+ standalone: true,
362
+ imports: [OGridComponent],
363
+ template: `
364
+ <button (click)="logState()">Log State</button>
365
+ <ogrid [props]="gridProps" />
366
+ `
367
+ })
368
+ export class AppComponent {
369
+ constructor(private gridService: OGridService) {}
370
+
371
+ logState() {
372
+ console.log(this.gridService.getColumnState());
373
+ }
374
+
375
+ gridProps = { columns, data, getRowId: (row: any) => row.id };
376
+ }
377
+ ```
378
+
379
+ </TabItem>
380
+ <TabItem value="vue" label="Vue">
381
+
382
+ ```vue
383
+ <script setup lang="ts">
384
+
385
+ const { getColumnState } = useOGrid({ columns, data, getRowId: (row) => row.id });
386
+
387
+ function logState() {
388
+ console.log(getColumnState());
389
+ }
390
+ </script>
391
+
392
+ <template>
393
+ <button @click="logState">Log State</button>
394
+ <OGrid :gridProps="{ columns, data, getRowId: (row) => row.id }" />
395
+ </template>
396
+ ```
397
+
398
+ </TabItem>
399
+ <TabItem value="js" label="Vanilla JS">
400
+
401
+ ```js
402
+
403
+ const grid = new OGrid(document.getElementById('grid'), {
404
+ columns, data, getRowId: (row) => row.id,
405
+ });
406
+
407
+ // Programmatic control
408
+ const api = grid.getApi();
409
+ console.log(api.getColumnState());
410
+ api.setRowData(newData);
411
+
412
+ // Cleanup
413
+ grid.destroy();
414
+ ```
415
+
416
+ </TabItem>
417
+ </Tabs>
418
+
419
+ ## Next Steps
420
+
421
+ - [Sorting](../features/sorting), [Filtering](../features/filtering), [Editing](../features/editing) -- core features
422
+ - [Grid API](../api/grid-api) -- imperative methods
423
+ - [Column Definitions](../api/column-def) -- all column options
424
+ - [Controlled vs Uncontrolled](../guides/controlled-vs-uncontrolled) -- managing state externally
425
+ - [Server-Side Data](../features/server-side-data) -- connect to REST APIs or GraphQL
@@ -0,0 +1,191 @@
1
+ ---
2
+ sidebar_position: 4
3
+ title: Vanilla JS
4
+ description: Use OGrid without React — pure JavaScript, class-based API
5
+ ---
6
+
7
+
8
+ # Vanilla JS Quick Start
9
+
10
+ OGrid's vanilla JS package provides the same features as the React packages with a class-based, imperative API. No React, no virtual DOM — just a container element and an options object.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ npm install @alaarab/ogrid-js
16
+ ```
17
+
18
+ ## Basic Example
19
+
20
+ ```html
21
+ <div id="grid" style="height: 400px;"></div>
22
+
23
+ <script type="module">
24
+ import { OGrid } from '@alaarab/ogrid-js';
25
+ import '@alaarab/ogrid-js/styles'; // default theme (light + dark mode)
26
+
27
+ const grid = new OGrid(document.getElementById('grid'), {
28
+ columns: [
29
+ { columnId: 'name', name: 'Name', sortable: true },
30
+ { columnId: 'department', name: 'Department', sortable: true },
31
+ {
32
+ columnId: 'salary',
33
+ name: 'Salary',
34
+ type: 'numeric',
35
+ sortable: true,
36
+ editable: true,
37
+ valueFormatter: (v) => `$${Number(v).toLocaleString()}`,
38
+ },
39
+ ],
40
+ data: [
41
+ { id: 1, name: 'Alice Johnson', department: 'Engineering', salary: 95000 },
42
+ { id: 2, name: 'Bob Smith', department: 'Marketing', salary: 72000 },
43
+ { id: 3, name: 'Carol Williams', department: 'Sales', salary: 110000 },
44
+ { id: 4, name: 'David Brown', department: 'Engineering', salary: 68000 },
45
+ { id: 5, name: 'Eva Martinez', department: 'Marketing', salary: 78000 },
46
+ ],
47
+ getRowId: (row) => row.id,
48
+ pageSize: 10,
49
+ editable: true,
50
+ cellSelection: true,
51
+ statusBar: true,
52
+ });
53
+ </script>
54
+ ```
55
+
56
+ ## Live Demo
57
+
58
+ <VanillaJSDemo />
59
+
60
+ ## What You Get
61
+
62
+ With this code you have:
63
+
64
+ - **Sorting** — click column headers
65
+ - **Inline editing** — double-click any salary cell
66
+ - **Cell selection** — click and drag to select ranges
67
+ - **Keyboard navigation** — arrow keys, Tab, Home/End, Ctrl+Arrow
68
+ - **Clipboard** — Ctrl+C/V/X
69
+ - **Undo/redo** — Ctrl+Z/Y
70
+ - **Status bar** — row count and selection aggregations
71
+ - **Pagination** — page controls at the bottom
72
+
73
+ ## Constructor
74
+
75
+ ```js
76
+ const grid = new OGrid(containerElement, options);
77
+ ```
78
+
79
+ | Parameter | Type | Description |
80
+ |-----------|------|-------------|
81
+ | `container` | `HTMLElement` | The DOM element to render into. OGrid fills this element. |
82
+ | `options` | `OGridOptions<T>` | Grid configuration (see below). |
83
+
84
+ ## Key Options
85
+
86
+ | Option | Type | Default | Description |
87
+ |--------|------|---------|-------------|
88
+ | `columns` | `IColumnDef<T>[]` | **required** | Column definitions |
89
+ | `data` | `T[]` | — | Client-side data array |
90
+ | `dataSource` | `IDataSource<T>` | — | Server-side data source (mutually exclusive with `data`) |
91
+ | `getRowId` | `(item: T) => RowId` | **required** | Unique row identifier |
92
+ | `pageSize` | `number` | `20` | Rows per page |
93
+ | `sort` | `{ field, direction }` | — | Initial sort |
94
+ | `filters` | `IFilters` | — | Initial filters |
95
+ | `editable` | `boolean` | `false` | Enable cell editing |
96
+ | `cellSelection` | `boolean` | `false` | Enable spreadsheet-style selection |
97
+ | `rowSelection` | `'single' \| 'multiple'` | — | Row selection mode |
98
+ | `sideBar` | `boolean \| ISideBarDef` | — | Show sidebar (columns + filters panels) |
99
+ | `layoutMode` | `'fill' \| 'content'` | `'fill'` | `'fill'` stretches to container; `'content'` sizes to data |
100
+ | `pinnedColumns` | `Record<string, 'left' \| 'right'>` | — | Pin columns to edges |
101
+
102
+ ## Events
103
+
104
+ Listen for events with `.on()`:
105
+
106
+ ```js
107
+ grid.on('cellValueChanged', (event) => {
108
+ console.log(`Cell ${event.columnId} changed from ${event.oldValue} to ${event.newValue}`);
109
+ });
110
+
111
+ grid.on('sortChange', ({ field, direction }) => {
112
+ console.log(`Sorted by ${field} ${direction}`);
113
+ });
114
+
115
+ grid.on('selectionChange', ({ selectedRows }) => {
116
+ console.log(`${selectedRows.length} rows selected`);
117
+ });
118
+ ```
119
+
120
+ | Event | Payload | Fired when |
121
+ |-------|---------|------------|
122
+ | `cellValueChanged` | `{ item, columnId, oldValue, newValue }` | A cell edit is committed |
123
+ | `sortChange` | `{ field, direction }` | Sort changes |
124
+ | `filterChange` | `{ filters }` | Filters change |
125
+ | `pageChange` | `{ page }` | Page changes |
126
+ | `selectionChange` | `{ selectedRows, selectedRowIds }` | Row selection changes |
127
+
128
+ ## Grid API
129
+
130
+ Access the imperative API via `grid.api`:
131
+
132
+ ```js
133
+ // Update data
134
+ grid.api.setRowData(newData);
135
+
136
+ // Get current state
137
+ const state = grid.api.getColumnState();
138
+
139
+ // Export to CSV
140
+ grid.api.exportToCsv('my-data.csv');
141
+
142
+ // Programmatic sort
143
+ grid.api.setSort('salary', 'desc');
144
+ ```
145
+
146
+ See the full [JS API Reference](../api/js-api) for all methods.
147
+
148
+ ## Theming
149
+
150
+ The default theme uses CSS custom properties. Override them to match your design:
151
+
152
+ ```css
153
+ :root {
154
+ --ogrid-primary: #0066cc; /* buttons, active page */
155
+ --ogrid-selection: #0078d4; /* active cell outline */
156
+ --ogrid-bg: #ffffff; /* background */
157
+ --ogrid-fg: #242424; /* text color */
158
+ --ogrid-border: #e0e0e0; /* borders */
159
+ --ogrid-bg-subtle: #f3f2f1; /* header background */
160
+ --ogrid-bg-hover: #f5f5f5; /* row hover */
161
+ }
162
+ ```
163
+
164
+ For dark mode, set `data-theme="dark"` on a parent element or rely on `prefers-color-scheme`:
165
+
166
+ ```css
167
+ [data-theme='dark'] {
168
+ --ogrid-bg: #1a1a24;
169
+ --ogrid-fg: #e0e0e0;
170
+ --ogrid-border: #333340;
171
+ /* ... */
172
+ }
173
+ ```
174
+
175
+ Or skip the default theme entirely and write your own CSS targeting the `ogrid-*` class names.
176
+
177
+ ## Cleanup
178
+
179
+ Always destroy the grid when you're done:
180
+
181
+ ```js
182
+ grid.destroy();
183
+ ```
184
+
185
+ This removes all DOM elements, event listeners, and ResizeObservers.
186
+
187
+ ## Next Steps
188
+
189
+ - [JS API Reference](../api/js-api) — full method and options reference
190
+ - [Features](../features/sorting) — all grid features work identically in JS
191
+ - [Theming Guide](../guides/theming) — deep dive into CSS customization