@toolbox-web/grid-angular 1.6.0 → 1.7.1

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 (32) hide show
  1. package/README.md +12 -10
  2. package/fesm2022/toolbox-web-grid-angular-features-filtering.mjs +26 -1
  3. package/fesm2022/toolbox-web-grid-angular-features-filtering.mjs.map +1 -1
  4. package/fesm2022/toolbox-web-grid-angular-features-grouping-columns.mjs.map +1 -1
  5. package/fesm2022/toolbox-web-grid-angular-features-grouping-rows.mjs.map +1 -1
  6. package/fesm2022/toolbox-web-grid-angular-features-master-detail.mjs +33 -1
  7. package/fesm2022/toolbox-web-grid-angular-features-master-detail.mjs.map +1 -1
  8. package/fesm2022/toolbox-web-grid-angular-features-pinned-rows.mjs +51 -10
  9. package/fesm2022/toolbox-web-grid-angular-features-pinned-rows.mjs.map +1 -1
  10. package/fesm2022/toolbox-web-grid-angular-features-reorder-rows.mjs +8 -0
  11. package/fesm2022/toolbox-web-grid-angular-features-reorder-rows.mjs.map +1 -1
  12. package/fesm2022/toolbox-web-grid-angular-features-responsive.mjs +30 -1
  13. package/fesm2022/toolbox-web-grid-angular-features-responsive.mjs.map +1 -1
  14. package/fesm2022/toolbox-web-grid-angular.mjs +324 -4
  15. package/fesm2022/toolbox-web-grid-angular.mjs.map +1 -1
  16. package/package.json +1 -1
  17. package/types/toolbox-web-grid-angular-features-filtering.d.ts +22 -3
  18. package/types/toolbox-web-grid-angular-features-filtering.d.ts.map +1 -1
  19. package/types/toolbox-web-grid-angular-features-grouping-columns.d.ts +29 -2
  20. package/types/toolbox-web-grid-angular-features-grouping-columns.d.ts.map +1 -1
  21. package/types/toolbox-web-grid-angular-features-grouping-rows.d.ts +17 -2
  22. package/types/toolbox-web-grid-angular-features-grouping-rows.d.ts.map +1 -1
  23. package/types/toolbox-web-grid-angular-features-master-detail.d.ts +22 -2
  24. package/types/toolbox-web-grid-angular-features-master-detail.d.ts.map +1 -1
  25. package/types/toolbox-web-grid-angular-features-pinned-rows.d.ts +71 -2
  26. package/types/toolbox-web-grid-angular-features-pinned-rows.d.ts.map +1 -1
  27. package/types/toolbox-web-grid-angular-features-reorder-rows.d.ts +4 -0
  28. package/types/toolbox-web-grid-angular-features-reorder-rows.d.ts.map +1 -1
  29. package/types/toolbox-web-grid-angular-features-responsive.d.ts +22 -2
  30. package/types/toolbox-web-grid-angular-features-responsive.d.ts.map +1 -1
  31. package/types/toolbox-web-grid-angular.d.ts +154 -7
  32. package/types/toolbox-web-grid-angular.d.ts.map +1 -1
@@ -1,4 +1,4 @@
1
- import { registerFeatureClaim, claimEvent, unregisterFeatureClaim, unclaimEvent, registerResponsiveCardRendererBridge, getResponsiveCardTemplate, registerTemplateBridge } from '@toolbox-web/grid-angular';
1
+ import { registerFeatureClaim, claimEvent, unregisterFeatureClaim, unclaimEvent, registerResponsiveCardRendererBridge, getResponsiveCardTemplate, registerTemplateBridge, registerFeatureConfigPreprocessor, isComponentClass } from '@toolbox-web/grid-angular';
2
2
  import '@toolbox-web/grid/features/responsive';
3
3
  import * as i0 from '@angular/core';
4
4
  import { inject, ElementRef, input, output, Directive } from '@angular/core';
@@ -121,6 +121,35 @@ registerTemplateBridge(({ grid, adapter }) => {
121
121
  }
122
122
  existingPlugin.setCardRenderer?.(cardRenderer);
123
123
  });
124
+ /**
125
+ * Bridge any Angular component class used as `responsive.cardRenderer` to a
126
+ * plain `(row, rowIndex, column?) => HTMLElement` function before the core
127
+ * plugin factory consumes the config. Without this preprocessor, a component
128
+ * class passed as `cardRenderer` would be invoked as a function at render
129
+ * time and crash. Light-DOM `<tbw-grid-responsive-card>` templates continue
130
+ * to win via the post-mount template bridge above.
131
+ *
132
+ * @since 1.7.1
133
+ */
134
+ registerFeatureConfigPreprocessor('responsive', (config, adapter) => {
135
+ if (!config || typeof config !== 'object')
136
+ return config;
137
+ const cfg = config;
138
+ if (!isComponentClass(cfg.cardRenderer))
139
+ return config;
140
+ const componentClass = cfg.cardRenderer;
141
+ const mount = adapter.mountComponentRenderer(componentClass, (ctx) => ({ row: ctx.row, rowIndex: ctx.rowIndex, column: ctx.column }));
142
+ const cached = new Map();
143
+ const cardRenderer = (row, rowIndex, column) => {
144
+ const existing = cached.get(row);
145
+ if (existing)
146
+ return existing;
147
+ const { hostElement } = mount({ row, rowIndex, column });
148
+ cached.set(row, hostElement);
149
+ return hostElement;
150
+ };
151
+ return { ...cfg, cardRenderer };
152
+ });
124
153
 
125
154
  /**
126
155
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"toolbox-web-grid-angular-features-responsive.mjs","sources":["../../../../libs/grid-angular/features/responsive/src/grid-responsive.directive.ts","../../../../libs/grid-angular/features/responsive/src/index.ts","../../../../libs/grid-angular/features/responsive/src/toolbox-web-grid-angular-features-responsive.ts"],"sourcesContent":["/**\n * `GridResponsiveDirective` — owns `[responsive]` and `(responsiveChange)`\n * on `<tbw-grid>`. See `GridFilteringDirective` for the full rationale.\n *\n * @category Directive\n */\nimport { Directive, ElementRef, inject, input, OnDestroy, OnInit, output } from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport { claimEvent, registerFeatureClaim, unclaimEvent, unregisterFeatureClaim } from '@toolbox-web/grid-angular';\nimport type { ResponsiveChangeDetail, ResponsivePluginConfig } from '@toolbox-web/grid/plugins/responsive';\n\n/**\n * Owns the binding(s) `[responsive], [responsiveChange]` on `<tbw-grid>` for the matching feature plugin. See `GridFilteringDirective` for the full rationale.\n *\n * @category Directive\n */\n@Directive({\n selector: 'tbw-grid[responsive], tbw-grid[responsiveChange]',\n standalone: true,\n})\nexport class GridResponsiveDirective implements OnInit, OnDestroy {\n private readonly elementRef = inject(ElementRef<DataGridElement>);\n\n readonly responsive = input<boolean | ResponsivePluginConfig>();\n readonly responsiveChange = output<ResponsiveChangeDetail>();\n\n private listener?: (e: Event) => void;\n\n constructor() {\n const grid = this.elementRef.nativeElement;\n registerFeatureClaim(grid, 'responsive', () => this.responsive());\n claimEvent(grid, 'responsive-change');\n }\n\n ngOnInit(): void {\n const grid = this.elementRef.nativeElement;\n this.listener = (e: Event): void => this.responsiveChange.emit((e as CustomEvent<ResponsiveChangeDetail>).detail);\n grid.addEventListener('responsive-change', this.listener);\n }\n\n ngOnDestroy(): void {\n const grid = this.elementRef.nativeElement;\n if (this.listener) {\n grid.removeEventListener('responsive-change', this.listener);\n this.listener = undefined;\n }\n unregisterFeatureClaim(grid, 'responsive');\n unclaimEvent(grid, 'responsive-change');\n }\n}\n","/**\n * Responsive feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `[responsive]` input on the `Grid`\n * directive AND to wire `<tbw-grid-responsive-card>` Angular templates into\n * the ResponsivePlugin's `cardRenderer`.\n *\n * @example\n * ```typescript\n * // In your bootstrap (e.g. main.ts or app.component.ts):\n * import '@toolbox-web/grid-angular/features/responsive';\n * ```\n *\n * ```html\n * <tbw-grid [responsive]=\"{ breakpoint: 768 }\">\n * <tbw-grid-responsive-card>\n * <ng-template let-row>...</ng-template>\n * </tbw-grid-responsive-card>\n * </tbw-grid>\n * ```\n *\n * @packageDocumentation\n */\n\nimport {\n getResponsiveCardTemplate,\n registerResponsiveCardRendererBridge,\n registerTemplateBridge,\n type GridAdapter,\n type GridResponsiveCardContext,\n} from '@toolbox-web/grid-angular';\nimport '@toolbox-web/grid/features/responsive';\nexport { GridResponsiveDirective } from './grid-responsive.directive';\nexport type { _Augmentation as _ResponsiveAugmentation } from '@toolbox-web/grid/features/responsive';\n\n/**\n * Subset of `ResponsivePlugin` we touch from the bridge. Avoids importing\n * the plugin class itself.\n */\ninterface ResponsivePluginLike {\n setCardRenderer?: (renderer: (row: unknown, rowIndex: number) => HTMLElement) => void;\n}\n\n// Install the row renderer bridge on the adapter. This is what\n// `adapter.createResponsiveCardRenderer(grid)` and\n// `adapter.parseResponsiveCardElement(el)` delegate to. Without this import,\n// both methods return undefined.\nregisterResponsiveCardRendererBridge(<TRow = unknown>(gridElement: HTMLElement, adapter: GridAdapter) => {\n // Type inferred from `getResponsiveCardTemplate` (same package instance as\n // `adapter`), not from a local `import type { TemplateRef } from '@angular/core'`\n // — the latter resolves through Bun's `.bun/` cache during ng-packagr build\n // and produces a brand-incompatible TemplateRef vs the built adapter `.d.ts`.\n const template = getResponsiveCardTemplate(gridElement);\n if (!template) return undefined;\n\n return (row: TRow, rowIndex: number) => {\n const context: GridResponsiveCardContext<TRow> = { $implicit: row, row, index: rowIndex };\n const viewRef = adapter.createTrackedEmbeddedView(template, context);\n const container = document.createElement('div');\n viewRef.rootNodes.forEach((node: Node) => container.appendChild(node));\n return container;\n };\n});\n\n// Wire <tbw-grid-responsive-card> Angular templates into the ResponsivePlugin\n// once content templates are registered. Runs from `Grid.ngAfterContentInit`\n// via the template-bridge registry.\nregisterTemplateBridge(({ grid, adapter }) => {\n // Only act when the user actually placed a <tbw-grid-responsive-card> in light DOM.\n const cardElement = grid.querySelector('tbw-grid-responsive-card');\n if (!cardElement) return;\n\n // Build a card renderer from the Angular template.\n const cardRenderer = adapter.createResponsiveCardRenderer(grid);\n if (!cardRenderer) return;\n\n // The plugin must already have been attached (via [responsive] input,\n // gridConfig.features.responsive, or gridConfig.plugins). Use the runtime\n // lookup so we don't miss plugins instantiated from `gridConfig.features`,\n // which never appear in `gridConfig.plugins`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const existingPlugin = (grid as any).getPluginByName?.('responsive') as ResponsivePluginLike | undefined;\n\n if (!existingPlugin) {\n console.warn(\n '[tbw-grid-angular] <tbw-grid-responsive-card> found but ResponsivePlugin is not configured.\\n' +\n 'Add the [responsive] input, set gridConfig.features.responsive, or include\\n' +\n 'ResponsivePlugin in gridConfig.plugins:\\n\\n' +\n ' <tbw-grid [responsive]=\"{ breakpoint: 600 }\">...</tbw-grid>\\n\\n' +\n 'or:\\n\\n' +\n ' gridConfig = { features: { responsive: { breakpoint: 600 } } };',\n );\n return;\n }\n\n existingPlugin.setCardRenderer?.(cardRenderer as (row: unknown, rowIndex: number) => HTMLElement);\n});\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"toolbox-web-grid-angular-features-responsive.mjs","sources":["../../../../libs/grid-angular/features/responsive/src/grid-responsive.directive.ts","../../../../libs/grid-angular/features/responsive/src/index.ts","../../../../libs/grid-angular/features/responsive/src/toolbox-web-grid-angular-features-responsive.ts"],"sourcesContent":["/**\n * `GridResponsiveDirective` — owns `[responsive]` and `(responsiveChange)`\n * on `<tbw-grid>`. See `GridFilteringDirective` for the full rationale.\n *\n * @category Directive\n */\nimport { Directive, ElementRef, inject, input, OnDestroy, OnInit, output, type Type } from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport { claimEvent, registerFeatureClaim, unclaimEvent, unregisterFeatureClaim } from '@toolbox-web/grid-angular';\nimport type {\n ResponsivePluginConfig as CoreResponsivePluginConfig,\n ResponsiveChangeDetail,\n} from '@toolbox-web/grid/plugins/responsive';\n\n/**\n * Angular-specific responsive config that allows an Angular component class\n * as `cardRenderer`.\n *\n * Extends the core `ResponsivePluginConfig` to accept a `Type<unknown>` for\n * `cardRenderer` in addition to the vanilla\n * `(row, rowIndex, column?) => HTMLElement` signature. Bridging to vanilla\n * DOM is handled by the side-effect import\n * `@toolbox-web/grid-angular/features/responsive`.\n *\n * Re-exported from the feature entry under the same name as the core type\n * so Angular consumers see a single canonical `ResponsivePluginConfig` from\n * `@toolbox-web/grid-angular/features/responsive`.\n *\n * @since 1.7.1\n */\nexport type ResponsivePluginConfig<TRow = unknown> = Omit<CoreResponsivePluginConfig<TRow>, 'cardRenderer'> & {\n cardRenderer?: CoreResponsivePluginConfig<TRow>['cardRenderer'] | Type<unknown>;\n};\n\n/**\n * Owns the binding(s) `[responsive], [responsiveChange]` on `<tbw-grid>` for the matching feature plugin. See `GridFilteringDirective` for the full rationale.\n *\n * @category Directive\n */\n@Directive({\n selector: 'tbw-grid[responsive], tbw-grid[responsiveChange]',\n standalone: true,\n})\nexport class GridResponsiveDirective implements OnInit, OnDestroy {\n private readonly elementRef = inject(ElementRef<DataGridElement>);\n\n readonly responsive = input<boolean | ResponsivePluginConfig>();\n readonly responsiveChange = output<ResponsiveChangeDetail>();\n\n private listener?: (e: Event) => void;\n\n constructor() {\n const grid = this.elementRef.nativeElement;\n registerFeatureClaim(grid, 'responsive', () => this.responsive());\n claimEvent(grid, 'responsive-change');\n }\n\n ngOnInit(): void {\n const grid = this.elementRef.nativeElement;\n this.listener = (e: Event): void => this.responsiveChange.emit((e as CustomEvent<ResponsiveChangeDetail>).detail);\n grid.addEventListener('responsive-change', this.listener);\n }\n\n ngOnDestroy(): void {\n const grid = this.elementRef.nativeElement;\n if (this.listener) {\n grid.removeEventListener('responsive-change', this.listener);\n this.listener = undefined;\n }\n unregisterFeatureClaim(grid, 'responsive');\n unclaimEvent(grid, 'responsive-change');\n }\n}\n","/**\n * Responsive feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `[responsive]` input on the `Grid`\n * directive AND to wire `<tbw-grid-responsive-card>` Angular templates into\n * the ResponsivePlugin's `cardRenderer`.\n *\n * @example\n * ```typescript\n * // In your bootstrap (e.g. main.ts or app.component.ts):\n * import '@toolbox-web/grid-angular/features/responsive';\n * ```\n *\n * ```html\n * <tbw-grid [responsive]=\"{ breakpoint: 768 }\">\n * <tbw-grid-responsive-card>\n * <ng-template let-row>...</ng-template>\n * </tbw-grid-responsive-card>\n * </tbw-grid>\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { Type } from '@angular/core';\nimport {\n getResponsiveCardTemplate,\n isComponentClass,\n registerFeatureConfigPreprocessor,\n registerResponsiveCardRendererBridge,\n registerTemplateBridge,\n type GridAdapter,\n type GridResponsiveCardContext,\n} from '@toolbox-web/grid-angular';\nimport '@toolbox-web/grid/features/responsive';\nimport type { ResponsivePluginConfig } from './grid-responsive.directive';\nexport { GridResponsiveDirective } from './grid-responsive.directive';\nexport type { ResponsivePluginConfig } from './grid-responsive.directive';\nexport type { _Augmentation as _ResponsiveAugmentation } from '@toolbox-web/grid/features/responsive';\n\n/**\n * Subset of `ResponsivePlugin` we touch from the bridge. Avoids importing\n * the plugin class itself.\n */\ninterface ResponsivePluginLike {\n setCardRenderer?: (renderer: (row: unknown, rowIndex: number) => HTMLElement) => void;\n}\n\n// Install the row renderer bridge on the adapter. This is what\n// `adapter.createResponsiveCardRenderer(grid)` and\n// `adapter.parseResponsiveCardElement(el)` delegate to. Without this import,\n// both methods return undefined.\nregisterResponsiveCardRendererBridge(<TRow = unknown>(gridElement: HTMLElement, adapter: GridAdapter) => {\n // Type inferred from `getResponsiveCardTemplate` (same package instance as\n // `adapter`), not from a local `import type { TemplateRef } from '@angular/core'`\n // — the latter resolves through Bun's `.bun/` cache during ng-packagr build\n // and produces a brand-incompatible TemplateRef vs the built adapter `.d.ts`.\n const template = getResponsiveCardTemplate(gridElement);\n if (!template) return undefined;\n\n return (row: TRow, rowIndex: number) => {\n const context: GridResponsiveCardContext<TRow> = { $implicit: row, row, index: rowIndex };\n const viewRef = adapter.createTrackedEmbeddedView(template, context);\n const container = document.createElement('div');\n viewRef.rootNodes.forEach((node: Node) => container.appendChild(node));\n return container;\n };\n});\n\n// Wire <tbw-grid-responsive-card> Angular templates into the ResponsivePlugin\n// once content templates are registered. Runs from `Grid.ngAfterContentInit`\n// via the template-bridge registry.\nregisterTemplateBridge(({ grid, adapter }) => {\n // Only act when the user actually placed a <tbw-grid-responsive-card> in light DOM.\n const cardElement = grid.querySelector('tbw-grid-responsive-card');\n if (!cardElement) return;\n\n // Build a card renderer from the Angular template.\n const cardRenderer = adapter.createResponsiveCardRenderer(grid);\n if (!cardRenderer) return;\n\n // The plugin must already have been attached (via [responsive] input,\n // gridConfig.features.responsive, or gridConfig.plugins). Use the runtime\n // lookup so we don't miss plugins instantiated from `gridConfig.features`,\n // which never appear in `gridConfig.plugins`.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const existingPlugin = (grid as any).getPluginByName?.('responsive') as ResponsivePluginLike | undefined;\n\n if (!existingPlugin) {\n console.warn(\n '[tbw-grid-angular] <tbw-grid-responsive-card> found but ResponsivePlugin is not configured.\\n' +\n 'Add the [responsive] input, set gridConfig.features.responsive, or include\\n' +\n 'ResponsivePlugin in gridConfig.plugins:\\n\\n' +\n ' <tbw-grid [responsive]=\"{ breakpoint: 600 }\">...</tbw-grid>\\n\\n' +\n 'or:\\n\\n' +\n ' gridConfig = { features: { responsive: { breakpoint: 600 } } };',\n );\n return;\n }\n\n existingPlugin.setCardRenderer?.(cardRenderer as (row: unknown, rowIndex: number) => HTMLElement);\n});\n\n/**\n * Bridge any Angular component class used as `responsive.cardRenderer` to a\n * plain `(row, rowIndex, column?) => HTMLElement` function before the core\n * plugin factory consumes the config. Without this preprocessor, a component\n * class passed as `cardRenderer` would be invoked as a function at render\n * time and crash. Light-DOM `<tbw-grid-responsive-card>` templates continue\n * to win via the post-mount template bridge above.\n *\n * @since 1.7.1\n */\nregisterFeatureConfigPreprocessor('responsive', (config, adapter) => {\n if (!config || typeof config !== 'object') return config;\n const cfg = config as ResponsivePluginConfig;\n if (!isComponentClass(cfg.cardRenderer)) return config;\n\n const componentClass = cfg.cardRenderer as Type<unknown>;\n const mount = adapter.mountComponentRenderer<{ row: unknown; rowIndex: number; column?: unknown }>(\n componentClass,\n (ctx) => ({ row: ctx.row, rowIndex: ctx.rowIndex, column: ctx.column }),\n );\n const cached = new Map<unknown, HTMLElement>();\n const cardRenderer: NonNullable<ResponsivePluginConfig['cardRenderer']> = (row, rowIndex, column) => {\n const existing = cached.get(row);\n if (existing) return existing;\n const { hostElement } = mount({ row, rowIndex, column });\n cached.set(row, hostElement);\n return hostElement;\n };\n return { ...cfg, cardRenderer };\n});\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ElementRef, contentChild, TemplateRef, effect, Directive, DestroyRef, input, InjectionToken, Injectable, makeEnvironmentProviders, createComponent, signal, afterNextRender, computed, output, EnvironmentInjector, ApplicationRef, ViewContainerRef } from '@angular/core';
2
+ import { inject, ElementRef, contentChild, TemplateRef, effect, Directive, DestroyRef, input, InjectionToken, Injectable, makeEnvironmentProviders, createComponent, signal, afterNextRender, computed, output, ViewContainerRef, EnvironmentInjector, ApplicationRef } from '@angular/core';
3
3
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
4
4
  import { FormGroup } from '@angular/forms';
5
5
  import { startWith, debounceTime } from 'rxjs/operators';
@@ -2666,6 +2666,20 @@ function injectGrid(selector = 'tbw-grid') {
2666
2666
  };
2667
2667
  }
2668
2668
 
2669
+ // @internal Types-only barrel: pulls core feature modules onto ng-packagr's type
2670
+ // graph so FeatureConfig augmentations merge before emit. See
2671
+ // .github/knowledge/adapters-angular.md ("FeatureName derivation"). Use `//` not
2672
+ // `/** */` — terser preserves JSDoc in the fesm bundle (~1.5 KiB cost).
2673
+ //
2674
+ // Each line re-exports the core feature's `_Augmentation` anchor type under a
2675
+ // unique local name. This is functionally equivalent to
2676
+ // `import type {} from '@toolbox-web/grid/features/<name>'` but survives
2677
+ // Prettier / organize-imports, which strip empty-brace imports as unused.
2678
+ // The re-exports are type-only (zero runtime cost) and stay internal because
2679
+ // `feature-registry.ts` consumes this file with a bare side-effect import
2680
+ // (`import './internal/feature-augmentations'`), not a re-export.
2681
+ // Append a new line whenever a core feature is added.
2682
+
2669
2683
  /**
2670
2684
  * Feature Registry for @toolbox-web/grid-angular
2671
2685
  *
@@ -3999,6 +4013,155 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
3999
4013
  args: [{ selector: 'tbw-grid-detail' }]
4000
4014
  }], propDecorators: { showExpandColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "showExpandColumn", required: false }] }], animation: [{ type: i0.Input, args: [{ isSignal: true, alias: "animation", required: false }] }], template: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
4001
4015
 
4016
+ let autoIdCounter$1 = 0;
4017
+ /**
4018
+ * Declarative wrapper around the grid's imperative
4019
+ * {@link DataGridElement.registerHeaderContent} API.
4020
+ *
4021
+ * Captures an `<ng-template>` and mounts it as an Angular embedded view into
4022
+ * the slot the grid provides for header content. Must be a child of
4023
+ * `<tbw-grid>`.
4024
+ *
4025
+ * ## Usage
4026
+ *
4027
+ * ```html
4028
+ * <tbw-grid [rows]="rows" [gridConfig]="config">
4029
+ * <tbw-grid-header-content id="calendar-nav" [order]="0">
4030
+ * <ng-template let-grid>
4031
+ * <app-header-nav [year]="year()" (yearChange)="setYear($event)" />
4032
+ * </ng-template>
4033
+ * </tbw-grid-header-content>
4034
+ * </tbw-grid>
4035
+ * ```
4036
+ *
4037
+ * @category Directive
4038
+ * @since 1.7.0
4039
+ */
4040
+ class GridHeaderContent {
4041
+ elementRef = inject((ElementRef));
4042
+ viewContainerRef = inject(ViewContainerRef);
4043
+ destroyRef = inject(DestroyRef);
4044
+ /** Unique identifier for this header content entry. Optional — defaults to a stable generated id. */
4045
+ id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
4046
+ /** Render order priority. Lower values appear first. @default 100 */
4047
+ order = input(100, ...(ngDevMode ? [{ debugName: "order" }] : /* istanbul ignore next */ []));
4048
+ /** The template to mount into the grid's header content slot. */
4049
+ template = contentChild((TemplateRef), ...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
4050
+ viewRef = null;
4051
+ registeredId = null;
4052
+ resolvedId = `tbw-header-content-${++autoIdCounter$1}`;
4053
+ destroyed = false;
4054
+ constructor() {
4055
+ afterNextRender(() => {
4056
+ void this.register();
4057
+ });
4058
+ this.destroyRef.onDestroy(() => {
4059
+ this.destroyed = true;
4060
+ this.unregister();
4061
+ });
4062
+ // Re-register when id or order changes after mount.
4063
+ effect(() => {
4064
+ const nextId = this.id() ?? this.resolvedId;
4065
+ const nextOrder = this.order();
4066
+ if (this.registeredId && this.registeredId !== nextId) {
4067
+ this.unregister();
4068
+ void this.register();
4069
+ return;
4070
+ }
4071
+ if (this.registeredId && nextOrder !== this.lastOrder) {
4072
+ this.unregister();
4073
+ void this.register();
4074
+ }
4075
+ this.lastOrder = nextOrder;
4076
+ });
4077
+ }
4078
+ lastOrder;
4079
+ async register() {
4080
+ const grid = this.findGrid();
4081
+ if (!grid)
4082
+ return;
4083
+ try {
4084
+ await grid.ready?.();
4085
+ }
4086
+ catch {
4087
+ return;
4088
+ }
4089
+ if (this.destroyed)
4090
+ return;
4091
+ const template = this.template();
4092
+ const id = this.id() ?? this.resolvedId;
4093
+ const order = this.order();
4094
+ const def = {
4095
+ id,
4096
+ order,
4097
+ render: (container) => {
4098
+ if (!template)
4099
+ return undefined;
4100
+ // Sticky container: the shell may re-invoke `render` with the SAME
4101
+ // container across refreshes. If our embedded view is still attached
4102
+ // inside it, the previous render is live and this is a refresh — do
4103
+ // nothing (no-op cleanup preserves child state).
4104
+ const firstNode = this.viewRef?.rootNodes[0];
4105
+ if (this.viewRef && firstNode && container.contains(firstNode)) {
4106
+ return () => {
4107
+ /* intentionally empty */
4108
+ };
4109
+ }
4110
+ // Fresh container (first render or container was replaced) — destroy
4111
+ // any stale view, then build a new one.
4112
+ if (this.viewRef) {
4113
+ this.viewRef.destroy();
4114
+ this.viewRef = null;
4115
+ }
4116
+ this.viewRef = this.viewContainerRef.createEmbeddedView(template, {
4117
+ $implicit: grid,
4118
+ grid,
4119
+ });
4120
+ this.viewRef.detectChanges();
4121
+ for (const node of this.viewRef.rootNodes) {
4122
+ container.appendChild(node);
4123
+ }
4124
+ // No-op cleanup: the grid may call this between re-renders before
4125
+ // invoking `render` again with the SAME container. Tearing the view
4126
+ // down here would destroy any internal state in the projected
4127
+ // template on every shell refresh. Teardown happens in `unregister`
4128
+ // (component destroy / id / order change).
4129
+ return () => {
4130
+ /* intentionally empty */
4131
+ };
4132
+ },
4133
+ };
4134
+ grid.registerHeaderContent?.(def);
4135
+ this.registeredId = id;
4136
+ }
4137
+ unregister() {
4138
+ const grid = this.findGrid();
4139
+ if (grid && this.registeredId) {
4140
+ grid.unregisterHeaderContent?.(this.registeredId);
4141
+ }
4142
+ this.registeredId = null;
4143
+ if (this.viewRef) {
4144
+ this.viewRef.destroy();
4145
+ this.viewRef = null;
4146
+ }
4147
+ }
4148
+ findGrid() {
4149
+ const host = this.elementRef.nativeElement;
4150
+ const grid = host.closest('tbw-grid');
4151
+ return grid;
4152
+ }
4153
+ /** Type guard for template context inference. */
4154
+ static ngTemplateContextGuard(_dir, ctx) {
4155
+ return true;
4156
+ }
4157
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridHeaderContent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4158
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.5", type: GridHeaderContent, isStandalone: true, selector: "tbw-grid-header-content", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, order: { classPropertyName: "order", publicName: "order", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "template", first: true, predicate: (TemplateRef), descendants: true, isSignal: true }], ngImport: i0 });
4159
+ }
4160
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridHeaderContent, decorators: [{
4161
+ type: Directive,
4162
+ args: [{ selector: 'tbw-grid-header-content', standalone: true }]
4163
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], order: [{ type: i0.Input, args: [{ isSignal: true, alias: "order", required: false }] }], template: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
4164
+
4002
4165
  /**
4003
4166
  * Directive that registers `<tbw-grid-header>` as a known Angular element.
4004
4167
  *
@@ -4672,6 +4835,144 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
4672
4835
  }]
4673
4836
  }] });
4674
4837
 
4838
+ let autoIdCounter = 0;
4839
+ /**
4840
+ * Declarative wrapper around the grid's imperative
4841
+ * {@link DataGridElement.registerToolbarContent} API.
4842
+ *
4843
+ * Captures an `<ng-template>` and mounts it as an Angular embedded view into
4844
+ * the slot the grid provides for toolbar content. Must be a child of
4845
+ * `<tbw-grid>`.
4846
+ *
4847
+ * Prefer this over `<tbw-grid-tool-buttons>` (light DOM) when you need
4848
+ * Angular template bindings to component state. Use the light-DOM form for
4849
+ * static markup that should be moved verbatim into the toolbar.
4850
+ *
4851
+ * ## Usage
4852
+ *
4853
+ * ```html
4854
+ * <tbw-grid [rows]="rows" [gridConfig]="config">
4855
+ * <tbw-grid-toolbar-content id="calendar-nav" [order]="0">
4856
+ * <ng-template let-grid>
4857
+ * <app-toolbar-nav (prev)="prev()" (today)="today()" (next)="next()" />
4858
+ * </ng-template>
4859
+ * </tbw-grid-toolbar-content>
4860
+ * </tbw-grid>
4861
+ * ```
4862
+ *
4863
+ * @category Directive
4864
+ * @since 1.7.0
4865
+ */
4866
+ class GridToolbarContent {
4867
+ elementRef = inject((ElementRef));
4868
+ viewContainerRef = inject(ViewContainerRef);
4869
+ destroyRef = inject(DestroyRef);
4870
+ id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
4871
+ order = input(100, ...(ngDevMode ? [{ debugName: "order" }] : /* istanbul ignore next */ []));
4872
+ template = contentChild((TemplateRef), ...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
4873
+ viewRef = null;
4874
+ registeredId = null;
4875
+ resolvedId = `tbw-toolbar-content-${++autoIdCounter}`;
4876
+ lastOrder;
4877
+ destroyed = false;
4878
+ constructor() {
4879
+ afterNextRender(() => {
4880
+ void this.register();
4881
+ });
4882
+ this.destroyRef.onDestroy(() => {
4883
+ this.destroyed = true;
4884
+ this.unregister();
4885
+ });
4886
+ effect(() => {
4887
+ const nextId = this.id() ?? this.resolvedId;
4888
+ const nextOrder = this.order();
4889
+ if (this.registeredId && this.registeredId !== nextId) {
4890
+ this.unregister();
4891
+ void this.register();
4892
+ return;
4893
+ }
4894
+ if (this.registeredId && nextOrder !== this.lastOrder) {
4895
+ this.unregister();
4896
+ void this.register();
4897
+ }
4898
+ this.lastOrder = nextOrder;
4899
+ });
4900
+ }
4901
+ async register() {
4902
+ const grid = this.findGrid();
4903
+ if (!grid)
4904
+ return;
4905
+ try {
4906
+ await grid.ready?.();
4907
+ }
4908
+ catch {
4909
+ return;
4910
+ }
4911
+ if (this.destroyed)
4912
+ return;
4913
+ const template = this.template();
4914
+ const id = this.id() ?? this.resolvedId;
4915
+ const order = this.order();
4916
+ const def = {
4917
+ id,
4918
+ order,
4919
+ render: (container) => {
4920
+ if (!template)
4921
+ return undefined;
4922
+ // Sticky container: see grid-header-content.directive.ts for rationale.
4923
+ const firstNode = this.viewRef?.rootNodes[0];
4924
+ if (this.viewRef && firstNode && container.contains(firstNode)) {
4925
+ return () => {
4926
+ /* intentionally empty */
4927
+ };
4928
+ }
4929
+ if (this.viewRef) {
4930
+ this.viewRef.destroy();
4931
+ this.viewRef = null;
4932
+ }
4933
+ this.viewRef = this.viewContainerRef.createEmbeddedView(template, {
4934
+ $implicit: grid,
4935
+ grid,
4936
+ });
4937
+ this.viewRef.detectChanges();
4938
+ for (const node of this.viewRef.rootNodes) {
4939
+ container.appendChild(node);
4940
+ }
4941
+ // No-op cleanup — see comment in grid-header-content.directive.ts.
4942
+ return () => {
4943
+ /* intentionally empty */
4944
+ };
4945
+ },
4946
+ };
4947
+ grid.registerToolbarContent?.(def);
4948
+ this.registeredId = id;
4949
+ }
4950
+ unregister() {
4951
+ const grid = this.findGrid();
4952
+ if (grid && this.registeredId) {
4953
+ grid.unregisterToolbarContent?.(this.registeredId);
4954
+ }
4955
+ this.registeredId = null;
4956
+ if (this.viewRef) {
4957
+ this.viewRef.destroy();
4958
+ this.viewRef = null;
4959
+ }
4960
+ }
4961
+ findGrid() {
4962
+ const host = this.elementRef.nativeElement;
4963
+ return host.closest('tbw-grid');
4964
+ }
4965
+ static ngTemplateContextGuard(_dir, ctx) {
4966
+ return true;
4967
+ }
4968
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridToolbarContent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4969
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.5", type: GridToolbarContent, isStandalone: true, selector: "tbw-grid-toolbar-content", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, order: { classPropertyName: "order", publicName: "order", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "template", first: true, predicate: (TemplateRef), descendants: true, isSignal: true }], ngImport: i0 });
4970
+ }
4971
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridToolbarContent, decorators: [{
4972
+ type: Directive,
4973
+ args: [{ selector: 'tbw-grid-toolbar-content', standalone: true }]
4974
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], order: [{ type: i0.Input, args: [{ isSignal: true, alias: "order", required: false }] }], template: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
4975
+
4675
4976
  /** Capitalize the first letter of a string for header generation. */
4676
4977
  function capitalize(str) {
4677
4978
  return str.charAt(0).toUpperCase() + str.slice(1);
@@ -6103,6 +6404,24 @@ class Grid {
6103
6404
  * ```
6104
6405
  */
6105
6406
  tbwScroll = output();
6407
+ /**
6408
+ * Emitted once at the end of every render-scheduler flush, after all
6409
+ * plugin `afterRender` hooks have run and `ready()` has resolved.
6410
+ *
6411
+ * Use this to act on the rendered DOM after a programmatic mutation
6412
+ * (e.g. focus the first input of a freshly added row in full-grid edit
6413
+ * mode) without `setTimeout` or double-`requestAnimationFrame` hacks.
6414
+ * The `render` event fires on every flush — including scroll-driven
6415
+ * virtual-window updates — so prefer subscribing once and unsubscribing
6416
+ * (or gating on `detail.phase >= RenderPhase.ROWS`) when you only care
6417
+ * about a specific mutation.
6418
+ *
6419
+ * @example
6420
+ * ```html
6421
+ * <tbw-grid (render)="onRender($event)">...</tbw-grid>
6422
+ * ```
6423
+ */
6424
+ render = output();
6106
6425
  // Map of output names to event names for automatic wiring.
6107
6426
  //
6108
6427
  // The `satisfies` clause enforces compile-time sync against
@@ -6152,6 +6471,7 @@ class Grid {
6152
6471
  printStart: 'print-start',
6153
6472
  printComplete: 'print-complete',
6154
6473
  tbwScroll: 'tbw-scroll',
6474
+ render: 'render',
6155
6475
  };
6156
6476
  // ─────────────────────────────────────────────────────────────────────────
6157
6477
  // Forward-only event coverage guard.
@@ -6341,12 +6661,12 @@ class Grid {
6341
6661
  }
6342
6662
  }
6343
6663
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: Grid, deps: [], target: i0.ɵɵFactoryTarget.Directive });
6344
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", 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 }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, columnDefaults: { classPropertyName: "columnDefaults", publicName: "columnDefaults", isSignal: true, isRequired: false, transformFunction: null }, fitMode: { classPropertyName: "fitMode", publicName: "fitMode", isSignal: true, isRequired: false, transformFunction: null }, gridConfig: { classPropertyName: "gridConfig", publicName: "gridConfig", 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 }, filtering: { classPropertyName: "filtering", publicName: "filtering", isSignal: true, isRequired: false, transformFunction: null }, reorderColumns: { classPropertyName: "reorderColumns", publicName: "reorderColumns", 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 }, reorderRows: { classPropertyName: "reorderRows", publicName: "reorderRows", isSignal: true, isRequired: false, transformFunction: null }, rowDragDrop: { classPropertyName: "rowDragDrop", publicName: "rowDragDrop", 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: "export", 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 }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellClick: "cellClick", rowClick: "rowClick", cellActivate: "cellActivate", cellChange: "cellChange", cellCommit: "cellCommit", cellCancel: "cellCancel", editOpen: "editOpen", beforeEditClose: "beforeEditClose", editClose: "editClose", dirtyChange: "dirtyChange", dataChange: "dataChange", rowCommit: "rowCommit", changedRowsReset: "changedRowsReset", sortChange: "sortChange", filterChange: "filterChange", columnResize: "columnResize", columnResizeReset: "columnResizeReset", columnMove: "columnMove", columnVisibility: "columnVisibility", columnStateChange: "columnStateChange", selectionChange: "selectionChange", rowMove: "rowMove", rowDragStart: "rowDragStart", rowDragEnd: "rowDragEnd", rowDrop: "rowDrop", rowTransfer: "rowTransfer", groupToggle: "groupToggle", groupExpand: "groupExpand", groupCollapse: "groupCollapse", treeExpand: "treeExpand", detailExpand: "detailExpand", responsiveChange: "responsiveChange", contextMenuOpen: "contextMenuOpen", copy: "copy", paste: "paste", undo: "undo", redo: "redo", exportComplete: "exportComplete", printStart: "printStart", printComplete: "printComplete", tbwScroll: "tbwScroll" }, ngImport: i0 });
6664
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", 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 }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, columnDefaults: { classPropertyName: "columnDefaults", publicName: "columnDefaults", isSignal: true, isRequired: false, transformFunction: null }, fitMode: { classPropertyName: "fitMode", publicName: "fitMode", isSignal: true, isRequired: false, transformFunction: null }, gridConfig: { classPropertyName: "gridConfig", publicName: "gridConfig", 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 }, filtering: { classPropertyName: "filtering", publicName: "filtering", isSignal: true, isRequired: false, transformFunction: null }, reorderColumns: { classPropertyName: "reorderColumns", publicName: "reorderColumns", 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 }, reorderRows: { classPropertyName: "reorderRows", publicName: "reorderRows", isSignal: true, isRequired: false, transformFunction: null }, rowDragDrop: { classPropertyName: "rowDragDrop", publicName: "rowDragDrop", 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: "export", 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 }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellClick: "cellClick", rowClick: "rowClick", cellActivate: "cellActivate", cellChange: "cellChange", cellCommit: "cellCommit", cellCancel: "cellCancel", editOpen: "editOpen", beforeEditClose: "beforeEditClose", editClose: "editClose", dirtyChange: "dirtyChange", dataChange: "dataChange", rowCommit: "rowCommit", changedRowsReset: "changedRowsReset", sortChange: "sortChange", filterChange: "filterChange", columnResize: "columnResize", columnResizeReset: "columnResizeReset", columnMove: "columnMove", columnVisibility: "columnVisibility", columnStateChange: "columnStateChange", selectionChange: "selectionChange", rowMove: "rowMove", rowDragStart: "rowDragStart", rowDragEnd: "rowDragEnd", rowDrop: "rowDrop", rowTransfer: "rowTransfer", groupToggle: "groupToggle", groupExpand: "groupExpand", groupCollapse: "groupCollapse", treeExpand: "treeExpand", detailExpand: "detailExpand", responsiveChange: "responsiveChange", contextMenuOpen: "contextMenuOpen", copy: "copy", paste: "paste", undo: "undo", redo: "redo", exportComplete: "exportComplete", printStart: "printStart", printComplete: "printComplete", tbwScroll: "tbwScroll", render: "render" }, ngImport: i0 });
6345
6665
  }
6346
6666
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: Grid, decorators: [{
6347
6667
  type: Directive,
6348
6668
  args: [{ selector: 'tbw-grid' }]
6349
- }], 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 }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], columnDefaults: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnDefaults", required: false }] }], fitMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "fitMode", required: false }] }], gridConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "gridConfig", 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 }] }], filtering: [{ type: i0.Input, args: [{ isSignal: true, alias: "filtering", required: false }] }], reorderColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderColumns", 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 }] }], reorderRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderRows", required: false }] }], rowDragDrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowDragDrop", 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: "export", 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 }] }], tooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltip", 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"] }], cellCancel: [{ type: i0.Output, args: ["cellCancel"] }], editOpen: [{ type: i0.Output, args: ["editOpen"] }], beforeEditClose: [{ type: i0.Output, args: ["beforeEditClose"] }], editClose: [{ type: i0.Output, args: ["editClose"] }], dirtyChange: [{ type: i0.Output, args: ["dirtyChange"] }], dataChange: [{ type: i0.Output, args: ["dataChange"] }], 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"] }], columnResizeReset: [{ type: i0.Output, args: ["columnResizeReset"] }], 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"] }], rowDragStart: [{ type: i0.Output, args: ["rowDragStart"] }], rowDragEnd: [{ type: i0.Output, args: ["rowDragEnd"] }], rowDrop: [{ type: i0.Output, args: ["rowDrop"] }], rowTransfer: [{ type: i0.Output, args: ["rowTransfer"] }], groupToggle: [{ type: i0.Output, args: ["groupToggle"] }], groupExpand: [{ type: i0.Output, args: ["groupExpand"] }], groupCollapse: [{ type: i0.Output, args: ["groupCollapse"] }], treeExpand: [{ type: i0.Output, args: ["treeExpand"] }], detailExpand: [{ type: i0.Output, args: ["detailExpand"] }], responsiveChange: [{ type: i0.Output, args: ["responsiveChange"] }], contextMenuOpen: [{ type: i0.Output, args: ["contextMenuOpen"] }], copy: [{ type: i0.Output, args: ["copy"] }], paste: [{ type: i0.Output, args: ["paste"] }], undo: [{ type: i0.Output, args: ["undo"] }], redo: [{ type: i0.Output, args: ["redo"] }], exportComplete: [{ type: i0.Output, args: ["exportComplete"] }], printStart: [{ type: i0.Output, args: ["printStart"] }], printComplete: [{ type: i0.Output, args: ["printComplete"] }], tbwScroll: [{ type: i0.Output, args: ["tbwScroll"] }] } });
6669
+ }], 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 }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], columnDefaults: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnDefaults", required: false }] }], fitMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "fitMode", required: false }] }], gridConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "gridConfig", 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 }] }], filtering: [{ type: i0.Input, args: [{ isSignal: true, alias: "filtering", required: false }] }], reorderColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderColumns", 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 }] }], reorderRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderRows", required: false }] }], rowDragDrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowDragDrop", 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: "export", 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 }] }], tooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltip", 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"] }], cellCancel: [{ type: i0.Output, args: ["cellCancel"] }], editOpen: [{ type: i0.Output, args: ["editOpen"] }], beforeEditClose: [{ type: i0.Output, args: ["beforeEditClose"] }], editClose: [{ type: i0.Output, args: ["editClose"] }], dirtyChange: [{ type: i0.Output, args: ["dirtyChange"] }], dataChange: [{ type: i0.Output, args: ["dataChange"] }], 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"] }], columnResizeReset: [{ type: i0.Output, args: ["columnResizeReset"] }], 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"] }], rowDragStart: [{ type: i0.Output, args: ["rowDragStart"] }], rowDragEnd: [{ type: i0.Output, args: ["rowDragEnd"] }], rowDrop: [{ type: i0.Output, args: ["rowDrop"] }], rowTransfer: [{ type: i0.Output, args: ["rowTransfer"] }], groupToggle: [{ type: i0.Output, args: ["groupToggle"] }], groupExpand: [{ type: i0.Output, args: ["groupExpand"] }], groupCollapse: [{ type: i0.Output, args: ["groupCollapse"] }], treeExpand: [{ type: i0.Output, args: ["treeExpand"] }], detailExpand: [{ type: i0.Output, args: ["detailExpand"] }], responsiveChange: [{ type: i0.Output, args: ["responsiveChange"] }], contextMenuOpen: [{ type: i0.Output, args: ["contextMenuOpen"] }], copy: [{ type: i0.Output, args: ["copy"] }], paste: [{ type: i0.Output, args: ["paste"] }], undo: [{ type: i0.Output, args: ["undo"] }], redo: [{ type: i0.Output, args: ["redo"] }], exportComplete: [{ type: i0.Output, args: ["exportComplete"] }], printStart: [{ type: i0.Output, args: ["printStart"] }], printComplete: [{ type: i0.Output, args: ["printComplete"] }], tbwScroll: [{ type: i0.Output, args: ["tbwScroll"] }], render: [{ type: i0.Output, args: ["render"] }] } });
6350
6670
 
6351
6671
  /**
6352
6672
  * Combined provider helper for grid type defaults and icons.
@@ -6409,5 +6729,5 @@ function provideGrid(options = {}) {
6409
6729
  * Generated bundle index. Do not edit.
6410
6730
  */
6411
6731
 
6412
- export { BaseFilterPanel, BaseGridEditor, BaseGridEditorCVA, BaseOverlayEditor, GRID_ICONS, GRID_TYPE_DEFAULTS, Grid, GridAdapter, GridColumnEditor, GridColumnView, GridDetailView, GridFormArray, GridIconRegistry, GridLazyForm, GridResponsiveCard, GridToolPanel, GridTypeRegistry, TbwEditor, TbwGridColumn, TbwGridHeader, TbwGridToolButtons, TbwRenderer, applyColumnDefaults, claimEvent, getDetailTemplate, getFeatureClaim, getFeatureConfigPreprocessor, getFormArrayContext, getLazyFormContext, getResponsiveCardTemplate, hasColumnShorthands, injectGrid, isComponentClass, isEventClaimed, makeFlushFocusedInput, normalizeColumns, parseColumnShorthand, provideGrid, provideGridIcons, provideGridTypeDefaults, registerDetailRendererBridge, registerEditorMountHook, registerFeatureClaim, registerFeatureConfigPreprocessor, registerFilterPanelTypeDefaultBridge, registerResponsiveCardRendererBridge, registerTemplateBridge, runTemplateBridges, unclaimEvent, unregisterFeatureClaim };
6732
+ export { BaseFilterPanel, BaseGridEditor, BaseGridEditorCVA, BaseOverlayEditor, GRID_ICONS, GRID_TYPE_DEFAULTS, Grid, GridAdapter, GridColumnEditor, GridColumnView, GridDetailView, GridFormArray, GridHeaderContent, GridIconRegistry, GridLazyForm, GridResponsiveCard, GridToolPanel, GridToolbarContent, GridTypeRegistry, TbwEditor, TbwGridColumn, TbwGridHeader, TbwGridToolButtons, TbwRenderer, applyColumnDefaults, claimEvent, getDetailTemplate, getFeatureClaim, getFeatureConfigPreprocessor, getFormArrayContext, getLazyFormContext, getResponsiveCardTemplate, hasColumnShorthands, injectGrid, isComponentClass, isEventClaimed, makeFlushFocusedInput, normalizeColumns, parseColumnShorthand, provideGrid, provideGridIcons, provideGridTypeDefaults, registerDetailRendererBridge, registerEditorMountHook, registerFeatureClaim, registerFeatureConfigPreprocessor, registerFilterPanelTypeDefaultBridge, registerResponsiveCardRendererBridge, registerTemplateBridge, runTemplateBridges, unclaimEvent, unregisterFeatureClaim };
6413
6733
  //# sourceMappingURL=toolbox-web-grid-angular.mjs.map