@toolbox-web/grid-angular 0.2.0 → 0.3.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.
package/README.md CHANGED
@@ -12,6 +12,8 @@ Angular adapter for `@toolbox-web/grid` data grid component. Provides directives
12
12
  - ✅ **Structural directives** - Clean `*tbwRenderer` and `*tbwEditor` syntax
13
13
  - ✅ **Template-driven renderers** - Use `<ng-template>` for custom cell views
14
14
  - ✅ **Template-driven editors** - Use `<ng-template>` for custom cell editors
15
+ - ✅ **Component-class column config** - Specify component classes directly in `gridConfig.columns`
16
+ - ✅ **Type-level defaults** - App-wide renderers/editors via `provideGridTypeDefaults()`
15
17
  - ✅ **Auto-wiring** - Editor components just emit events, no manual binding needed
16
18
  - ✅ **Full type safety** - Typed template contexts (`GridCellContext`, `GridEditorContext`)
17
19
  - ✅ **Angular 17+** - Standalone components, signals support
@@ -297,6 +299,160 @@ import { Grid, GridToolPanel } from '@toolbox-web/grid-angular';
297
299
  })
298
300
  ```
299
301
 
302
+ ## Type-Level Defaults
303
+
304
+ Define app-wide renderers and editors for custom column types using `provideGridTypeDefaults()`:
305
+
306
+ ```typescript
307
+ // app.config.ts
308
+ import { ApplicationConfig } from '@angular/core';
309
+ import { provideGridTypeDefaults } from '@toolbox-web/grid-angular';
310
+ import { CountryBadgeComponent, CountryEditorComponent, CurrencyCellComponent } from './components';
311
+
312
+ export const appConfig: ApplicationConfig = {
313
+ providers: [
314
+ provideGridTypeDefaults({
315
+ country: {
316
+ renderer: CountryBadgeComponent,
317
+ editor: CountryEditorComponent,
318
+ },
319
+ currency: {
320
+ renderer: CurrencyCellComponent,
321
+ },
322
+ }),
323
+ ],
324
+ };
325
+ ```
326
+
327
+ Then any grid with columns using `type: 'country'` will automatically use the registered components:
328
+
329
+ ```typescript
330
+ // my-grid.component.ts
331
+ import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
332
+ import { Grid } from '@toolbox-web/grid-angular';
333
+ import { EditingPlugin } from '@toolbox-web/grid/plugins/editing';
334
+ import type { GridConfig } from '@toolbox-web/grid';
335
+
336
+ @Component({
337
+ imports: [Grid],
338
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
339
+ template: `<tbw-grid [rows]="data" [gridConfig]="config" />`,
340
+ })
341
+ export class MyGridComponent {
342
+ config: GridConfig = {
343
+ columns: [
344
+ { field: 'name', header: 'Name' },
345
+ { field: 'country', type: 'country', editable: true }, // Uses registered components
346
+ { field: 'salary', type: 'currency' },
347
+ ],
348
+ plugins: [new EditingPlugin()],
349
+ };
350
+ }
351
+ ```
352
+
353
+ **Services:**
354
+
355
+ | Service | Description |
356
+ | -------------------- | ------------------------------------------- |
357
+ | `GridTypeRegistry` | Injectable service for dynamic registration |
358
+ | `GRID_TYPE_DEFAULTS` | Injection token for type defaults |
359
+
360
+ ## Component-Class Column Config
361
+
362
+ For maximum flexibility and type safety, you can specify Angular component classes directly in your `gridConfig.columns`. This approach gives you full control over the component lifecycle while keeping your grid configuration clean and concise.
363
+
364
+ ### Component Interfaces
365
+
366
+ Your components should implement one of these interfaces:
367
+
368
+ **Renderer components:**
369
+
370
+ ```typescript
371
+ import { Component, input } from '@angular/core';
372
+ import type { AngularCellRenderer, ColumnConfig } from '@toolbox-web/grid-angular';
373
+
374
+ @Component({
375
+ selector: 'app-status-badge',
376
+ template: `<span [class]="'badge badge--' + value()">{{ value() }}</span>`,
377
+ standalone: true,
378
+ })
379
+ export class StatusBadgeComponent implements AngularCellRenderer<Employee, string> {
380
+ value = input.required<string>();
381
+ row = input.required<Employee>();
382
+ column = input<ColumnConfig>(); // Optional
383
+ }
384
+ ```
385
+
386
+ **Editor components:**
387
+
388
+ ```typescript
389
+ import { Component, input, output } from '@angular/core';
390
+ import type { AngularCellEditor, ColumnConfig } from '@toolbox-web/grid-angular';
391
+
392
+ @Component({
393
+ selector: 'app-bonus-editor',
394
+ template: `
395
+ <input type="range" [min]="0" [max]="maxBonus()" [value]="value()" (input)="onInput($event)" />
396
+ <button (click)="cancel.emit()">Cancel</button>
397
+ `,
398
+ standalone: true,
399
+ })
400
+ export class BonusEditorComponent implements AngularCellEditor<Employee, number> {
401
+ value = input.required<number>();
402
+ row = input.required<Employee>();
403
+ column = input<ColumnConfig>(); // Optional
404
+
405
+ commit = output<number>();
406
+ cancel = output<void>();
407
+
408
+ // Computed property using row data
409
+ maxBonus = computed(() => this.row().salary * 0.5);
410
+
411
+ onInput(event: Event) {
412
+ const newValue = Number((event.target as HTMLInputElement).value);
413
+ this.commit.emit(newValue);
414
+ }
415
+ }
416
+ ```
417
+
418
+ ### Using Components in Grid Config
419
+
420
+ Use `AngularGridConfig` and `angularConfig` input for type-safe component references:
421
+
422
+ ```typescript
423
+ import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
424
+ import { Grid, type AngularGridConfig } from '@toolbox-web/grid-angular';
425
+ import { EditingPlugin } from '@toolbox-web/grid/plugins/editing';
426
+ import { StatusBadgeComponent, BonusEditorComponent } from './components';
427
+
428
+ @Component({
429
+ imports: [Grid],
430
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
431
+ template: `<tbw-grid [angularConfig]="config" [rows]="employees" />`,
432
+ })
433
+ export class MyGridComponent {
434
+ config: AngularGridConfig<Employee> = {
435
+ columns: [
436
+ { field: 'name', header: 'Name' },
437
+ { field: 'status', header: 'Status', renderer: StatusBadgeComponent },
438
+ { field: 'bonus', header: 'Bonus', editable: true, editor: BonusEditorComponent },
439
+ ],
440
+ plugins: [new EditingPlugin()],
441
+ };
442
+ }
443
+ ```
444
+
445
+ > **Note:** Use `[angularConfig]` instead of `[gridConfig]` when using component classes. The directive automatically processes the config and converts component classes to grid-compatible functions.
446
+
447
+ ### Interfaces Reference
448
+
449
+ | Interface | Required Inputs | Required Outputs | Description |
450
+ | --------------------- | ------------------ | ------------------ | ------------------ |
451
+ | `AngularCellRenderer` | `value()`, `row()` | - | Read-only renderer |
452
+ | `AngularCellEditor` | `value()`, `row()` | `commit`, `cancel` | Editable cell |
453
+
454
+ Both interfaces also support an optional `column()` input for accessing the column configuration.
455
+
300
456
  ## Using Plugins
301
457
 
302
458
  Import plugins individually for smaller bundles:
@@ -343,6 +499,21 @@ import { SelectionPlugin, FilteringPlugin } from '@toolbox-web/grid/all';
343
499
  | `GridDetailView` | `tbw-grid-detail` | Master-detail panel template |
344
500
  | `GridToolPanel` | `tbw-grid-tool-panel` | Custom sidebar panel |
345
501
 
502
+ ### Type Registry
503
+
504
+ | Export | Description |
505
+ | --------------------------- | -------------------------------------------- |
506
+ | `provideGridTypeDefaults()` | Provider factory for app-level type defaults |
507
+ | `GridTypeRegistry` | Injectable service for dynamic registration |
508
+ | `GRID_TYPE_DEFAULTS` | Injection token for type defaults |
509
+
510
+ ### Grid Directive Inputs
511
+
512
+ | Input | Type | Description |
513
+ | --------------- | ------------------------- | ------------------------------------------------------ |
514
+ | `angularConfig` | `AngularGridConfig<TRow>` | Grid config with component class support (recommended) |
515
+ | `customStyles` | `string` | Custom CSS styles to inject into the grid |
516
+
346
517
  ### Grid Directive Outputs
347
518
 
348
519
  | Output | Type | Description |
@@ -373,15 +544,27 @@ import { SelectionPlugin, FilteringPlugin } from '@toolbox-web/grid/all';
373
544
 
374
545
  ```typescript
375
546
  import type {
547
+ // Template contexts
376
548
  GridCellContext,
377
549
  GridEditorContext,
378
550
  GridDetailContext,
379
551
  GridToolPanelContext,
380
- CellCommitEvent,
381
- RowCommitEvent,
382
552
  StructuralCellContext,
383
553
  StructuralEditorContext,
554
+ // Events
555
+ CellCommitEvent,
556
+ RowCommitEvent,
557
+ // Type-level defaults
558
+ AngularTypeDefault,
559
+ // Component-class column config
560
+ AngularCellRenderer,
561
+ AngularCellEditor,
562
+ AngularColumnConfig,
563
+ AngularGridConfig,
384
564
  } from '@toolbox-web/grid-angular';
565
+
566
+ // Type guard for component class detection
567
+ import { isComponentClass } from '@toolbox-web/grid-angular';
385
568
  ```
386
569
 
387
570
  ### AngularGridAdapter
package/index.d.ts CHANGED
@@ -5,6 +5,10 @@
5
5
  * Provides directives for seamless Angular integration with the grid component.
6
6
  */
7
7
  export { AngularGridAdapter } from './lib/angular-grid-adapter';
8
+ export { isComponentClass } from './lib/angular-column-config';
9
+ export type { AngularCellEditor, AngularCellRenderer, AngularColumnConfig, AngularGridConfig, } from './lib/angular-column-config';
10
+ export { GRID_TYPE_DEFAULTS, GridTypeRegistry, provideGridTypeDefaults } from './lib/grid-type-registry';
11
+ export type { AngularTypeDefault } from './lib/grid-type-registry';
8
12
  export { GridColumnEditor } from './lib/directives/grid-column-editor.directive';
9
13
  export type { GridEditorContext } from './lib/directives/grid-column-editor.directive';
10
14
  export { GridColumnView } from './lib/directives/grid-column-view.directive';
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;;;;;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"}
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,6BAA6B,CAAC;AAC/D,YAAY,EACV,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACzG,YAAY,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAGnE,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"}