@toolbox-web/grid-angular 0.0.1 → 0.1.2

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.
package/README.md ADDED
@@ -0,0 +1,440 @@
1
+ # @toolbox-web/grid-angular
2
+
3
+ [![npm](https://img.shields.io/npm/v/@toolbox-web/grid-angular.svg)](https://www.npmjs.com/package/@toolbox-web/grid-angular)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](../../LICENSE)
5
+ [![GitHub Sponsors](https://img.shields.io/badge/Sponsor-❤-ea4aaa?logo=github)](https://github.com/sponsors/OysteinAmundsen)
6
+
7
+ Angular adapter for `@toolbox-web/grid` data grid component. Provides directives for declarative template-driven cell renderers and editors.
8
+
9
+ ## Features
10
+
11
+ - ✅ **Auto-adapter registration** - Just import `Grid` directive
12
+ - ✅ **Structural directives** - Clean `*tbwRenderer` and `*tbwEditor` syntax
13
+ - ✅ **Template-driven renderers** - Use `<ng-template>` for custom cell views
14
+ - ✅ **Template-driven editors** - Use `<ng-template>` for custom cell editors
15
+ - ✅ **Auto-wiring** - Editor components just emit events, no manual binding needed
16
+ - ✅ **Full type safety** - Typed template contexts (`GridCellContext`, `GridEditorContext`)
17
+ - ✅ **Angular 17+** - Standalone components, signals support
18
+ - ✅ **AOT compatible** - Works with Angular's ahead-of-time compilation
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ # npm
24
+ npm install @toolbox-web/grid @toolbox-web/grid-angular
25
+
26
+ # yarn
27
+ yarn add @toolbox-web/grid @toolbox-web/grid-angular
28
+
29
+ # pnpm
30
+ pnpm add @toolbox-web/grid @toolbox-web/grid-angular
31
+
32
+ # bun
33
+ bun add @toolbox-web/grid @toolbox-web/grid-angular
34
+ ```
35
+
36
+ ## Quick Start
37
+
38
+ ### 1. Register the Grid Component
39
+
40
+ In your Angular application, import the grid registration:
41
+
42
+ ```typescript
43
+ // main.ts or app.config.ts
44
+ import '@toolbox-web/grid';
45
+ ```
46
+
47
+ ### 2. Use in Components
48
+
49
+ ```typescript
50
+ import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
51
+ import { Grid } from '@toolbox-web/grid-angular';
52
+
53
+ @Component({
54
+ selector: 'app-my-grid',
55
+ imports: [Grid],
56
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
57
+ template: ` <tbw-grid [rows]="rows" [gridConfig]="config" style="height: 400px; display: block;"> </tbw-grid> `,
58
+ })
59
+ export class MyGridComponent {
60
+ rows = [
61
+ { id: 1, name: 'Alice', status: 'active' },
62
+ { id: 2, name: 'Bob', status: 'inactive' },
63
+ ];
64
+
65
+ config = {
66
+ columns: [
67
+ { field: 'id', header: 'ID', type: 'number' },
68
+ { field: 'name', header: 'Name' },
69
+ { field: 'status', header: 'Status' },
70
+ ],
71
+ };
72
+ }
73
+ ```
74
+
75
+ ## Structural Directives (Recommended)
76
+
77
+ The cleanest way to define custom renderers and editors is with structural directives. These provide a concise syntax without the boilerplate of nested `<ng-template>` elements.
78
+
79
+ ### TbwRenderer
80
+
81
+ Use `*tbwRenderer` to customize how cell values are displayed:
82
+
83
+ ```typescript
84
+ import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
85
+ import { Grid, TbwRenderer } from '@toolbox-web/grid-angular';
86
+
87
+ @Component({
88
+ imports: [Grid, TbwRenderer, StatusBadgeComponent],
89
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
90
+ template: `
91
+ <tbw-grid [rows]="rows" [gridConfig]="config">
92
+ <tbw-grid-column field="status">
93
+ <app-status-badge *tbwRenderer="let value" [value]="value" />
94
+ </tbw-grid-column>
95
+ </tbw-grid>
96
+ `,
97
+ })
98
+ export class MyGridComponent {}
99
+ ```
100
+
101
+ **Template Context:**
102
+
103
+ | Variable | Type | Description |
104
+ | ----------- | --------- | ------------------------------------- |
105
+ | `$implicit` | `TValue` | The cell value (use with `let-value`) |
106
+ | `row` | `TRow` | The full row data object |
107
+ | `column` | `unknown` | The column configuration |
108
+
109
+ ### TbwEditor
110
+
111
+ Use `*tbwEditor` for custom cell editors. The adapter automatically listens for `commit` and `cancel` events from your component, so you don't need to manually wire up callbacks:
112
+
113
+ ```typescript
114
+ import { Component, CUSTOM_ELEMENTS_SCHEMA, output } from '@angular/core';
115
+ import { Grid, TbwRenderer, TbwEditor } from '@toolbox-web/grid-angular';
116
+
117
+ // Your editor component just needs to emit 'commit' and 'cancel' events
118
+ @Component({
119
+ selector: 'app-status-editor',
120
+ template: `
121
+ <select [value]="value()" (change)="commit.emit($any($event.target).value)">
122
+ <option value="active">Active</option>
123
+ <option value="inactive">Inactive</option>
124
+ </select>
125
+ `,
126
+ })
127
+ export class StatusEditorComponent {
128
+ value = input<string>();
129
+ commit = output<string>();
130
+ cancel = output<void>();
131
+ }
132
+
133
+ @Component({
134
+ imports: [Grid, TbwRenderer, TbwEditor, StatusBadgeComponent, StatusEditorComponent],
135
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
136
+ template: `
137
+ <tbw-grid [rows]="rows" [gridConfig]="config">
138
+ <tbw-grid-column field="status" editable>
139
+ <app-status-badge *tbwRenderer="let value" [value]="value" />
140
+ <app-status-editor *tbwEditor="let value" [value]="value" />
141
+ </tbw-grid-column>
142
+ </tbw-grid>
143
+ `,
144
+ })
145
+ export class MyGridComponent {}
146
+ ```
147
+
148
+ **Template Context:**
149
+
150
+ | Variable | Type | Description |
151
+ | ----------- | ---------- | -------------------------------------------- |
152
+ | `$implicit` | `TValue` | The cell value (use with `let-value`) |
153
+ | `row` | `TRow` | The full row data object |
154
+ | `column` | `unknown` | The column configuration |
155
+ | `onCommit` | `Function` | Callback to commit (optional with auto-wire) |
156
+ | `onCancel` | `Function` | Callback to cancel (optional with auto-wire) |
157
+
158
+ > **Auto-wiring:** If your editor component emits a `commit` event with the new value, the adapter automatically calls the grid's commit function. Similarly for `cancel`. This means you can skip the explicit `onCommit`/`onCancel` bindings!
159
+
160
+ ## Nested Directive Syntax (Alternative)
161
+
162
+ For more explicit control, you can use the nested directive syntax with `<ng-template>`:
163
+
164
+ ### GridColumnView
165
+
166
+ ```typescript
167
+ import { Grid, GridColumnView } from '@toolbox-web/grid-angular';
168
+
169
+ @Component({
170
+ imports: [Grid, GridColumnView],
171
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
172
+ template: `
173
+ <tbw-grid [rows]="rows" [gridConfig]="config">
174
+ <tbw-grid-column field="status">
175
+ <tbw-grid-column-view>
176
+ <ng-template let-value let-row="row">
177
+ <span [class]="'badge badge--' + value">{{ value }}</span>
178
+ </ng-template>
179
+ </tbw-grid-column-view>
180
+ </tbw-grid-column>
181
+ </tbw-grid>
182
+ `
183
+ })
184
+ ```
185
+
186
+ ### GridColumnEditor
187
+
188
+ ```typescript
189
+ import { Grid, GridColumnView, GridColumnEditor } from '@toolbox-web/grid-angular';
190
+
191
+ @Component({
192
+ imports: [Grid, GridColumnView, GridColumnEditor],
193
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
194
+ template: `
195
+ <tbw-grid [rows]="rows" [gridConfig]="config">
196
+ <tbw-grid-column field="status" editable>
197
+ <tbw-grid-column-view>
198
+ <ng-template let-value>
199
+ <span [class]="'badge badge--' + value">{{ value }}</span>
200
+ </ng-template>
201
+ </tbw-grid-column-view>
202
+ <tbw-grid-column-editor>
203
+ <ng-template let-value let-commit="commit" let-cancel="cancel">
204
+ <select [value]="value" (change)="commit.emit($any($event.target).value)">
205
+ <option value="active">Active</option>
206
+ <option value="inactive">Inactive</option>
207
+ </select>
208
+ </ng-template>
209
+ </tbw-grid-column-editor>
210
+ </tbw-grid-column>
211
+ </tbw-grid>
212
+ `
213
+ })
214
+ ```
215
+
216
+ ## Grid-Level Events
217
+
218
+ The `Grid` directive provides convenient outputs for common grid events:
219
+
220
+ ```typescript
221
+ import { Grid, CellCommitEvent, RowCommitEvent } from '@toolbox-web/grid-angular';
222
+
223
+ @Component({
224
+ imports: [Grid],
225
+ template: `
226
+ <tbw-grid
227
+ [rows]="rows"
228
+ [gridConfig]="config"
229
+ (cellCommit)="onCellCommit($event)"
230
+ (rowCommit)="onRowCommit($event)"
231
+ />
232
+ `,
233
+ })
234
+ export class MyGridComponent {
235
+ onCellCommit(event: CellCommitEvent<Employee>) {
236
+ console.log('Cell edited:', event.field, event.oldValue, '→', event.newValue);
237
+ }
238
+
239
+ onRowCommit(event: RowCommitEvent<Employee>) {
240
+ console.log('Row saved:', event.rowIndex, event.row);
241
+ }
242
+ }
243
+ ```
244
+
245
+ ## Master-Detail Panels
246
+
247
+ Use `GridDetailView` for expandable row details:
248
+
249
+ ```typescript
250
+ import { Grid, GridDetailView } from '@toolbox-web/grid-angular';
251
+ import { MasterDetailPlugin } from '@toolbox-web/grid/all';
252
+
253
+ @Component({
254
+ imports: [Grid, GridDetailView, DetailPanelComponent],
255
+ template: `
256
+ <tbw-grid [rows]="rows" [gridConfig]="config">
257
+ <tbw-grid-detail showExpandColumn animation="slide">
258
+ <ng-template let-row>
259
+ <app-detail-panel [employee]="row" />
260
+ </ng-template>
261
+ </tbw-grid-detail>
262
+ </tbw-grid>
263
+ `,
264
+ })
265
+ export class MyGridComponent {
266
+ config = {
267
+ plugins: [new MasterDetailPlugin()],
268
+ // ... columns
269
+ };
270
+ }
271
+ ```
272
+
273
+ ## Custom Tool Panels
274
+
275
+ Add custom sidebar panels with `GridToolPanel`:
276
+
277
+ ```typescript
278
+ import { Grid, GridToolPanel } from '@toolbox-web/grid-angular';
279
+
280
+ @Component({
281
+ imports: [Grid, GridToolPanel, QuickFiltersPanelComponent],
282
+ template: `
283
+ <tbw-grid [rows]="rows" [gridConfig]="config">
284
+ <tbw-grid-tool-panel
285
+ id="filters"
286
+ title="Quick Filters"
287
+ icon="🔍"
288
+ tooltip="Filter the data"
289
+ [order]="10"
290
+ >
291
+ <ng-template let-grid>
292
+ <app-quick-filters [grid]="grid" />
293
+ </ng-template>
294
+ </tbw-grid-tool-panel>
295
+ </tbw-grid>
296
+ `,
297
+ })
298
+ ```
299
+
300
+ ## Using Plugins
301
+
302
+ Import plugins individually for smaller bundles:
303
+
304
+ ```typescript
305
+ import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
306
+ import { Grid } from '@toolbox-web/grid-angular';
307
+ import { SelectionPlugin } from '@toolbox-web/grid/plugins/selection';
308
+ import { FilteringPlugin } from '@toolbox-web/grid/plugins/filtering';
309
+
310
+ @Component({
311
+ imports: [Grid],
312
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
313
+ template: `<tbw-grid [rows]="rows" [gridConfig]="config" />`,
314
+ })
315
+ export class MyGridComponent {
316
+ config = {
317
+ columns: [...],
318
+ plugins: [
319
+ new SelectionPlugin({ mode: 'row' }),
320
+ new FilteringPlugin({ debounceMs: 200 }),
321
+ ],
322
+ };
323
+ }
324
+ ```
325
+
326
+ Or import all plugins at once (larger bundle, but convenient):
327
+
328
+ ```typescript
329
+ import { SelectionPlugin, FilteringPlugin } from '@toolbox-web/grid/all';
330
+ ```
331
+
332
+ ## API Reference
333
+
334
+ ### Exported Directives
335
+
336
+ | Directive | Selector | Description |
337
+ | ------------------ | ------------------------ | -------------------------------------- |
338
+ | `Grid` | `tbw-grid` | Main directive, auto-registers adapter |
339
+ | `TbwRenderer` | `*tbwRenderer` | Structural directive for cell views |
340
+ | `TbwEditor` | `*tbwEditor` | Structural directive for cell editors |
341
+ | `GridColumnView` | `tbw-grid-column-view` | Nested directive for cell views |
342
+ | `GridColumnEditor` | `tbw-grid-column-editor` | Nested directive for cell editors |
343
+ | `GridDetailView` | `tbw-grid-detail` | Master-detail panel template |
344
+ | `GridToolPanel` | `tbw-grid-tool-panel` | Custom sidebar panel |
345
+
346
+ ### Grid Directive Outputs
347
+
348
+ | Output | Type | Description |
349
+ | -------------- | --------------------------------- | -------------------- |
350
+ | `cellCommit` | `EventEmitter<CellCommitEvent>` | Cell value committed |
351
+ | `rowCommit` | `EventEmitter<RowCommitEvent>` | Row edit committed |
352
+ | `sortChange` | `EventEmitter<SortChangeEvent>` | Sort state changed |
353
+ | `columnResize` | `EventEmitter<ColumnResizeEvent>` | Column resized |
354
+
355
+ ### GridDetailView Inputs
356
+
357
+ | Input | Type | Default | Description |
358
+ | ------------------ | ---------------------------- | --------- | ----------------------------------- |
359
+ | `showExpandColumn` | `boolean` | `true` | Show expand/collapse chevron column |
360
+ | `animation` | `'slide' \| 'fade' \| false` | `'slide'` | Animation style for expand/collapse |
361
+
362
+ ### GridToolPanel Inputs
363
+
364
+ | Input | Type | Default | Description |
365
+ | --------- | -------- | -------- | --------------------------------- |
366
+ | `id` | `string` | Required | Unique panel identifier |
367
+ | `title` | `string` | Required | Panel title in accordion header |
368
+ | `icon` | `string` | - | Icon for the accordion header |
369
+ | `tooltip` | `string` | - | Tooltip text for header |
370
+ | `order` | `number` | `100` | Panel sort order (lower = higher) |
371
+
372
+ ### Exported Types
373
+
374
+ ```typescript
375
+ import type {
376
+ GridCellContext,
377
+ GridEditorContext,
378
+ GridDetailContext,
379
+ GridToolPanelContext,
380
+ CellCommitEvent,
381
+ RowCommitEvent,
382
+ StructuralCellContext,
383
+ StructuralEditorContext,
384
+ } from '@toolbox-web/grid-angular';
385
+ ```
386
+
387
+ ### AngularGridAdapter
388
+
389
+ The adapter class is exported for advanced use cases:
390
+
391
+ ```typescript
392
+ import { AngularGridAdapter } from '@toolbox-web/grid-angular';
393
+ ```
394
+
395
+ In most cases, the `Grid` directive handles adapter registration automatically.
396
+
397
+ ## Demo
398
+
399
+ See the full Angular demo at [`demos/employee-management/angular/`](../../demos/employee-management/angular/) which demonstrates:
400
+
401
+ - 15+ plugins with full configuration
402
+ - Custom editors (star rating, date picker, status select, bonus slider)
403
+ - Custom renderers (status badges, rating colors, top performer stars)
404
+ - Structural directives with auto-wiring
405
+ - Signal-based reactivity
406
+ - Shell integration (header, tool panels)
407
+ - Master-detail expandable rows
408
+
409
+ ## Requirements
410
+
411
+ - Angular 17+ (standalone components)
412
+ - `@toolbox-web/grid` >= 0.2.0
413
+
414
+ ## Development
415
+
416
+ ```bash
417
+ # Build the library
418
+ bun nx build grid-angular
419
+
420
+ # Run tests
421
+ bun nx test grid-angular
422
+
423
+ # Lint
424
+ bun nx lint grid-angular
425
+ ```
426
+
427
+ ---
428
+
429
+ ## Support This Project
430
+
431
+ This grid is built and maintained by a single developer in spare time. If it saves you time or money, consider sponsoring to keep development going:
432
+
433
+ [![GitHub Sponsors](https://img.shields.io/badge/Sponsor_on_GitHub-ea4aaa?style=for-the-badge&logo=github)](https://github.com/sponsors/OysteinAmundsen)
434
+ [![Patreon](https://img.shields.io/badge/Support_on_Patreon-f96854?style=for-the-badge&logo=patreon)](https://www.patreon.com/c/OysteinAmundsen)
435
+
436
+ ---
437
+
438
+ ## License
439
+
440
+ MIT
package/index.d.ts CHANGED
@@ -1,3 +1,9 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * @toolbox-web/grid-angular - Angular adapter for @toolbox-web/grid.
4
+ *
5
+ * Provides directives for seamless Angular integration with the grid component.
6
+ */
1
7
  export { AngularGridAdapter } from './lib/angular-grid-adapter';
2
8
  export { GridColumnEditor } from './lib/directives/grid-column-editor.directive';
3
9
  export type { GridEditorContext } from './lib/directives/grid-column-editor.directive';
@@ -8,4 +14,8 @@ export type { GridDetailContext } from './lib/directives/grid-detail-view.direct
8
14
  export { GridToolPanel } from './lib/directives/grid-tool-panel.directive';
9
15
  export type { GridToolPanelContext } from './lib/directives/grid-tool-panel.directive';
10
16
  export { Grid } from './lib/directives/grid.directive';
17
+ export type { CellCommitEvent, RowCommitEvent } from './lib/directives/grid.directive';
18
+ export { TbwEditor, TbwRenderer } from './lib/directives/structural-directives';
19
+ export type { StructuralCellContext, StructuralEditorContext } from './lib/directives/structural-directives';
20
+ export { TbwEditor as TbwCellEditor, TbwRenderer as TbwCellView } from './lib/directives/structural-directives';
11
21
  //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../libs/grid-angular/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+CAA+C,CAAC;AACjF,YAAY,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AACvF,OAAO,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAC7E,YAAY,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAC7E,YAAY,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAC;AAC3E,YAAY,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../libs/grid-angular/src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+CAA+C,CAAC;AACjF,YAAY,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AACvF,OAAO,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAC7E,YAAY,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAC7E,YAAY,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,4CAA4C,CAAC;AAC3E,YAAY,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAGvF,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAChF,YAAY,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAG7G,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,WAAW,IAAI,WAAW,EAAE,MAAM,wCAAwC,CAAC"}