@toolbox-web/grid 0.0.1 → 0.0.3

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 (2) hide show
  1. package/README.md +479 -0
  2. package/package.json +53 -53
package/README.md ADDED
@@ -0,0 +1,479 @@
1
+ # @toolbox-web/grid
2
+
3
+ A high-performance, framework-agnostic data grid built with pure TypeScript and native Web Components. Zero runtime dependencies.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @toolbox-web/grid
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import '@toolbox-web/grid';
15
+
16
+ const grid = document.createElement('tbw-grid');
17
+ grid.columns = [
18
+ { field: 'name', header: 'Name' },
19
+ { field: 'email', header: 'Email' },
20
+ ];
21
+ grid.rows = data;
22
+ document.body.appendChild(grid);
23
+ ```
24
+
25
+ > [!TIP]
26
+ > For complete examples, see the [Storybook documentation](https://oysteinamundsen.github.io/toolbox/).
27
+
28
+ ---
29
+
30
+ ## Configuration
31
+
32
+ The grid supports multiple configuration methods, all converging into a **single source of truth** (`effectiveConfig`).
33
+
34
+ ### Configuration Methods
35
+
36
+ **1. Via `gridConfig` (recommended for complex setups):**
37
+
38
+ ```typescript
39
+ grid.gridConfig = {
40
+ columns: [{ field: 'name' }, { field: 'age', type: 'number' }],
41
+ fitMode: 'stretch',
42
+ editOn: 'dblclick',
43
+ plugins: [new SelectionPlugin({ mode: 'row' })],
44
+ shell: { header: { title: 'My Data Grid' } },
45
+ };
46
+ ```
47
+
48
+ **2. Via individual properties (convenience for simple cases):**
49
+
50
+ ```typescript
51
+ grid.columns = [{ field: 'name' }, { field: 'age' }];
52
+ grid.fitMode = 'stretch';
53
+ grid.editOn = 'dblclick';
54
+ ```
55
+
56
+ **3. Via Light DOM (declarative HTML):**
57
+
58
+ ```html
59
+ <tbw-grid>
60
+ <tbw-grid-column field="name" header="Name" sortable></tbw-grid-column>
61
+ <tbw-grid-column field="age" header="Age" type="number"></tbw-grid-column>
62
+ <tbw-grid-header title="My Data Grid">
63
+ <tbw-grid-header-content>
64
+ <span>Custom content</span>
65
+ </tbw-grid-header-content>
66
+ </tbw-grid-header>
67
+ </tbw-grid>
68
+ ```
69
+
70
+ ### Precedence
71
+
72
+ When the same property is set via multiple methods, higher precedence wins:
73
+
74
+ 1. Individual props (`fitMode`, `editOn`) - highest
75
+ 2. `columns` prop
76
+ 3. Light DOM elements
77
+ 4. `gridConfig` property - lowest
78
+
79
+ ---
80
+
81
+ ## Features
82
+
83
+ ### Core Capabilities
84
+
85
+ | Feature | Description |
86
+ | ------------------- | --------------------------------------------------------------------------------- |
87
+ | Virtualization | Row and column virtualization for datasets with 100k+ rows |
88
+ | Keyboard Navigation | Full keyboard support including arrow keys, Tab, Enter, Home/End, PageUp/PageDown |
89
+ | Accessibility | ARIA attributes and screen reader support |
90
+ | Theming | CSS custom properties with 4 built-in themes |
91
+ | Column Inference | Automatic column type detection from data |
92
+
93
+ ### Editing
94
+
95
+ | Feature | Description |
96
+ | --------------- | ----------------------------------------------------- |
97
+ | Inline Editing | Cell and row editing modes with configurable triggers |
98
+ | Undo/Redo | Edit history with Ctrl+Z / Ctrl+Y |
99
+ | Clipboard | Copy/paste with configurable delimiters |
100
+ | Change Tracking | Track modified rows with commit/reset lifecycle |
101
+
102
+ ### Data Operations
103
+
104
+ | Feature | Description |
105
+ | ---------------- | ---------------------------------------------------------------------- |
106
+ | Sorting | Single and multi-column sorting |
107
+ | Filtering | Text, number, date, set, and boolean filters |
108
+ | Aggregations | Built-in aggregators (sum, avg, count, min, max) plus custom functions |
109
+ | Row Grouping | Hierarchical grouping with nested aggregations |
110
+ | Tree Data | Nested data structures with expand/collapse |
111
+ | Pivot Tables | Data transformation with row/column groups |
112
+ | Server-Side Data | Lazy loading with block caching |
113
+
114
+ ### Column Features
115
+
116
+ | Feature | Description |
117
+ | ------------- | -------------------------------------------- |
118
+ | Pinning | Sticky columns on left or right edges |
119
+ | Resizing | Drag-to-resize with auto-sizing |
120
+ | Reordering | Drag-and-drop repositioning |
121
+ | Visibility | Show/hide columns programmatically or via UI |
122
+ | Header Groups | Multi-level column headers |
123
+
124
+ ### Selection & Export
125
+
126
+ | Feature | Description |
127
+ | --------------- | ---------------------------------- |
128
+ | Selection Modes | Cell, row, or range selection |
129
+ | Context Menus | Configurable right-click menus |
130
+ | Master/Detail | Expandable detail rows |
131
+ | Export | CSV, Excel (XML), and JSON formats |
132
+
133
+ ---
134
+
135
+ ## API Reference
136
+
137
+ ### Element
138
+
139
+ ```html
140
+ <tbw-grid></tbw-grid>
141
+ ```
142
+
143
+ ### Properties
144
+
145
+ | Property | Type | Description |
146
+ | ------------ | ----------------------- | -------------------------------------------------- |
147
+ | `rows` | `T[]` | Data array |
148
+ | `columns` | `ColumnConfig[]` | Column definitions (→ `gridConfig.columns`) |
149
+ | `gridConfig` | `GridConfig` | Full configuration object (single source of truth) |
150
+ | `fitMode` | `'stretch' \| 'fixed'` | Column sizing behavior (→ `gridConfig.fitMode`) |
151
+ | `editOn` | `'click' \| 'dblclick'` | Edit trigger (→ `gridConfig.editOn`) |
152
+
153
+ ### Methods
154
+
155
+ | Method | Returns | Description |
156
+ | ---------------------------------- | --------------------- | -------------------------------------- |
157
+ | `ready()` | `Promise<void>` | Resolves when fully initialized |
158
+ | `forceLayout()` | `Promise<void>` | Force re-layout |
159
+ | `getConfig()` | `Promise<GridConfig>` | Get effective configuration |
160
+ | `resetChangedRows(silent?)` | `Promise<void>` | Clear change tracking |
161
+ | `beginBulkEdit(rowIndex)` | `Promise<void>` | Start row editing |
162
+ | `commitActiveRowEdit()` | `Promise<void>` | Commit current edit |
163
+ | `setColumnVisible(field, visible)` | `boolean` | Set column visibility |
164
+ | `getAllColumns()` | `ColumnInfo[]` | Get all columns with visibility status |
165
+
166
+ ### Events
167
+
168
+ | Event | Detail | Description |
169
+ | ------------------- | ------------------------ | ------------------------- |
170
+ | `cell-commit` | `CellCommitDetail` | Cell value committed |
171
+ | `row-commit` | `RowCommitDetail` | Row edit committed |
172
+ | `sort-change` | `SortChangeDetail` | Sort state changed |
173
+ | `column-resize` | `ColumnResizeDetail` | Column resized |
174
+ | `column-visibility` | `ColumnVisibilityDetail` | Column visibility changed |
175
+ | `activate-cell` | `ActivateCellDetail` | Cell activated |
176
+
177
+ Import event names from the `DGEvents` constant:
178
+
179
+ ```typescript
180
+ import { DGEvents } from '@toolbox-web/grid';
181
+ grid.addEventListener(DGEvents.CELL_COMMIT, handler);
182
+ ```
183
+
184
+ ---
185
+
186
+ ## Column Configuration
187
+
188
+ ```typescript
189
+ interface ColumnConfig {
190
+ field: string; // Required: property key in row data
191
+ header?: string; // Display label (defaults to field name)
192
+ type?: 'string' | 'number' | 'date' | 'boolean' | 'select';
193
+ width?: number | string; // Pixels, '1fr', or percentage
194
+ sortable?: boolean; // Enable sorting (default: true)
195
+ resizable?: boolean; // Enable resize (default: true)
196
+ editable?: boolean; // Enable editing
197
+ hidden?: boolean; // Initially hidden
198
+ lockVisible?: boolean; // Prevent hiding
199
+ format?: (value: any, row: T) => string;
200
+ }
201
+ ```
202
+
203
+ ### Plugin-Provided Column Properties
204
+
205
+ Some column properties are added via [TypeScript module augmentation](#typescript-module-augmentation) when you import a plugin:
206
+
207
+ | Property | Plugin | Description |
208
+ | ------------- | ----------------- | ------------------------ |
209
+ | `sticky` | `pinnedColumns` | Pin column left or right |
210
+ | `group` | `groupingColumns` | Column header group |
211
+ | `filterable` | `filtering` | Enable column filter |
212
+ | `filterType` | `filtering` | Filter type |
213
+ | `reorderable` | `reorder` | Enable column reordering |
214
+
215
+ See [Storybook](https://your-storybook-url) for complete configuration examples.
216
+
217
+ ---
218
+
219
+ ## Grid Configuration
220
+
221
+ ```typescript
222
+ interface GridConfig {
223
+ columns?: ColumnConfig[];
224
+ fitMode?: 'stretch' | 'fixed';
225
+ editOn?: 'click' | 'dblclick';
226
+ plugins?: BaseGridPlugin[]; // Array of plugin class instances
227
+ }
228
+ ```
229
+
230
+ ### Plugin Configuration Example
231
+
232
+ Plugins are class instances that you import and instantiate with their configuration:
233
+
234
+ ```typescript
235
+ import { GroupingRowsPlugin } from '@toolbox-web/grid/plugins/grouping-rows';
236
+ import { SelectionPlugin } from '@toolbox-web/grid/plugins/selection';
237
+
238
+ grid.gridConfig = {
239
+ plugins: [
240
+ new GroupingRowsPlugin({
241
+ groupOn: (row) => row.category,
242
+ fullWidth: false,
243
+ aggregators: { total: 'sum' },
244
+ }),
245
+ new SelectionPlugin({
246
+ mode: 'row',
247
+ multiple: true,
248
+ }),
249
+ ],
250
+ };
251
+ ```
252
+
253
+ ---
254
+
255
+ ## Theming
256
+
257
+ Apply a built-in theme:
258
+
259
+ ```css
260
+ @import '@toolbox-web/grid/themes/dg-theme-standard.css';
261
+ ```
262
+
263
+ Available themes: `standard`, `contrast`, `vibrant`, `large`
264
+
265
+ ### Custom Theming
266
+
267
+ Override CSS custom properties on `tbw-grid` or a parent element:
268
+
269
+ ```css
270
+ tbw-grid {
271
+ --tbw-color-bg: #ffffff;
272
+ --tbw-color-fg: #1a1a1a;
273
+ --tbw-color-border: #e5e5e5;
274
+ --tbw-color-header-bg: #f5f5f5;
275
+ --tbw-row-height: 32px;
276
+ }
277
+ ```
278
+
279
+ For a complete list of available CSS variables, see [grid.css](./src/lib/core/grid.css).
280
+
281
+ ### Core CSS Variables
282
+
283
+ | Variable | Description |
284
+ | ----------------------- | ---------------------------- |
285
+ | `--tbw-color-bg` | Grid background |
286
+ | `--tbw-color-fg` | Text color |
287
+ | `--tbw-color-fg-muted` | Secondary text color |
288
+ | `--tbw-color-accent` | Accent/primary color |
289
+ | `--tbw-color-border` | Border color |
290
+ | `--tbw-color-header-bg` | Header background |
291
+ | `--tbw-color-header-fg` | Header text color |
292
+ | `--tbw-color-selection` | Selected cell/row background |
293
+ | `--tbw-color-row-hover` | Row hover background |
294
+ | `--tbw-row-height` | Data row height |
295
+ | `--tbw-header-height` | Header row height |
296
+ | `--tbw-font-family` | Font family |
297
+ | `--tbw-font-size` | Base font size |
298
+ | `--tbw-border-radius` | Corner radius |
299
+ | `--tbw-focus-outline` | Focus ring style |
300
+
301
+ ### Plugin CSS Variables
302
+
303
+ Plugins define their own CSS variables following a **layered fallback pattern**:
304
+
305
+ ```
306
+ var(--tbw-{plugin}-{property}, var(--tbw-{global-property}))
307
+ ```
308
+
309
+ This allows you to:
310
+
311
+ 1. Override a specific plugin's style: `--tbw-selection-bg`
312
+ 2. Or let it inherit from the global variable: `--tbw-color-selection`
313
+
314
+ **Example: Customizing the selection plugin**
315
+
316
+ ```css
317
+ tbw-grid {
318
+ /* Override just the selection plugin's background */
319
+ --tbw-selection-bg: #e0f2fe;
320
+
321
+ /* Or change the global selection color (affects all plugins) */
322
+ --tbw-color-selection: #e0f2fe;
323
+ }
324
+ ```
325
+
326
+ **Common plugin variables:**
327
+
328
+ | Plugin | Variables |
329
+ | ------------- | ---------------------------------------------------------- |
330
+ | `selection` | `--tbw-selection-bg`, `--tbw-selection-border` |
331
+ | `filtering` | `--tbw-filtering-panel-bg`, `--tbw-filtering-input-border` |
332
+ | `contextMenu` | `--tbw-context-menu-bg`, `--tbw-context-menu-hover` |
333
+ | `pinnedRows` | `--tbw-pinned-rows-bg`, `--tbw-pinned-rows-border` |
334
+ | `tree` | `--tbw-tree-indent`, `--tbw-tree-toggle-color` |
335
+
336
+ Check each plugin's `styles` property for the full list of customizable variables.
337
+
338
+ ---
339
+
340
+ ## Plugins
341
+
342
+ The grid uses a plugin architecture for optional features. Each plugin has its own documentation:
343
+
344
+ | Plugin | Description | Documentation |
345
+ | --------------------- | ------------------------------ | ----------------------------------------------------------- |
346
+ | Selection | Cell, row, and range selection | [README](./src/lib/plugins/selection/README.md) |
347
+ | Multi-Sort | Multi-column sorting | [README](./src/lib/plugins/multi-sort/README.md) |
348
+ | Filtering | Column filters | [README](./src/lib/plugins/filtering/README.md) |
349
+ | Row Grouping | Row grouping with aggregation | [README](./src/lib/plugins/grouping-rows/README.md) |
350
+ | Column Grouping | Column header groups | [README](./src/lib/plugins/grouping-columns/README.md) |
351
+ | Tree | Tree/hierarchical data | [README](./src/lib/plugins/tree/README.md) |
352
+ | Pivot | Pivot table transformation | [README](./src/lib/plugins/pivot/README.md) |
353
+ | Master-Detail | Expandable detail rows | [README](./src/lib/plugins/master-detail/README.md) |
354
+ | Pinned Columns | Sticky columns | [README](./src/lib/plugins/pinned-columns/README.md) |
355
+ | Reorder | Column drag reordering | [README](./src/lib/plugins/reorder/README.md) |
356
+ | Visibility | Column visibility UI | [README](./src/lib/plugins/visibility/README.md) |
357
+ | Clipboard | Copy/paste | [README](./src/lib/plugins/clipboard/README.md) |
358
+ | Context Menu | Right-click menus | [README](./src/lib/plugins/context-menu/README.md) |
359
+ | Export | CSV/Excel/JSON export | [README](./src/lib/plugins/export/README.md) |
360
+ | Undo/Redo | Edit history | [README](./src/lib/plugins/undo-redo/README.md) |
361
+ | Server-Side | Lazy data loading | [README](./src/lib/plugins/server-side/README.md) |
362
+ | Pinned Rows | Footer aggregations | [README](./src/lib/plugins/pinned-rows/README.md) |
363
+ | Column Virtualization | Horizontal virtualization | [README](./src/lib/plugins/column-virtualization/README.md) |
364
+
365
+ ### Creating Custom Plugins
366
+
367
+ Plugins extend the `BaseGridPlugin` class:
368
+
369
+ ```typescript
370
+ import { BaseGridPlugin } from '@toolbox-web/grid';
371
+
372
+ interface MyPluginConfig {
373
+ myOption?: boolean;
374
+ }
375
+
376
+ export class MyPlugin extends BaseGridPlugin<MyPluginConfig> {
377
+ readonly name = 'myPlugin';
378
+ readonly version = '1.0.0';
379
+
380
+ // CSS injected into shadow DOM
381
+ readonly styles = `
382
+ .my-element { color: red; }
383
+ `;
384
+
385
+ // Default config (override in constructor)
386
+ protected get defaultConfig(): Partial<MyPluginConfig> {
387
+ return { myOption: true };
388
+ }
389
+
390
+ // Called when plugin is attached to grid
391
+ attach(grid: GridElement): void {
392
+ super.attach(grid);
393
+ // Setup event listeners, etc.
394
+ }
395
+
396
+ // Called when plugin is detached
397
+ detach(): void {
398
+ // Cleanup
399
+ }
400
+
401
+ // Hook: Called after grid renders
402
+ afterRender(): void {
403
+ // DOM manipulation
404
+ }
405
+ }
406
+ ```
407
+
408
+ ### Accessing Plugin Instances
409
+
410
+ Use `grid.getPlugin()` to get a plugin instance for inter-plugin communication or API access:
411
+
412
+ ```typescript
413
+ import { SelectionPlugin } from '@toolbox-web/grid/plugins/selection';
414
+
415
+ const selection = grid.getPlugin(SelectionPlugin);
416
+ if (selection) {
417
+ selection.selectAll();
418
+ }
419
+ ```
420
+
421
+ ---
422
+
423
+ ## TypeScript
424
+
425
+ All types are exported from the package:
426
+
427
+ ```typescript
428
+ import type { GridConfig, ColumnConfig, CellCommitDetail, BaseGridPlugin } from '@toolbox-web/grid';
429
+ ```
430
+
431
+ ### Plugin Type Exports
432
+
433
+ Each plugin exports its class and configuration types from its own entry point:
434
+
435
+ ```typescript
436
+ import { SelectionPlugin, SelectionConfig } from '@toolbox-web/grid/plugins/selection';
437
+ import { FilteringPlugin, FilterConfig, FilterModel } from '@toolbox-web/grid/plugins/filtering';
438
+ import { TreePlugin, TreeConfig, TreeState } from '@toolbox-web/grid/plugins/tree';
439
+ ```
440
+
441
+ ### All-in-One Bundle
442
+
443
+ For convenience, you can import everything from the all-in-one bundle:
444
+
445
+ ```typescript
446
+ import {
447
+ SelectionPlugin,
448
+ FilteringPlugin,
449
+ TreePlugin,
450
+ // ... all other plugins
451
+ } from '@toolbox-web/grid/all';
452
+ ```
453
+
454
+ Note: This includes all plugins in your bundle. For smaller bundles, import plugins individually.
455
+
456
+ ---
457
+
458
+ ## Browser Support
459
+
460
+ Modern browsers with Web Components support (Chrome, Firefox, Safari, Edge).
461
+
462
+ ---
463
+
464
+ ## Development
465
+
466
+ ```bash
467
+ bun nx build grid # Build
468
+ bun nx test grid # Test
469
+ bun nx test grid --coverage # Test with coverage
470
+ bun nx storybook storybook-app # Storybook (port 4400)
471
+ ```
472
+
473
+ For architecture details, rendering pipeline, and plugin development, see [ARCHITECTURE.md](./ARCHITECTURE.md).
474
+
475
+ ---
476
+
477
+ ## License
478
+
479
+ MIT
package/package.json CHANGED
@@ -1,53 +1,53 @@
1
- {
2
- "name": "@toolbox-web/grid",
3
- "version": "0.0.1",
4
- "description": "High-performance data grid web component",
5
- "type": "module",
6
- "main": "./index.js",
7
- "module": "./index.js",
8
- "types": "./index.d.ts",
9
- "exports": {
10
- ".": {
11
- "types": "./index.d.ts",
12
- "import": "./index.js"
13
- },
14
- "./all": {
15
- "types": "./all.d.ts",
16
- "import": "./all.js"
17
- },
18
- "./plugins/*": {
19
- "types": "./lib/plugins/*/index.d.ts",
20
- "import": "./lib/plugins/*/index.js"
21
- },
22
- "./themes/*": "./themes/*",
23
- "./umd/*": "./umd/*"
24
- },
25
- "files": [
26
- "**/*.js",
27
- "**/*.d.ts",
28
- "**/*.css",
29
- "**/*.map",
30
- "custom-elements.json"
31
- ],
32
- "sideEffects": [
33
- "*.css"
34
- ],
35
- "keywords": [
36
- "web-component",
37
- "data-grid",
38
- "table",
39
- "virtualization"
40
- ],
41
- "license": "MIT",
42
- "author": "Oystein Amundsen",
43
- "repository": {
44
- "type": "git",
45
- "url": "https://github.com/OysteinAmundsen/toolbox.git",
46
- "directory": "libs/grid"
47
- },
48
- "homepage": "https://github.com/OysteinAmundsen/toolbox/tree/main/libs/grid#readme",
49
- "bugs": {
50
- "url": "https://github.com/OysteinAmundsen/toolbox/issues"
51
- },
52
- "customElements": "custom-elements.json"
53
- }
1
+ {
2
+ "name": "@toolbox-web/grid",
3
+ "version": "0.0.3",
4
+ "description": "High-performance data grid web component",
5
+ "type": "module",
6
+ "main": "./index.js",
7
+ "module": "./index.js",
8
+ "types": "./index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./index.d.ts",
12
+ "import": "./index.js"
13
+ },
14
+ "./all": {
15
+ "types": "./all.d.ts",
16
+ "import": "./all.js"
17
+ },
18
+ "./plugins/*": {
19
+ "types": "./lib/plugins/*/index.d.ts",
20
+ "import": "./lib/plugins/*/index.js"
21
+ },
22
+ "./themes/*": "./themes/*",
23
+ "./umd/*": "./umd/*"
24
+ },
25
+ "files": [
26
+ "**/*.js",
27
+ "**/*.d.ts",
28
+ "**/*.css",
29
+ "**/*.map",
30
+ "custom-elements.json"
31
+ ],
32
+ "sideEffects": [
33
+ "*.css"
34
+ ],
35
+ "keywords": [
36
+ "web-component",
37
+ "data-grid",
38
+ "table",
39
+ "virtualization"
40
+ ],
41
+ "license": "MIT",
42
+ "author": "Oystein Amundsen",
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "https://github.com/OysteinAmundsen/toolbox.git",
46
+ "directory": "libs/grid"
47
+ },
48
+ "homepage": "https://github.com/OysteinAmundsen/toolbox/tree/main/libs/grid#readme",
49
+ "bugs": {
50
+ "url": "https://github.com/OysteinAmundsen/toolbox/issues"
51
+ },
52
+ "customElements": "custom-elements.json"
53
+ }