@toolbox-web/grid-angular 0.7.2 → 0.9.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
@@ -14,6 +14,7 @@ Angular adapter for `@toolbox-web/grid` data grid component. Provides directives
14
14
  - ✅ **Template-driven editors** - Use `<ng-template>` for custom cell editors
15
15
  - ✅ **Component-class column config** - Specify component classes directly in `gridConfig.columns`
16
16
  - ✅ **Type-level defaults** - App-wide renderers/editors via `provideGridTypeDefaults()`
17
+ - ✅ **Icon configuration** - App-wide icon overrides via `provideGridIcons()`
17
18
  - ✅ **Reactive Forms integration** - Use `formControlName` and `formControl` bindings
18
19
  - ✅ **Auto-wiring** - Editor components just emit events, no manual binding needed
19
20
  - ✅ **Full type safety** - Typed template contexts (`GridCellContext`, `GridEditorContext`)
@@ -359,6 +360,68 @@ export class MyGridComponent {
359
360
  | `GridTypeRegistry` | Injectable service for dynamic registration |
360
361
  | `GRID_TYPE_DEFAULTS` | Injection token for type defaults |
361
362
 
363
+ ## App-Wide Icon Configuration
364
+
365
+ Customize grid icons at the application level using `provideGridIcons()`:
366
+
367
+ ```typescript
368
+ // app.config.ts
369
+ import { ApplicationConfig } from '@angular/core';
370
+ import { provideGridIcons } from '@toolbox-web/grid-angular';
371
+
372
+ export const appConfig: ApplicationConfig = {
373
+ providers: [
374
+ provideGridIcons({
375
+ expand: '➕',
376
+ collapse: '➖',
377
+ sortAsc: '↑',
378
+ sortDesc: '↓',
379
+ filter: '<svg viewBox="0 0 16 16">...</svg>',
380
+ }),
381
+ ],
382
+ };
383
+ ```
384
+
385
+ **Dynamic Icon Registration:**
386
+
387
+ ```typescript
388
+ import { Component, inject, OnInit } from '@angular/core';
389
+ import { GridIconRegistry } from '@toolbox-web/grid-angular';
390
+
391
+ @Component({ ... })
392
+ export class AppComponent implements OnInit {
393
+ private iconRegistry = inject(GridIconRegistry);
394
+
395
+ ngOnInit() {
396
+ // Dynamically set icons
397
+ this.iconRegistry.set('expand', '▶');
398
+ this.iconRegistry.set('collapse', '▼');
399
+ }
400
+ }
401
+ ```
402
+
403
+ **Available Icons:**
404
+
405
+ | Icon | Default | Description |
406
+ | -------------- | ------- | ------------------------------------ |
407
+ | `expand` | `▶` | Expand icon for trees/groups/details |
408
+ | `collapse` | `▼` | Collapse icon |
409
+ | `sortAsc` | `▲` | Sort ascending indicator |
410
+ | `sortDesc` | `▼` | Sort descending indicator |
411
+ | `sortNone` | `⇅` | Unsorted indicator |
412
+ | `filter` | SVG | Filter icon in headers |
413
+ | `filterActive` | SVG | Filter icon when active |
414
+ | `submenuArrow` | `▶` | Context menu submenu arrow |
415
+ | `dragHandle` | `⋮⋮` | Drag handle for reordering |
416
+ | `toolPanel` | `☰` | Tool panel toggle icon |
417
+ | `print` | `🖨️` | Print button icon |
418
+
419
+ **Precedence (highest wins):**
420
+
421
+ 1. `gridConfig.icons` - Per-grid overrides
422
+ 2. `provideGridIcons()` - App-level defaults
423
+ 3. Built-in defaults
424
+
362
425
  ## Component-Class Column Config
363
426
 
364
427
  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.
@@ -782,6 +845,14 @@ if (context?.hasFormGroups) {
782
845
  | `GridTypeRegistry` | Injectable service for dynamic registration |
783
846
  | `GRID_TYPE_DEFAULTS` | Injection token for type defaults |
784
847
 
848
+ ### Icon Registry
849
+
850
+ | Export | Description |
851
+ | -------------------- | ------------------------------------------------ |
852
+ | `provideGridIcons()` | Provider factory for app-level icon overrides |
853
+ | `GridIconRegistry` | Injectable service for dynamic icon registration |
854
+ | `GRID_ICONS` | Injection token for icon overrides |
855
+
785
856
  ### Grid Directive Inputs
786
857
 
787
858
  | Input | Type | Description |
@@ -341,11 +341,23 @@ function getFormArrayContext(gridElement) {
341
341
  class GridFormArray {
342
342
  elementRef = inject((ElementRef));
343
343
  cellCommitListener = null;
344
+ rowCommitListener = null;
344
345
  touchListener = null;
345
346
  /**
346
347
  * The FormArray to bind to the grid.
347
348
  */
348
349
  formArray = input.required(...(ngDevMode ? [{ debugName: "formArray" }] : []));
350
+ /**
351
+ * Whether to automatically sync Angular validation state to grid's visual invalid styling.
352
+ *
353
+ * When enabled:
354
+ * - After a cell commit, if the FormControl is invalid, the cell is marked with `setInvalid()`
355
+ * - When a FormControl becomes valid, `clearInvalid()` is called
356
+ * - On `row-commit`, if the row's FormGroup has invalid controls, the commit is prevented
357
+ *
358
+ * @default true
359
+ */
360
+ syncValidation = input(true, ...(ngDevMode ? [{ debugName: "syncValidation" }] : []));
349
361
  /**
350
362
  * Effect that syncs the FormArray value to the grid rows.
351
363
  */
@@ -369,6 +381,14 @@ class GridFormArray {
369
381
  this.#handleCellCommit(detail);
370
382
  };
371
383
  grid.addEventListener('cell-commit', this.cellCommitListener);
384
+ // Intercept row-commit events to prevent if FormGroup is invalid
385
+ this.rowCommitListener = (e) => {
386
+ if (!this.syncValidation())
387
+ return;
388
+ const detail = e.detail;
389
+ this.#handleRowCommit(e, detail);
390
+ };
391
+ grid.addEventListener('row-commit', this.rowCommitListener);
372
392
  // Mark FormArray as touched on first interaction
373
393
  this.touchListener = () => {
374
394
  this.formArray().markAsTouched();
@@ -387,6 +407,9 @@ class GridFormArray {
387
407
  if (this.cellCommitListener) {
388
408
  grid.removeEventListener('cell-commit', this.cellCommitListener);
389
409
  }
410
+ if (this.rowCommitListener) {
411
+ grid.removeEventListener('row-commit', this.rowCommitListener);
412
+ }
390
413
  if (this.touchListener) {
391
414
  grid.removeEventListener('click', this.touchListener);
392
415
  }
@@ -491,7 +514,7 @@ class GridFormArray {
491
514
  * Handles cell-commit events by updating the FormControl in the FormGroup.
492
515
  */
493
516
  #handleCellCommit(detail) {
494
- const { rowIndex, field, value } = detail;
517
+ const { rowIndex, field, value, rowId } = detail;
495
518
  const rowFormGroup = this.#getRowFormGroup(rowIndex);
496
519
  if (rowFormGroup) {
497
520
  const control = rowFormGroup.get(field);
@@ -499,18 +522,83 @@ class GridFormArray {
499
522
  control.setValue(value);
500
523
  control.markAsDirty();
501
524
  control.markAsTouched();
525
+ // Sync Angular validation state to grid's visual invalid styling
526
+ if (this.syncValidation() && rowId) {
527
+ this.#syncControlValidationToGrid(rowId, field, control);
528
+ }
502
529
  }
503
530
  }
504
531
  }
532
+ /**
533
+ * Handles row-commit events - prevents commit if FormGroup has invalid controls.
534
+ */
535
+ #handleRowCommit(event, detail) {
536
+ const { rowIndex } = detail;
537
+ const rowFormGroup = this.#getRowFormGroup(rowIndex);
538
+ if (rowFormGroup && rowFormGroup.invalid) {
539
+ // Prevent row commit if the FormGroup is invalid
540
+ event.preventDefault();
541
+ }
542
+ }
543
+ /**
544
+ * Syncs a FormControl's validation state to the grid's visual invalid styling.
545
+ */
546
+ #syncControlValidationToGrid(rowId, field, control) {
547
+ const grid = this.elementRef.nativeElement;
548
+ if (!grid)
549
+ return;
550
+ // Get EditingPlugin via getPluginByName
551
+ const editingPlugin = grid.getPluginByName?.('editing');
552
+ if (!editingPlugin)
553
+ return;
554
+ if (control.invalid) {
555
+ // Get first error message to display
556
+ const errorMessage = this.#getFirstErrorMessage(control);
557
+ editingPlugin.setInvalid(rowId, field, errorMessage);
558
+ }
559
+ else {
560
+ editingPlugin.clearInvalid(rowId, field);
561
+ }
562
+ }
563
+ /**
564
+ * Gets a human-readable error message from the first validation error.
565
+ */
566
+ #getFirstErrorMessage(control) {
567
+ const errors = control.errors;
568
+ if (!errors)
569
+ return '';
570
+ const firstKey = Object.keys(errors)[0];
571
+ const error = errors[firstKey];
572
+ // Common Angular validators
573
+ switch (firstKey) {
574
+ case 'required':
575
+ return 'This field is required';
576
+ case 'minlength':
577
+ return `Minimum length is ${error.requiredLength}`;
578
+ case 'maxlength':
579
+ return `Maximum length is ${error.requiredLength}`;
580
+ case 'min':
581
+ return `Minimum value is ${error.min}`;
582
+ case 'max':
583
+ return `Maximum value is ${error.max}`;
584
+ case 'email':
585
+ return 'Invalid email address';
586
+ case 'pattern':
587
+ return 'Invalid format';
588
+ default:
589
+ // Custom validators may provide a message property
590
+ return typeof error === 'string' ? error : (error?.message ?? `Validation error: ${firstKey}`);
591
+ }
592
+ }
505
593
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: GridFormArray, deps: [], target: i0.ɵɵFactoryTarget.Directive });
506
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: GridFormArray, isStandalone: true, selector: "tbw-grid[formArray]", inputs: { formArray: { classPropertyName: "formArray", publicName: "formArray", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
594
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: GridFormArray, isStandalone: true, selector: "tbw-grid[formArray]", inputs: { formArray: { classPropertyName: "formArray", publicName: "formArray", isSignal: true, isRequired: true, transformFunction: null }, syncValidation: { classPropertyName: "syncValidation", publicName: "syncValidation", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
507
595
  }
508
596
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: GridFormArray, decorators: [{
509
597
  type: Directive,
510
598
  args: [{
511
599
  selector: 'tbw-grid[formArray]',
512
600
  }]
513
- }], propDecorators: { formArray: [{ type: i0.Input, args: [{ isSignal: true, alias: "formArray", required: true }] }] } });
601
+ }], propDecorators: { formArray: [{ type: i0.Input, args: [{ isSignal: true, alias: "formArray", required: true }] }], syncValidation: [{ type: i0.Input, args: [{ isSignal: true, alias: "syncValidation", required: false }] }] } });
514
602
 
515
603
  /**
516
604
  * Registry to store responsive card templates by grid element.
@@ -1612,6 +1700,149 @@ class AngularGridAdapter {
1612
1700
  }
1613
1701
  }
1614
1702
 
1703
+ /**
1704
+ * Icon configuration registry for Angular applications.
1705
+ *
1706
+ * Provides application-wide icon overrides for all grids via
1707
+ * Angular's dependency injection.
1708
+ */
1709
+ /**
1710
+ * Injection token for providing icon overrides at app level.
1711
+ */
1712
+ const GRID_ICONS = new InjectionToken('GRID_ICONS');
1713
+ /**
1714
+ * Injectable service for managing grid icons.
1715
+ *
1716
+ * Use `provideGridIcons()` in your app config to set up icons,
1717
+ * or inject this service for dynamic registration.
1718
+ *
1719
+ * @example
1720
+ * ```typescript
1721
+ * // App-level setup (app.config.ts)
1722
+ * export const appConfig: ApplicationConfig = {
1723
+ * providers: [
1724
+ * provideGridIcons({
1725
+ * expand: '➕',
1726
+ * collapse: '➖',
1727
+ * sortAsc: '↑',
1728
+ * sortDesc: '↓',
1729
+ * })
1730
+ * ]
1731
+ * };
1732
+ *
1733
+ * // Dynamic registration
1734
+ * @Component({ ... })
1735
+ * export class AppComponent {
1736
+ * private registry = inject(GridIconRegistry);
1737
+ *
1738
+ * ngOnInit() {
1739
+ * this.registry.set('filter', '<svg>...</svg>');
1740
+ * }
1741
+ * }
1742
+ * ```
1743
+ */
1744
+ class GridIconRegistry {
1745
+ icons = new Map();
1746
+ constructor() {
1747
+ // Merge any initial icons from provider
1748
+ const initial = inject(GRID_ICONS, { optional: true });
1749
+ if (initial) {
1750
+ for (const [key, value] of Object.entries(initial)) {
1751
+ this.icons.set(key, value);
1752
+ }
1753
+ }
1754
+ }
1755
+ /**
1756
+ * Set an icon override.
1757
+ *
1758
+ * @param name - The icon name (e.g., 'expand', 'collapse', 'filter')
1759
+ * @param value - The icon value (string text or SVG markup)
1760
+ */
1761
+ set(name, value) {
1762
+ this.icons.set(name, value);
1763
+ }
1764
+ /**
1765
+ * Get an icon value.
1766
+ */
1767
+ get(name) {
1768
+ return this.icons.get(name);
1769
+ }
1770
+ /**
1771
+ * Remove an icon override.
1772
+ */
1773
+ remove(name) {
1774
+ this.icons.delete(name);
1775
+ }
1776
+ /**
1777
+ * Check if an icon has an override.
1778
+ */
1779
+ has(name) {
1780
+ return this.icons.has(name);
1781
+ }
1782
+ /**
1783
+ * Get all icon overrides as a GridIcons partial.
1784
+ * Used internally by the adapter.
1785
+ *
1786
+ * @internal
1787
+ */
1788
+ getAll() {
1789
+ const result = {};
1790
+ for (const [key, value] of this.icons) {
1791
+ result[key] = value;
1792
+ }
1793
+ return result;
1794
+ }
1795
+ /**
1796
+ * Get all registered icon names.
1797
+ */
1798
+ getRegisteredIcons() {
1799
+ return Array.from(this.icons.keys());
1800
+ }
1801
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: GridIconRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1802
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: GridIconRegistry, providedIn: 'root' });
1803
+ }
1804
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: GridIconRegistry, decorators: [{
1805
+ type: Injectable,
1806
+ args: [{ providedIn: 'root' }]
1807
+ }], ctorParameters: () => [] });
1808
+ /**
1809
+ * Provides application-level icon overrides for all grids.
1810
+ *
1811
+ * Available icons to override:
1812
+ * - `expand` - Expand icon for collapsed items (trees, groups, details)
1813
+ * - `collapse` - Collapse icon for expanded items
1814
+ * - `sortAsc` - Sort ascending indicator
1815
+ * - `sortDesc` - Sort descending indicator
1816
+ * - `sortNone` - Sort neutral/unsorted indicator
1817
+ * - `submenuArrow` - Submenu arrow for context menus
1818
+ * - `dragHandle` - Drag handle icon for reordering
1819
+ * - `toolPanel` - Tool panel toggle icon in toolbar
1820
+ * - `filter` - Filter icon in column headers
1821
+ * - `filterActive` - Filter icon when filter is active
1822
+ * - `print` - Print icon for print button
1823
+ *
1824
+ * @example
1825
+ * ```typescript
1826
+ * // app.config.ts
1827
+ * import { provideGridIcons } from '@toolbox-web/grid-angular';
1828
+ *
1829
+ * export const appConfig: ApplicationConfig = {
1830
+ * providers: [
1831
+ * provideGridIcons({
1832
+ * expand: '➕',
1833
+ * collapse: '➖',
1834
+ * sortAsc: '↑',
1835
+ * sortDesc: '↓',
1836
+ * filter: '<svg viewBox="0 0 16 16">...</svg>',
1837
+ * })
1838
+ * ]
1839
+ * };
1840
+ * ```
1841
+ */
1842
+ function provideGridIcons(icons) {
1843
+ return makeEnvironmentProviders([{ provide: GRID_ICONS, useValue: icons }]);
1844
+ }
1845
+
1615
1846
  /**
1616
1847
  * Angular inject function for programmatic access to a grid instance.
1617
1848
  *
@@ -2186,6 +2417,7 @@ class Grid {
2186
2417
  injector = inject(EnvironmentInjector);
2187
2418
  appRef = inject(ApplicationRef);
2188
2419
  viewContainerRef = inject(ViewContainerRef);
2420
+ iconRegistry = inject(GridIconRegistry, { optional: true });
2189
2421
  adapter = null;
2190
2422
  constructor() {
2191
2423
  // Effect to process angularConfig and apply to grid
@@ -2215,6 +2447,13 @@ class Grid {
2215
2447
  if (selectableValue !== undefined) {
2216
2448
  coreConfigOverrides['selectable'] = selectableValue;
2217
2449
  }
2450
+ // Merge icon overrides from registry with any existing icons in config
2451
+ // Registry icons are base, config.icons override them
2452
+ const registryIcons = this.iconRegistry?.getAll();
2453
+ if (registryIcons && Object.keys(registryIcons).length > 0) {
2454
+ const existingIcons = processedConfig?.icons || config?.icons || {};
2455
+ coreConfigOverrides['icons'] = { ...registryIcons, ...existingIcons };
2456
+ }
2218
2457
  // Apply to the grid element
2219
2458
  const grid = this.elementRef.nativeElement;
2220
2459
  grid.gridConfig = {
@@ -2223,6 +2462,14 @@ class Grid {
2223
2462
  plugins: mergedPlugins.length > 0 ? mergedPlugins : undefined,
2224
2463
  };
2225
2464
  });
2465
+ // Effect to sync loading state to the grid element
2466
+ effect(() => {
2467
+ const loadingValue = this.loading();
2468
+ if (loadingValue === undefined)
2469
+ return;
2470
+ const grid = this.elementRef.nativeElement;
2471
+ grid.loading = loadingValue;
2472
+ });
2226
2473
  }
2227
2474
  /**
2228
2475
  * Custom CSS styles to inject into the grid.
@@ -2303,6 +2550,34 @@ class Grid {
2303
2550
  * ```
2304
2551
  */
2305
2552
  selectable = input(...(ngDevMode ? [undefined, { debugName: "selectable" }] : []));
2553
+ /**
2554
+ * Show a loading overlay on the grid.
2555
+ * Use this during initial data fetch or refresh operations.
2556
+ *
2557
+ * For row/cell loading states, access the grid element directly:
2558
+ * - `grid.setRowLoading(rowId, true/false)`
2559
+ * - `grid.setCellLoading(rowId, field, true/false)`
2560
+ *
2561
+ * @default false
2562
+ *
2563
+ * @example
2564
+ * ```html
2565
+ * <!-- Show loading during data fetch -->
2566
+ * <tbw-grid [loading]="isLoading" [rows]="rows" />
2567
+ * ```
2568
+ *
2569
+ * ```typescript
2570
+ * isLoading = true;
2571
+ *
2572
+ * ngOnInit() {
2573
+ * this.dataService.fetchData().subscribe(data => {
2574
+ * this.rows = data;
2575
+ * this.isLoading = false;
2576
+ * });
2577
+ * }
2578
+ * ```
2579
+ */
2580
+ loading = input(...(ngDevMode ? [undefined, { debugName: "loading" }] : []));
2306
2581
  /**
2307
2582
  * Angular-specific grid configuration that supports component classes for renderers/editors.
2308
2583
  *
@@ -3167,12 +3442,12 @@ class Grid {
3167
3442
  }
3168
3443
  }
3169
3444
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: Grid, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3170
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: Grid, isStandalone: true, selector: "tbw-grid", inputs: { customStyles: { classPropertyName: "customStyles", publicName: "customStyles", isSignal: true, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, angularConfig: { classPropertyName: "angularConfig", publicName: "angularConfig", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, editing: { classPropertyName: "editing", publicName: "editing", isSignal: true, isRequired: false, transformFunction: null }, clipboard: { classPropertyName: "clipboard", publicName: "clipboard", isSignal: true, isRequired: false, transformFunction: null }, contextMenu: { classPropertyName: "contextMenu", publicName: "contextMenu", isSignal: true, isRequired: false, transformFunction: null }, multiSort: { classPropertyName: "multiSort", publicName: "multiSort", isSignal: true, isRequired: false, transformFunction: null }, sorting: { classPropertyName: "sorting", publicName: "sorting", isSignal: true, isRequired: false, transformFunction: null }, filtering: { classPropertyName: "filtering", publicName: "filtering", isSignal: true, isRequired: false, transformFunction: null }, reorder: { classPropertyName: "reorder", publicName: "reorder", isSignal: true, isRequired: false, transformFunction: null }, visibility: { classPropertyName: "visibility", publicName: "visibility", isSignal: true, isRequired: false, transformFunction: null }, pinnedColumns: { classPropertyName: "pinnedColumns", publicName: "pinnedColumns", isSignal: true, isRequired: false, transformFunction: null }, groupingColumns: { classPropertyName: "groupingColumns", publicName: "groupingColumns", isSignal: true, isRequired: false, transformFunction: null }, columnVirtualization: { classPropertyName: "columnVirtualization", publicName: "columnVirtualization", isSignal: true, isRequired: false, transformFunction: null }, rowReorder: { classPropertyName: "rowReorder", publicName: "rowReorder", isSignal: true, isRequired: false, transformFunction: null }, groupingRows: { classPropertyName: "groupingRows", publicName: "groupingRows", isSignal: true, isRequired: false, transformFunction: null }, pinnedRows: { classPropertyName: "pinnedRows", publicName: "pinnedRows", isSignal: true, isRequired: false, transformFunction: null }, tree: { classPropertyName: "tree", publicName: "tree", isSignal: true, isRequired: false, transformFunction: null }, masterDetail: { classPropertyName: "masterDetail", publicName: "masterDetail", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, undoRedo: { classPropertyName: "undoRedo", publicName: "undoRedo", isSignal: true, isRequired: false, transformFunction: null }, exportFeature: { classPropertyName: "exportFeature", publicName: "exportFeature", isSignal: true, isRequired: false, transformFunction: null }, print: { classPropertyName: "print", publicName: "print", isSignal: true, isRequired: false, transformFunction: null }, pivot: { classPropertyName: "pivot", publicName: "pivot", isSignal: true, isRequired: false, transformFunction: null }, serverSide: { classPropertyName: "serverSide", publicName: "serverSide", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellClick: "cellClick", rowClick: "rowClick", cellActivate: "cellActivate", cellChange: "cellChange", cellCommit: "cellCommit", rowCommit: "rowCommit", changedRowsReset: "changedRowsReset", sortChange: "sortChange", filterChange: "filterChange", columnResize: "columnResize", columnMove: "columnMove", columnVisibility: "columnVisibility", columnStateChange: "columnStateChange", selectionChange: "selectionChange", rowMove: "rowMove", groupToggle: "groupToggle", treeExpand: "treeExpand", detailExpand: "detailExpand", responsiveChange: "responsiveChange", copy: "copy", paste: "paste", undoRedoAction: "undoRedoAction", exportComplete: "exportComplete", printStart: "printStart", printComplete: "printComplete" }, ngImport: i0 });
3445
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: Grid, isStandalone: true, selector: "tbw-grid", inputs: { customStyles: { classPropertyName: "customStyles", publicName: "customStyles", isSignal: true, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, angularConfig: { classPropertyName: "angularConfig", publicName: "angularConfig", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, editing: { classPropertyName: "editing", publicName: "editing", isSignal: true, isRequired: false, transformFunction: null }, clipboard: { classPropertyName: "clipboard", publicName: "clipboard", isSignal: true, isRequired: false, transformFunction: null }, contextMenu: { classPropertyName: "contextMenu", publicName: "contextMenu", isSignal: true, isRequired: false, transformFunction: null }, multiSort: { classPropertyName: "multiSort", publicName: "multiSort", isSignal: true, isRequired: false, transformFunction: null }, sorting: { classPropertyName: "sorting", publicName: "sorting", isSignal: true, isRequired: false, transformFunction: null }, filtering: { classPropertyName: "filtering", publicName: "filtering", isSignal: true, isRequired: false, transformFunction: null }, reorder: { classPropertyName: "reorder", publicName: "reorder", isSignal: true, isRequired: false, transformFunction: null }, visibility: { classPropertyName: "visibility", publicName: "visibility", isSignal: true, isRequired: false, transformFunction: null }, pinnedColumns: { classPropertyName: "pinnedColumns", publicName: "pinnedColumns", isSignal: true, isRequired: false, transformFunction: null }, groupingColumns: { classPropertyName: "groupingColumns", publicName: "groupingColumns", isSignal: true, isRequired: false, transformFunction: null }, columnVirtualization: { classPropertyName: "columnVirtualization", publicName: "columnVirtualization", isSignal: true, isRequired: false, transformFunction: null }, rowReorder: { classPropertyName: "rowReorder", publicName: "rowReorder", isSignal: true, isRequired: false, transformFunction: null }, groupingRows: { classPropertyName: "groupingRows", publicName: "groupingRows", isSignal: true, isRequired: false, transformFunction: null }, pinnedRows: { classPropertyName: "pinnedRows", publicName: "pinnedRows", isSignal: true, isRequired: false, transformFunction: null }, tree: { classPropertyName: "tree", publicName: "tree", isSignal: true, isRequired: false, transformFunction: null }, masterDetail: { classPropertyName: "masterDetail", publicName: "masterDetail", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, undoRedo: { classPropertyName: "undoRedo", publicName: "undoRedo", isSignal: true, isRequired: false, transformFunction: null }, exportFeature: { classPropertyName: "exportFeature", publicName: "exportFeature", isSignal: true, isRequired: false, transformFunction: null }, print: { classPropertyName: "print", publicName: "print", isSignal: true, isRequired: false, transformFunction: null }, pivot: { classPropertyName: "pivot", publicName: "pivot", isSignal: true, isRequired: false, transformFunction: null }, serverSide: { classPropertyName: "serverSide", publicName: "serverSide", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellClick: "cellClick", rowClick: "rowClick", cellActivate: "cellActivate", cellChange: "cellChange", cellCommit: "cellCommit", rowCommit: "rowCommit", changedRowsReset: "changedRowsReset", sortChange: "sortChange", filterChange: "filterChange", columnResize: "columnResize", columnMove: "columnMove", columnVisibility: "columnVisibility", columnStateChange: "columnStateChange", selectionChange: "selectionChange", rowMove: "rowMove", groupToggle: "groupToggle", treeExpand: "treeExpand", detailExpand: "detailExpand", responsiveChange: "responsiveChange", copy: "copy", paste: "paste", undoRedoAction: "undoRedoAction", exportComplete: "exportComplete", printStart: "printStart", printComplete: "printComplete" }, ngImport: i0 });
3171
3446
  }
3172
3447
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: Grid, decorators: [{
3173
3448
  type: Directive,
3174
3449
  args: [{ selector: 'tbw-grid' }]
3175
- }], ctorParameters: () => [], propDecorators: { customStyles: [{ type: i0.Input, args: [{ isSignal: true, alias: "customStyles", required: false }] }], sortable: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortable", required: false }] }], filterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterable", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], angularConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "angularConfig", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }], editing: [{ type: i0.Input, args: [{ isSignal: true, alias: "editing", required: false }] }], clipboard: [{ type: i0.Input, args: [{ isSignal: true, alias: "clipboard", required: false }] }], contextMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextMenu", required: false }] }], multiSort: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiSort", required: false }] }], sorting: [{ type: i0.Input, args: [{ isSignal: true, alias: "sorting", required: false }] }], filtering: [{ type: i0.Input, args: [{ isSignal: true, alias: "filtering", required: false }] }], reorder: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorder", required: false }] }], visibility: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibility", required: false }] }], pinnedColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedColumns", required: false }] }], groupingColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupingColumns", required: false }] }], columnVirtualization: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnVirtualization", required: false }] }], rowReorder: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowReorder", required: false }] }], groupingRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupingRows", required: false }] }], pinnedRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedRows", required: false }] }], tree: [{ type: i0.Input, args: [{ isSignal: true, alias: "tree", required: false }] }], masterDetail: [{ type: i0.Input, args: [{ isSignal: true, alias: "masterDetail", required: false }] }], responsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "responsive", required: false }] }], undoRedo: [{ type: i0.Input, args: [{ isSignal: true, alias: "undoRedo", required: false }] }], exportFeature: [{ type: i0.Input, args: [{ isSignal: true, alias: "exportFeature", required: false }] }], print: [{ type: i0.Input, args: [{ isSignal: true, alias: "print", required: false }] }], pivot: [{ type: i0.Input, args: [{ isSignal: true, alias: "pivot", required: false }] }], serverSide: [{ type: i0.Input, args: [{ isSignal: true, alias: "serverSide", required: false }] }], cellClick: [{ type: i0.Output, args: ["cellClick"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], cellActivate: [{ type: i0.Output, args: ["cellActivate"] }], cellChange: [{ type: i0.Output, args: ["cellChange"] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], rowCommit: [{ type: i0.Output, args: ["rowCommit"] }], changedRowsReset: [{ type: i0.Output, args: ["changedRowsReset"] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }], columnResize: [{ type: i0.Output, args: ["columnResize"] }], columnMove: [{ type: i0.Output, args: ["columnMove"] }], columnVisibility: [{ type: i0.Output, args: ["columnVisibility"] }], columnStateChange: [{ type: i0.Output, args: ["columnStateChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], rowMove: [{ type: i0.Output, args: ["rowMove"] }], groupToggle: [{ type: i0.Output, args: ["groupToggle"] }], treeExpand: [{ type: i0.Output, args: ["treeExpand"] }], detailExpand: [{ type: i0.Output, args: ["detailExpand"] }], responsiveChange: [{ type: i0.Output, args: ["responsiveChange"] }], copy: [{ type: i0.Output, args: ["copy"] }], paste: [{ type: i0.Output, args: ["paste"] }], undoRedoAction: [{ type: i0.Output, args: ["undoRedoAction"] }], exportComplete: [{ type: i0.Output, args: ["exportComplete"] }], printStart: [{ type: i0.Output, args: ["printStart"] }], printComplete: [{ type: i0.Output, args: ["printComplete"] }] } });
3450
+ }], ctorParameters: () => [], propDecorators: { customStyles: [{ type: i0.Input, args: [{ isSignal: true, alias: "customStyles", required: false }] }], sortable: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortable", required: false }] }], filterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterable", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], angularConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "angularConfig", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }], editing: [{ type: i0.Input, args: [{ isSignal: true, alias: "editing", required: false }] }], clipboard: [{ type: i0.Input, args: [{ isSignal: true, alias: "clipboard", required: false }] }], contextMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextMenu", required: false }] }], multiSort: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiSort", required: false }] }], sorting: [{ type: i0.Input, args: [{ isSignal: true, alias: "sorting", required: false }] }], filtering: [{ type: i0.Input, args: [{ isSignal: true, alias: "filtering", required: false }] }], reorder: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorder", required: false }] }], visibility: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibility", required: false }] }], pinnedColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedColumns", required: false }] }], groupingColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupingColumns", required: false }] }], columnVirtualization: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnVirtualization", required: false }] }], rowReorder: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowReorder", required: false }] }], groupingRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupingRows", required: false }] }], pinnedRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedRows", required: false }] }], tree: [{ type: i0.Input, args: [{ isSignal: true, alias: "tree", required: false }] }], masterDetail: [{ type: i0.Input, args: [{ isSignal: true, alias: "masterDetail", required: false }] }], responsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "responsive", required: false }] }], undoRedo: [{ type: i0.Input, args: [{ isSignal: true, alias: "undoRedo", required: false }] }], exportFeature: [{ type: i0.Input, args: [{ isSignal: true, alias: "exportFeature", required: false }] }], print: [{ type: i0.Input, args: [{ isSignal: true, alias: "print", required: false }] }], pivot: [{ type: i0.Input, args: [{ isSignal: true, alias: "pivot", required: false }] }], serverSide: [{ type: i0.Input, args: [{ isSignal: true, alias: "serverSide", required: false }] }], cellClick: [{ type: i0.Output, args: ["cellClick"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], cellActivate: [{ type: i0.Output, args: ["cellActivate"] }], cellChange: [{ type: i0.Output, args: ["cellChange"] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], rowCommit: [{ type: i0.Output, args: ["rowCommit"] }], changedRowsReset: [{ type: i0.Output, args: ["changedRowsReset"] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }], columnResize: [{ type: i0.Output, args: ["columnResize"] }], columnMove: [{ type: i0.Output, args: ["columnMove"] }], columnVisibility: [{ type: i0.Output, args: ["columnVisibility"] }], columnStateChange: [{ type: i0.Output, args: ["columnStateChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], rowMove: [{ type: i0.Output, args: ["rowMove"] }], groupToggle: [{ type: i0.Output, args: ["groupToggle"] }], treeExpand: [{ type: i0.Output, args: ["treeExpand"] }], detailExpand: [{ type: i0.Output, args: ["detailExpand"] }], responsiveChange: [{ type: i0.Output, args: ["responsiveChange"] }], copy: [{ type: i0.Output, args: ["copy"] }], paste: [{ type: i0.Output, args: ["paste"] }], undoRedoAction: [{ type: i0.Output, args: ["undoRedoAction"] }], exportComplete: [{ type: i0.Output, args: ["exportComplete"] }], printStart: [{ type: i0.Output, args: ["printStart"] }], printComplete: [{ type: i0.Output, args: ["printComplete"] }] } });
3176
3451
 
3177
3452
  /**
3178
3453
  * @packageDocumentation
@@ -3185,5 +3460,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
3185
3460
  * Generated bundle index. Do not edit.
3186
3461
  */
3187
3462
 
3188
- export { AngularGridAdapter, BaseGridEditor, GRID_TYPE_DEFAULTS, Grid, GridColumnEditor, GridColumnView, GridDetailView, GridFormArray, GridResponsiveCard, GridToolPanel, GridTypeRegistry, TbwEditor as TbwCellEditor, TbwRenderer as TbwCellView, TbwEditor, TbwRenderer, clearFeatureRegistry, createPluginFromFeature, getFeatureFactory, getFormArrayContext, getRegisteredFeatures, injectGrid, isComponentClass, isFeatureRegistered, provideGridTypeDefaults, registerFeature };
3463
+ export { AngularGridAdapter, BaseGridEditor, GRID_ICONS, GRID_TYPE_DEFAULTS, Grid, GridColumnEditor, GridColumnView, GridDetailView, GridFormArray, GridIconRegistry, GridResponsiveCard, GridToolPanel, GridTypeRegistry, TbwEditor as TbwCellEditor, TbwRenderer as TbwCellView, TbwEditor, TbwRenderer, clearFeatureRegistry, createPluginFromFeature, getFeatureFactory, getFormArrayContext, getRegisteredFeatures, injectGrid, isComponentClass, isFeatureRegistered, provideGridIcons, provideGridTypeDefaults, registerFeature };
3189
3464
  //# sourceMappingURL=toolbox-web-grid-angular.mjs.map