@toolbox-web/grid-angular 2.0.0-rc.1 → 2.0.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.
Files changed (53) hide show
  1. package/fesm2022/toolbox-web-grid-angular-features-clipboard.mjs +5 -4
  2. package/fesm2022/toolbox-web-grid-angular-features-clipboard.mjs.map +1 -1
  3. package/fesm2022/toolbox-web-grid-angular-features-column-virtualization.mjs +5 -4
  4. package/fesm2022/toolbox-web-grid-angular-features-column-virtualization.mjs.map +1 -1
  5. package/fesm2022/toolbox-web-grid-angular-features-context-menu.mjs +5 -4
  6. package/fesm2022/toolbox-web-grid-angular-features-context-menu.mjs.map +1 -1
  7. package/fesm2022/toolbox-web-grid-angular-features-editing.mjs +1537 -1510
  8. package/fesm2022/toolbox-web-grid-angular-features-editing.mjs.map +1 -1
  9. package/fesm2022/toolbox-web-grid-angular-features-export.mjs +5 -4
  10. package/fesm2022/toolbox-web-grid-angular-features-export.mjs.map +1 -1
  11. package/fesm2022/toolbox-web-grid-angular-features-filtering.mjs +12 -9
  12. package/fesm2022/toolbox-web-grid-angular-features-filtering.mjs.map +1 -1
  13. package/fesm2022/toolbox-web-grid-angular-features-grouping-columns.mjs +5 -4
  14. package/fesm2022/toolbox-web-grid-angular-features-grouping-columns.mjs.map +1 -1
  15. package/fesm2022/toolbox-web-grid-angular-features-grouping-rows.mjs +5 -4
  16. package/fesm2022/toolbox-web-grid-angular-features-grouping-rows.mjs.map +1 -1
  17. package/fesm2022/toolbox-web-grid-angular-features-master-detail.mjs +16 -11
  18. package/fesm2022/toolbox-web-grid-angular-features-master-detail.mjs.map +1 -1
  19. package/fesm2022/toolbox-web-grid-angular-features-multi-sort.mjs +5 -4
  20. package/fesm2022/toolbox-web-grid-angular-features-multi-sort.mjs.map +1 -1
  21. package/fesm2022/toolbox-web-grid-angular-features-pinned-columns.mjs +5 -4
  22. package/fesm2022/toolbox-web-grid-angular-features-pinned-columns.mjs.map +1 -1
  23. package/fesm2022/toolbox-web-grid-angular-features-pinned-rows.mjs +5 -4
  24. package/fesm2022/toolbox-web-grid-angular-features-pinned-rows.mjs.map +1 -1
  25. package/fesm2022/toolbox-web-grid-angular-features-pivot.mjs +5 -4
  26. package/fesm2022/toolbox-web-grid-angular-features-pivot.mjs.map +1 -1
  27. package/fesm2022/toolbox-web-grid-angular-features-print.mjs +7 -5
  28. package/fesm2022/toolbox-web-grid-angular-features-print.mjs.map +1 -1
  29. package/fesm2022/toolbox-web-grid-angular-features-reorder-columns.mjs +5 -4
  30. package/fesm2022/toolbox-web-grid-angular-features-reorder-columns.mjs.map +1 -1
  31. package/fesm2022/toolbox-web-grid-angular-features-responsive.mjs +16 -11
  32. package/fesm2022/toolbox-web-grid-angular-features-responsive.mjs.map +1 -1
  33. package/fesm2022/toolbox-web-grid-angular-features-row-drag-drop.mjs +5 -4
  34. package/fesm2022/toolbox-web-grid-angular-features-row-drag-drop.mjs.map +1 -1
  35. package/fesm2022/toolbox-web-grid-angular-features-selection.mjs +13 -8
  36. package/fesm2022/toolbox-web-grid-angular-features-selection.mjs.map +1 -1
  37. package/fesm2022/toolbox-web-grid-angular-features-server-side.mjs +5 -4
  38. package/fesm2022/toolbox-web-grid-angular-features-server-side.mjs.map +1 -1
  39. package/fesm2022/toolbox-web-grid-angular-features-shell.mjs +31 -20
  40. package/fesm2022/toolbox-web-grid-angular-features-shell.mjs.map +1 -1
  41. package/fesm2022/toolbox-web-grid-angular-features-sticky-rows.mjs +5 -4
  42. package/fesm2022/toolbox-web-grid-angular-features-sticky-rows.mjs.map +1 -1
  43. package/fesm2022/toolbox-web-grid-angular-features-tooltip.mjs +5 -4
  44. package/fesm2022/toolbox-web-grid-angular-features-tooltip.mjs.map +1 -1
  45. package/fesm2022/toolbox-web-grid-angular-features-tree.mjs +5 -4
  46. package/fesm2022/toolbox-web-grid-angular-features-tree.mjs.map +1 -1
  47. package/fesm2022/toolbox-web-grid-angular-features-undo-redo.mjs +11 -7
  48. package/fesm2022/toolbox-web-grid-angular-features-undo-redo.mjs.map +1 -1
  49. package/fesm2022/toolbox-web-grid-angular-features-visibility.mjs +5 -4
  50. package/fesm2022/toolbox-web-grid-angular-features-visibility.mjs.map +1 -1
  51. package/fesm2022/toolbox-web-grid-angular.mjs +61 -71
  52. package/fesm2022/toolbox-web-grid-angular.mjs.map +1 -1
  53. package/package.json +2 -2
@@ -43,10 +43,10 @@ class GridExportDirective {
43
43
  unregisterFeatureClaim(grid, 'export');
44
44
  unclaimEvent(grid, 'export-complete');
45
45
  }
46
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridExportDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
47
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: GridExportDirective, isStandalone: true, selector: "tbw-grid[export], tbw-grid[exportComplete]", inputs: { exportFeature: { classPropertyName: "exportFeature", publicName: "export", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { exportComplete: "exportComplete" }, ngImport: i0 });
46
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridExportDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
47
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: GridExportDirective, isStandalone: true, selector: "tbw-grid[export], tbw-grid[exportComplete]", inputs: { exportFeature: { classPropertyName: "exportFeature", publicName: "export", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { exportComplete: "exportComplete" }, ngImport: i0 });
48
48
  }
49
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridExportDirective, decorators: [{
49
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridExportDirective, decorators: [{
50
50
  type: Directive,
51
51
  args: [{
52
52
  selector: 'tbw-grid[export], tbw-grid[exportComplete]',
@@ -124,7 +124,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
124
124
  function injectGridExport(selector = 'tbw-grid') {
125
125
  const elementRef = inject(ElementRef);
126
126
  const destroyRef = inject(DestroyRef);
127
- const isReady = signal(false, ...(ngDevMode ? [{ debugName: "isReady" }] : /* istanbul ignore next */ []));
127
+ const isReady = signal(false, /* @ts-ignore */
128
+ ...(ngDevMode ? [{ debugName: "isReady" }] : /* istanbul ignore next */ []));
128
129
  // Lazy discovery: cached grid reference
129
130
  let cachedGrid = null;
130
131
  let readyPromiseStarted = false;
@@ -1 +1 @@
1
- {"version":3,"file":"toolbox-web-grid-angular-features-export.mjs","sources":["../../../../libs/grid-angular/features/export/src/grid-export.directive.ts","../../../../libs/grid-angular/features/export/src/index.ts","../../../../libs/grid-angular/features/export/src/toolbox-web-grid-angular-features-export.ts"],"sourcesContent":["/**\n * `GridExportDirective` — owns the `export` input (template alias of\n * `exportFeature`) and `(exportComplete)` on `<tbw-grid>`. See\n * `GridFilteringDirective` for the full rationale.\n *\n * The TypeScript field is `exportFeature` (with `alias: 'export'`) because\n * `export` is a reserved keyword. Templates use `[export]` / `(exportComplete)`\n * exactly as before.\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 { ExportCompleteDetail, ExportConfig } from '@toolbox-web/grid/plugins/export';\n\n/**\n * Owns the binding(s) `[export], [exportComplete]` 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[export], tbw-grid[exportComplete]',\n standalone: true,\n})\nexport class GridExportDirective implements OnInit, OnDestroy {\n private readonly elementRef = inject(ElementRef<DataGridElement>);\n\n readonly exportFeature = input<boolean | ExportConfig>(undefined, { alias: 'export' });\n readonly exportComplete = output<ExportCompleteDetail>();\n\n private listener?: (e: Event) => void;\n\n constructor() {\n const grid = this.elementRef.nativeElement;\n registerFeatureClaim(grid, 'export', () => this.exportFeature());\n claimEvent(grid, 'export-complete');\n }\n\n ngOnInit(): void {\n const grid = this.elementRef.nativeElement;\n this.listener = (e: Event): void => this.exportComplete.emit((e as CustomEvent<ExportCompleteDetail>).detail);\n grid.addEventListener('export-complete', this.listener);\n }\n\n ngOnDestroy(): void {\n const grid = this.elementRef.nativeElement;\n if (this.listener) {\n grid.removeEventListener('export-complete', this.listener);\n this.listener = undefined;\n }\n unregisterFeatureClaim(grid, 'export');\n unclaimEvent(grid, 'export-complete');\n }\n}\n","/**\n * Export feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `export` input on Grid directive.\n * Also exports `injectGridExport()` for programmatic export control.\n *\n * @example\n * ```typescript\n * import '@toolbox-web/grid-angular/features/export';\n *\n * <tbw-grid [export]=\"true\" />\n * <tbw-grid [export]=\"{ fileName: 'data.csv' }\" />\n * ```\n *\n * @example Using injectGridExport\n * ```typescript\n * import { injectGridExport } from '@toolbox-web/grid-angular/features/export';\n *\n * @Component({...})\n * export class MyComponent {\n * private gridExport = injectGridExport();\n *\n * exportData() {\n * this.gridExport.exportToCsv('employees.csv');\n * }\n * }\n * ```\n *\n * @packageDocumentation\n */\n\nimport { afterNextRender, DestroyRef, ElementRef, inject, signal, type Signal } from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport '@toolbox-web/grid/features/export';\nimport { ExportPlugin, type ExportFormat, type ExportParams } from '@toolbox-web/grid/plugins/export';\nexport { GridExportDirective } from './grid-export.directive';\nexport type { _Augmentation as _ExportAugmentation } from '@toolbox-web/grid/features/export';\n\n/**\n * Export methods returned from injectGridExport.\n *\n * Uses lazy discovery - the grid is found on first method call, not during initialization.\n * This ensures it works with lazy-rendered tabs, conditional rendering, etc.\n */\nexport interface ExportMethods {\n /**\n * Export grid data to CSV file.\n * @param filename - Optional filename (defaults to 'export.csv')\n * @param params - Optional export parameters\n */\n exportToCsv: (filename?: string, params?: Partial<ExportParams>) => void;\n\n /**\n * Export grid data to Excel file (XML Spreadsheet format).\n * @param filename - Optional filename (defaults to 'export.xlsx')\n * @param params - Optional export parameters\n */\n exportToExcel: (filename?: string, params?: Partial<ExportParams>) => void;\n\n /**\n * Export grid data to JSON file.\n * @param filename - Optional filename (defaults to 'export.json')\n * @param params - Optional export parameters\n */\n exportToJson: (filename?: string, params?: Partial<ExportParams>) => void;\n\n /**\n * Check if an export is currently in progress.\n */\n isExporting: () => boolean;\n\n /**\n * Get information about the last export.\n */\n getLastExport: () => { format: ExportFormat; timestamp: Date } | null;\n\n /**\n * Signal indicating if grid is ready.\n * The grid is discovered lazily, so this updates when first method call succeeds.\n */\n isReady: Signal<boolean>;\n}\n\n/**\n * Angular inject function for programmatic export control.\n *\n * Uses **lazy grid discovery** - the grid element is found when methods are called,\n * not during initialization. This ensures it works reliably with:\n * - Lazy-rendered tabs\n * - Conditional rendering (*ngIf)\n * - Dynamic component loading\n *\n * @example\n * ```typescript\n * import { Component } from '@angular/core';\n * import { Grid } from '@toolbox-web/grid-angular';\n * import '@toolbox-web/grid-angular/features/export';\n * import { injectGridExport } from '@toolbox-web/grid-angular/features/export';\n *\n * @Component({\n * selector: 'app-my-grid',\n * imports: [Grid],\n * template: `\n * <button (click)=\"handleExport()\">Export CSV</button>\n * <tbw-grid [rows]=\"rows\" [export]=\"true\"></tbw-grid>\n * `\n * })\n * export class MyGridComponent {\n * gridExport = injectGridExport();\n *\n * handleExport() {\n * this.gridExport.exportToCsv('employees.csv');\n * }\n * }\n * ```\n *\n * @param selector - Optional CSS selector to target a specific grid element.\n * Defaults to `'tbw-grid'` (first grid in the component). Use when the\n * component contains multiple grids, e.g. `'tbw-grid.primary'` or `'#my-grid'`.\n */\nexport function injectGridExport(selector = 'tbw-grid'): ExportMethods {\n const elementRef = inject(ElementRef);\n const destroyRef = inject(DestroyRef);\n const isReady = signal(false);\n\n // Lazy discovery: cached grid reference\n let cachedGrid: DataGridElement | null = null;\n let readyPromiseStarted = false;\n\n /**\n * Lazily find the grid element. Called on each method invocation.\n * Caches the reference once found and triggers ready() check.\n */\n const getGrid = (): DataGridElement | null => {\n if (cachedGrid) return cachedGrid;\n\n const grid = elementRef.nativeElement.querySelector(selector) as DataGridElement | null;\n if (grid) {\n cachedGrid = grid;\n // Start ready() check only once\n if (!readyPromiseStarted) {\n readyPromiseStarted = true;\n grid.ready?.().then(() => {\n if (grid.getPluginByName('export')) {\n isReady.set(true);\n } else {\n setTimeout(() => isReady.set(true), 0);\n }\n });\n }\n }\n return grid;\n };\n\n const getPlugin = (): ExportPlugin | undefined => {\n return getGrid()?.getPluginByName('export') as ExportPlugin | undefined;\n };\n\n // Eagerly discover the grid after the first render so isReady updates\n // without requiring a programmatic method call. Falls back to a\n // MutationObserver for lazy-rendered tabs, *ngIf, @defer, etc.\n afterNextRender(() => {\n if (getGrid()) return;\n\n const host = elementRef.nativeElement as HTMLElement;\n const observer = new MutationObserver(() => {\n if (getGrid()) observer.disconnect();\n });\n observer.observe(host, { childList: true, subtree: true });\n\n destroyRef.onDestroy(() => observer.disconnect());\n });\n\n return {\n isReady: isReady.asReadonly(),\n\n exportToCsv: (filename?: string, params?: Partial<ExportParams>) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:export] ExportPlugin not found.\\n\\n` +\n ` → Enable export on the grid:\\n` +\n ` <tbw-grid [export]=\"true\" />`,\n );\n return;\n }\n plugin.exportCsv({ ...params, fileName: filename ?? params?.fileName ?? 'export.csv' });\n },\n\n exportToExcel: (filename?: string, params?: Partial<ExportParams>) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:export] ExportPlugin not found.\\n\\n` +\n ` → Enable export on the grid:\\n` +\n ` <tbw-grid [export]=\"true\" />`,\n );\n return;\n }\n plugin.exportExcel({ ...params, fileName: filename ?? params?.fileName ?? 'export.xlsx' });\n },\n\n exportToJson: (filename?: string, params?: Partial<ExportParams>) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:export] ExportPlugin not found.\\n\\n` +\n ` → Enable export on the grid:\\n` +\n ` <tbw-grid [export]=\"true\" />`,\n );\n return;\n }\n plugin.exportJson({ ...params, fileName: filename ?? params?.fileName ?? 'export.json' });\n },\n\n isExporting: () => {\n return getPlugin()?.isExporting() ?? false;\n },\n\n getLastExport: () => {\n return getPlugin()?.getLastExport() ?? null;\n },\n };\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-export.mjs","sources":["../../../../libs/grid-angular/features/export/src/grid-export.directive.ts","../../../../libs/grid-angular/features/export/src/index.ts","../../../../libs/grid-angular/features/export/src/toolbox-web-grid-angular-features-export.ts"],"sourcesContent":["/**\n * `GridExportDirective` — owns the `export` input (template alias of\n * `exportFeature`) and `(exportComplete)` on `<tbw-grid>`. See\n * `GridFilteringDirective` for the full rationale.\n *\n * The TypeScript field is `exportFeature` (with `alias: 'export'`) because\n * `export` is a reserved keyword. Templates use `[export]` / `(exportComplete)`\n * exactly as before.\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 { ExportCompleteDetail, ExportConfig } from '@toolbox-web/grid/plugins/export';\n\n/**\n * Owns the binding(s) `[export], [exportComplete]` 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[export], tbw-grid[exportComplete]',\n standalone: true,\n})\nexport class GridExportDirective implements OnInit, OnDestroy {\n private readonly elementRef = inject(ElementRef<DataGridElement>);\n\n readonly exportFeature = input<boolean | ExportConfig>(undefined, { alias: 'export' });\n readonly exportComplete = output<ExportCompleteDetail>();\n\n private listener?: (e: Event) => void;\n\n constructor() {\n const grid = this.elementRef.nativeElement;\n registerFeatureClaim(grid, 'export', () => this.exportFeature());\n claimEvent(grid, 'export-complete');\n }\n\n ngOnInit(): void {\n const grid = this.elementRef.nativeElement;\n this.listener = (e: Event): void => this.exportComplete.emit((e as CustomEvent<ExportCompleteDetail>).detail);\n grid.addEventListener('export-complete', this.listener);\n }\n\n ngOnDestroy(): void {\n const grid = this.elementRef.nativeElement;\n if (this.listener) {\n grid.removeEventListener('export-complete', this.listener);\n this.listener = undefined;\n }\n unregisterFeatureClaim(grid, 'export');\n unclaimEvent(grid, 'export-complete');\n }\n}\n","/**\n * Export feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `export` input on Grid directive.\n * Also exports `injectGridExport()` for programmatic export control.\n *\n * @example\n * ```typescript\n * import '@toolbox-web/grid-angular/features/export';\n *\n * <tbw-grid [export]=\"true\" />\n * <tbw-grid [export]=\"{ fileName: 'data.csv' }\" />\n * ```\n *\n * @example Using injectGridExport\n * ```typescript\n * import { injectGridExport } from '@toolbox-web/grid-angular/features/export';\n *\n * @Component({...})\n * export class MyComponent {\n * private gridExport = injectGridExport();\n *\n * exportData() {\n * this.gridExport.exportToCsv('employees.csv');\n * }\n * }\n * ```\n *\n * @packageDocumentation\n */\n\nimport { afterNextRender, DestroyRef, ElementRef, inject, signal, type Signal } from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport '@toolbox-web/grid/features/export';\nimport { ExportPlugin, type ExportFormat, type ExportParams } from '@toolbox-web/grid/plugins/export';\nexport { GridExportDirective } from './grid-export.directive';\nexport type { _Augmentation as _ExportAugmentation } from '@toolbox-web/grid/features/export';\n\n/**\n * Export methods returned from injectGridExport.\n *\n * Uses lazy discovery - the grid is found on first method call, not during initialization.\n * This ensures it works with lazy-rendered tabs, conditional rendering, etc.\n */\nexport interface ExportMethods {\n /**\n * Export grid data to CSV file.\n * @param filename - Optional filename (defaults to 'export.csv')\n * @param params - Optional export parameters\n */\n exportToCsv: (filename?: string, params?: Partial<ExportParams>) => void;\n\n /**\n * Export grid data to Excel file (XML Spreadsheet format).\n * @param filename - Optional filename (defaults to 'export.xlsx')\n * @param params - Optional export parameters\n */\n exportToExcel: (filename?: string, params?: Partial<ExportParams>) => void;\n\n /**\n * Export grid data to JSON file.\n * @param filename - Optional filename (defaults to 'export.json')\n * @param params - Optional export parameters\n */\n exportToJson: (filename?: string, params?: Partial<ExportParams>) => void;\n\n /**\n * Check if an export is currently in progress.\n */\n isExporting: () => boolean;\n\n /**\n * Get information about the last export.\n */\n getLastExport: () => { format: ExportFormat; timestamp: Date } | null;\n\n /**\n * Signal indicating if grid is ready.\n * The grid is discovered lazily, so this updates when first method call succeeds.\n */\n isReady: Signal<boolean>;\n}\n\n/**\n * Angular inject function for programmatic export control.\n *\n * Uses **lazy grid discovery** - the grid element is found when methods are called,\n * not during initialization. This ensures it works reliably with:\n * - Lazy-rendered tabs\n * - Conditional rendering (*ngIf)\n * - Dynamic component loading\n *\n * @example\n * ```typescript\n * import { Component } from '@angular/core';\n * import { Grid } from '@toolbox-web/grid-angular';\n * import '@toolbox-web/grid-angular/features/export';\n * import { injectGridExport } from '@toolbox-web/grid-angular/features/export';\n *\n * @Component({\n * selector: 'app-my-grid',\n * imports: [Grid],\n * template: `\n * <button (click)=\"handleExport()\">Export CSV</button>\n * <tbw-grid [rows]=\"rows\" [export]=\"true\"></tbw-grid>\n * `\n * })\n * export class MyGridComponent {\n * gridExport = injectGridExport();\n *\n * handleExport() {\n * this.gridExport.exportToCsv('employees.csv');\n * }\n * }\n * ```\n *\n * @param selector - Optional CSS selector to target a specific grid element.\n * Defaults to `'tbw-grid'` (first grid in the component). Use when the\n * component contains multiple grids, e.g. `'tbw-grid.primary'` or `'#my-grid'`.\n */\nexport function injectGridExport(selector = 'tbw-grid'): ExportMethods {\n const elementRef = inject(ElementRef);\n const destroyRef = inject(DestroyRef);\n const isReady = signal(false);\n\n // Lazy discovery: cached grid reference\n let cachedGrid: DataGridElement | null = null;\n let readyPromiseStarted = false;\n\n /**\n * Lazily find the grid element. Called on each method invocation.\n * Caches the reference once found and triggers ready() check.\n */\n const getGrid = (): DataGridElement | null => {\n if (cachedGrid) return cachedGrid;\n\n const grid = elementRef.nativeElement.querySelector(selector) as DataGridElement | null;\n if (grid) {\n cachedGrid = grid;\n // Start ready() check only once\n if (!readyPromiseStarted) {\n readyPromiseStarted = true;\n grid.ready?.().then(() => {\n if (grid.getPluginByName('export')) {\n isReady.set(true);\n } else {\n setTimeout(() => isReady.set(true), 0);\n }\n });\n }\n }\n return grid;\n };\n\n const getPlugin = (): ExportPlugin | undefined => {\n return getGrid()?.getPluginByName('export') as ExportPlugin | undefined;\n };\n\n // Eagerly discover the grid after the first render so isReady updates\n // without requiring a programmatic method call. Falls back to a\n // MutationObserver for lazy-rendered tabs, *ngIf, @defer, etc.\n afterNextRender(() => {\n if (getGrid()) return;\n\n const host = elementRef.nativeElement as HTMLElement;\n const observer = new MutationObserver(() => {\n if (getGrid()) observer.disconnect();\n });\n observer.observe(host, { childList: true, subtree: true });\n\n destroyRef.onDestroy(() => observer.disconnect());\n });\n\n return {\n isReady: isReady.asReadonly(),\n\n exportToCsv: (filename?: string, params?: Partial<ExportParams>) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:export] ExportPlugin not found.\\n\\n` +\n ` → Enable export on the grid:\\n` +\n ` <tbw-grid [export]=\"true\" />`,\n );\n return;\n }\n plugin.exportCsv({ ...params, fileName: filename ?? params?.fileName ?? 'export.csv' });\n },\n\n exportToExcel: (filename?: string, params?: Partial<ExportParams>) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:export] ExportPlugin not found.\\n\\n` +\n ` → Enable export on the grid:\\n` +\n ` <tbw-grid [export]=\"true\" />`,\n );\n return;\n }\n plugin.exportExcel({ ...params, fileName: filename ?? params?.fileName ?? 'export.xlsx' });\n },\n\n exportToJson: (filename?: string, params?: Partial<ExportParams>) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:export] ExportPlugin not found.\\n\\n` +\n ` → Enable export on the grid:\\n` +\n ` <tbw-grid [export]=\"true\" />`,\n );\n return;\n }\n plugin.exportJson({ ...params, fileName: filename ?? params?.fileName ?? 'export.json' });\n },\n\n isExporting: () => {\n return getPlugin()?.isExporting() ?? false;\n },\n\n getLastExport: () => {\n return getPlugin()?.getLastExport() ?? null;\n },\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -68,7 +68,8 @@ class GridFilteringDirective {
68
68
  * ```
69
69
  */
70
70
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
- filtering = input(...(ngDevMode ? [undefined, { debugName: "filtering" }] : /* istanbul ignore next */ []));
71
+ filtering = input(/* @ts-ignore */
72
+ ...(ngDevMode ? [undefined, { debugName: "filtering" }] : /* istanbul ignore next */ []));
72
73
  /**
73
74
  * Emitted when filter values change.
74
75
  *
@@ -110,10 +111,10 @@ class GridFilteringDirective {
110
111
  unregisterFeatureClaim(grid, 'filtering');
111
112
  unclaimEvent(grid, 'filter-change');
112
113
  }
113
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridFilteringDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
114
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: GridFilteringDirective, isStandalone: true, selector: "tbw-grid[filtering], tbw-grid[filterChange]", inputs: { filtering: { classPropertyName: "filtering", publicName: "filtering", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filterChange: "filterChange" }, ngImport: i0 });
114
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridFilteringDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
115
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: GridFilteringDirective, isStandalone: true, selector: "tbw-grid[filtering], tbw-grid[filterChange]", inputs: { filtering: { classPropertyName: "filtering", publicName: "filtering", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filterChange: "filterChange" }, ngImport: i0 });
115
116
  }
116
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridFilteringDirective, decorators: [{
117
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridFilteringDirective, decorators: [{
117
118
  type: Directive,
118
119
  args: [{
119
120
  selector: 'tbw-grid[filtering], tbw-grid[filterChange]',
@@ -183,7 +184,8 @@ class BaseFilterPanel {
183
184
  * - `clearFilter()` — clear the filter for this column
184
185
  * - `closePanel()` — close the filter panel
185
186
  */
186
- params = input.required(...(ngDevMode ? [{ debugName: "params" }] : /* istanbul ignore next */ []));
187
+ params = input.required(/* @ts-ignore */
188
+ ...(ngDevMode ? [{ debugName: "params" }] : /* istanbul ignore next */ []));
187
189
  /**
188
190
  * Apply the filter then close the panel.
189
191
  *
@@ -204,10 +206,10 @@ class BaseFilterPanel {
204
206
  this.params().clearFilter();
205
207
  this.params().closePanel();
206
208
  }
207
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: BaseFilterPanel, deps: [], target: i0.ɵɵFactoryTarget.Directive });
208
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: BaseFilterPanel, isStandalone: true, inputs: { params: { classPropertyName: "params", publicName: "params", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
209
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: BaseFilterPanel, deps: [], target: i0.ɵɵFactoryTarget.Directive });
210
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: BaseFilterPanel, isStandalone: true, inputs: { params: { classPropertyName: "params", publicName: "params", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
209
211
  }
210
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: BaseFilterPanel, decorators: [{
212
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: BaseFilterPanel, decorators: [{
211
213
  type: Directive
212
214
  }], propDecorators: { params: [{ type: i0.Input, args: [{ isSignal: true, alias: "params", required: true }] }] } });
213
215
 
@@ -339,7 +341,8 @@ registerFeatureConfigPreprocessor('filtering', (config, adapter) => {
339
341
  function injectGridFiltering(selector = 'tbw-grid') {
340
342
  const elementRef = inject(ElementRef);
341
343
  const destroyRef = inject(DestroyRef);
342
- const isReady = signal(false, ...(ngDevMode ? [{ debugName: "isReady" }] : /* istanbul ignore next */ []));
344
+ const isReady = signal(false, /* @ts-ignore */
345
+ ...(ngDevMode ? [{ debugName: "isReady" }] : /* istanbul ignore next */ []));
343
346
  let cachedGrid = null;
344
347
  let readyPromiseStarted = false;
345
348
  const getGrid = () => {
@@ -1 +1 @@
1
- {"version":3,"file":"toolbox-web-grid-angular-features-filtering.mjs","sources":["../../../../libs/grid-angular/features/filtering/src/grid-filtering.directive.ts","../../../../libs/grid-angular/features/filtering/src/base-filter-panel.ts","../../../../libs/grid-angular/features/filtering/src/index.ts","../../../../libs/grid-angular/features/filtering/src/toolbox-web-grid-angular-features-filtering.ts"],"sourcesContent":["/**\n * `GridFilteringDirective` — attribute-selector directive that owns the\n * `filtering` input and the `filterChange` output on `<tbw-grid>`.\n *\n * ## Why this exists\n *\n * Historically these bindings lived on the central `Grid` directive in\n * `@toolbox-web/grid-angular`. That meant the typed surface for the\n * filtering plugin shipped in the core bundle of every consumer, even those\n * that never imported the filtering feature. Moving them here lets the\n * surface tree-shake away with the rest of the feature when it is not\n * imported, matching the philosophy of the React / Vue adapters and the\n * web-component core (where unloaded plugins simply don't exist on the\n * element).\n *\n * ## Usage\n *\n * ```typescript\n * import { Component } from '@angular/core';\n * import { Grid } from '@toolbox-web/grid-angular';\n * import { GridFilteringDirective } from '@toolbox-web/grid-angular/features/filtering';\n *\n * @Component({\n * selector: 'app-grid',\n * imports: [Grid, GridFilteringDirective],\n * template: `\n * <tbw-grid [rows]=\"rows\" [filtering]=\"true\" (filterChange)=\"onFilter($event)\" />\n * `,\n * })\n * export class AppGridComponent {}\n * ```\n *\n * ## Backward compatibility (v1.x)\n *\n * The matching `filtering` input and `filterChange` output also still exist\n * on `Grid` (marked `@deprecated`) so existing apps that bind them without\n * importing `GridFilteringDirective` continue to work — those will be\n * removed in v2.0.0. When both this directive and the deprecated bindings\n * are present, the directive wins via the per-grid claims registry in\n * `internal/feature-claims.ts`: `Grid` consults the registry and skips its\n * own plugin creation + event wiring for any claimed feature.\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 {\n claimEvent,\n registerFeatureClaim,\n unclaimEvent,\n unregisterFeatureClaim,\n type FilterPanel,\n} from '@toolbox-web/grid-angular';\nimport type { FilterConfig as CoreFilterConfig, FilterChangeDetail } from '@toolbox-web/grid/plugins/filtering';\n\n/**\n * Angular-specific filter config that allows an Angular component class as\n * the plugin-level `filterPanelRenderer`.\n *\n * Extends the core `FilterConfig` to accept a `Type<FilterPanel>` for\n * `filterPanelRenderer` in addition to the vanilla\n * `(container, params) => void` signature. Bridging to vanilla DOM is handled\n * by the side-effect import `@toolbox-web/grid-angular/features/filtering`.\n *\n * Re-exported from the feature entry under the same name as the core type\n * so Angular consumers see a single canonical `FilterConfig` from\n * `@toolbox-web/grid-angular/features/filtering`.\n *\n * @since 1.7.1\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type FilterConfig<TRow = any> = Omit<CoreFilterConfig<TRow>, 'filterPanelRenderer'> & {\n filterPanelRenderer?: CoreFilterConfig<TRow>['filterPanelRenderer'] | Type<FilterPanel>;\n};\n\n/**\n * Owns the `[filtering]` input and `(filterChange)` output on `<tbw-grid>`.\n *\n * Selector matches when *either* binding is present so users can pick the\n * style that suits their template — both go through the same claim and the\n * same wiring.\n * @category Directive\n */\n@Directive({\n selector: 'tbw-grid[filtering], tbw-grid[filterChange]',\n standalone: true,\n})\nexport class GridFilteringDirective implements OnInit, OnDestroy {\n private readonly elementRef = inject(ElementRef<DataGridElement>);\n\n /**\n * Enable column filtering. Identical semantics to the deprecated input on\n * `Grid` — this directive owns the binding when both are present.\n *\n * @example\n * ```html\n * <tbw-grid [filtering]=\"true\" />\n * <tbw-grid [filtering]=\"{ debounceMs: 200 }\" />\n * ```\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly filtering = input<boolean | FilterConfig<any>>();\n\n /**\n * Emitted when filter values change.\n *\n * @example\n * ```html\n * <tbw-grid (filterChange)=\"onFilterChange($event)\" />\n * ```\n */\n readonly filterChange = output<FilterChangeDetail>();\n\n // Listener kept so we can detach in `ngOnDestroy`.\n private listener?: (e: Event) => void;\n\n constructor() {\n const grid = this.elementRef.nativeElement;\n // Tell `Grid` we own this feature's input. Reading `this.filtering()`\n // inside the getter establishes a reactive dependency in `Grid`'s\n // `createFeaturePlugins` effect — when our input changes, that effect\n // re-runs and the plugin config is updated.\n registerFeatureClaim(grid, 'filtering', () => this.filtering());\n // Tell `Grid` we own the matching event so it doesn't double-emit on\n // its own deprecated `filterChange` output.\n claimEvent(grid, 'filter-change');\n }\n\n ngOnInit(): void {\n const grid = this.elementRef.nativeElement;\n this.listener = (e: Event) => {\n this.filterChange.emit((e as CustomEvent<FilterChangeDetail>).detail);\n };\n grid.addEventListener('filter-change', this.listener);\n }\n\n ngOnDestroy(): void {\n const grid = this.elementRef.nativeElement;\n if (this.listener) {\n grid.removeEventListener('filter-change', this.listener);\n this.listener = undefined;\n }\n // Drop the claims so that, if the directive is removed via *ngIf but\n // the host `<tbw-grid>` survives, `Grid`'s deprecated bindings take\n // back over without leaving stale ownership behind.\n unregisterFeatureClaim(grid, 'filtering');\n unclaimEvent(grid, 'filter-change');\n }\n}\n","import { Directive, input } from '@angular/core';\nimport type { FilterPanel } from '@toolbox-web/grid-angular';\n\ntype FilterPanelParams = ReturnType<FilterPanel['params']>;\n\n/**\n * Base class for Angular filter panel components.\n *\n * Provides a ready-made `params` input and common lifecycle helpers\n * (`applyAndClose`, `clearAndClose`) so consumers only need to implement\n * their filter logic in `applyFilter()`.\n *\n * ## Usage\n *\n * ```typescript\n * import { Component, viewChild, ElementRef } from '@angular/core';\n * import { BaseFilterPanel } from '@toolbox-web/grid-angular/features/filtering';\n *\n * @Component({\n * selector: 'app-text-filter',\n * template: `\n * <input #input (keydown.enter)=\"applyAndClose()\" />\n * <button (click)=\"applyAndClose()\">Apply</button>\n * <button (click)=\"clearAndClose()\">Clear</button>\n * `\n * })\n * export class TextFilterComponent extends BaseFilterPanel {\n * input = viewChild.required<ElementRef<HTMLInputElement>>('input');\n *\n * applyFilter(): void {\n * this.params().applyTextFilter('contains', this.input().nativeElement.value);\n * }\n * }\n * ```\n *\n * ## Template Syntax\n *\n * The grid's filtering plugin will mount this component and provide `params`\n * automatically. No manual wiring is required:\n *\n * ```typescript\n * gridConfig = {\n * columns: [\n * { field: 'name', filterable: true, filterPanel: TextFilterComponent },\n * ],\n * };\n * ```\n *\n * @typeParam TRow - The row data type (available via `params().column`)\n *\n * @since 0.13.0\n */\n@Directive()\nexport abstract class BaseFilterPanel implements FilterPanel {\n /**\n * Filter panel parameters injected by the grid's filtering plugin.\n *\n * Provides access to:\n * - `field` — the column field name\n * - `column` — full column configuration\n * - `uniqueValues` — distinct values in the column\n * - `excludedValues` — currently excluded values (set filter)\n * - `searchText` — current search text\n * - `applySetFilter(excluded)` — apply a set-based (include/exclude) filter\n * - `applyTextFilter(operator, value, valueTo?)` — apply a text/number filter\n * - `clearFilter()` — clear the filter for this column\n * - `closePanel()` — close the filter panel\n */\n readonly params = input.required<FilterPanelParams>();\n\n /**\n * Implement this to apply your filter logic.\n *\n * Called by {@link applyAndClose} before closing the panel.\n * Use `this.params()` to access the filter API.\n *\n * @example\n * ```typescript\n * applyFilter(): void {\n * this.params().applyTextFilter('contains', this.searchText);\n * }\n * ```\n */\n abstract applyFilter(): void;\n\n /**\n * Apply the filter then close the panel.\n *\n * Calls {@link applyFilter} followed by `params().closePanel()`.\n * Bind this to your \"Apply\" button or Enter key handler.\n */\n applyAndClose(): void {\n this.applyFilter();\n this.params().closePanel();\n }\n\n /**\n * Clear the filter then close the panel.\n *\n * Calls `params().clearFilter()` followed by `params().closePanel()`.\n * Bind this to your \"Clear\" / \"Reset\" button.\n */\n clearAndClose(): void {\n this.params().clearFilter();\n this.params().closePanel();\n }\n}\n","/**\n * Filtering feature for @toolbox-web/grid-angular\n *\n * Two ways to use:\n *\n * 1. **Recommended (tree-shakeable surface):** add `GridFilteringDirective`\n * to your component's `imports`. The directive owns the `[filtering]`\n * input and `(filterChange)` output, so the typed surface tree-shakes\n * away when the feature is not imported.\n * 2. **Legacy (non-breaking, deprecated):** side-effect import the feature\n * entry; the matching `[filtering]` / `(filterChange)` bindings on the\n * central `Grid` directive will work as in v1.x. These bindings on `Grid`\n * are marked `@deprecated` and will be removed in v2.0.0.\n *\n * Either way `injectGridFiltering()` is available for programmatic control.\n *\n * @example Recommended (directive-owned binding)\n * ```typescript\n * import { Grid } from '@toolbox-web/grid-angular';\n * import { GridFilteringDirective } from '@toolbox-web/grid-angular/features/filtering';\n *\n * @Component({\n * imports: [Grid, GridFilteringDirective],\n * template: `<tbw-grid [filtering]=\"true\" (filterChange)=\"onChange($event)\" />`,\n * })\n * ```\n *\n * @example Legacy (deprecated; works without importing the directive)\n * ```typescript\n * import '@toolbox-web/grid-angular/features/filtering';\n *\n * <tbw-grid [filtering]=\"true\" />\n * <tbw-grid [filtering]=\"{ debounceMs: 200 }\" />\n * ```\n *\n * @example Using injectGridFiltering\n * ```typescript\n * import { injectGridFiltering } from '@toolbox-web/grid-angular/features/filtering';\n *\n * @Component({...})\n * export class MyComponent {\n * private filtering = injectGridFiltering();\n *\n * filterByStatus(status: string) {\n * this.filtering.setFilter('status', { operator: 'equals', value: status });\n * }\n * }\n * ```\n *\n * @packageDocumentation\n */\n\nimport { afterNextRender, DestroyRef, ElementRef, inject, signal, type Signal, type Type } from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport {\n isComponentClass,\n registerFeatureConfigPreprocessor,\n registerFilterPanelTypeDefaultBridge,\n type FilterPanel,\n type GridAdapter,\n} from '@toolbox-web/grid-angular';\nimport '@toolbox-web/grid/features/filtering';\nimport {\n FilteringPlugin,\n type BlankMode,\n type FilterConfig as CoreFilterConfig,\n type FilterModel,\n} from '@toolbox-web/grid/plugins/filtering';\nexport type { _Augmentation as _FilteringAugmentation } from '@toolbox-web/grid/features/filtering';\n\n// Attribute-selector directive that owns the `[filtering]` input and\n// `(filterChange)` output on `<tbw-grid>`. Add to your component's `imports`\n// alongside `Grid` to opt into the feature directly via the binding. The\n// matching deprecated bindings on `Grid` remain as a v1.x compatibility\n// shim and will be removed in v2.0.0.\nexport { GridFilteringDirective } from './grid-filtering.directive';\nexport type { FilterConfig } from './grid-filtering.directive';\n\n// `BaseFilterPanel` is filtering-specific (implements `FilterPanel` from the\n// filtering plugin) and physically lives in this secondary entry.\nexport { BaseFilterPanel } from './base-filter-panel';\n\ntype FilterPanelParams = ReturnType<FilterPanel['params']>;\n\n// Bridge any Angular component classes used as `filterPanelRenderer` (in\n// `gridConfig.typeDefaults` or via `provideGridTypeDefaults`) to the\n// `(container, params) => void` form required by FilteringPlugin. Without\n// this import, component-class filterPanelRenderers are silently dropped \\u2014\n// the same precondition as the FilteringPlugin itself (TBW031).\nregisterFilterPanelTypeDefaultBridge((rendererValue: unknown, adapter: GridAdapter) => {\n const componentClass = rendererValue as Type<unknown>;\n const mount = adapter.mountComponentRenderer<FilterPanelParams>(componentClass, (params) => ({ params }));\n return (container: HTMLElement, params: FilterPanelParams) => {\n container.appendChild(mount(params).hostElement);\n };\n});\n\n/**\n * Bridge an Angular component class used as the plugin-level\n * `filterPanelRenderer` (in `FilterConfig`) to the `(container, params) => void`\n * form required by FilteringPlugin. Mirrors `registerFilterPanelTypeDefaultBridge`\n * above, but for the plugin-wide renderer rather than per-type defaults.\n *\n * Without this preprocessor, passing a component class as\n * `filtering.filterPanelRenderer` would be invoked as a function at render\n * time and crash.\n *\n * @since 1.7.1\n */\nregisterFeatureConfigPreprocessor('filtering', (config, adapter) => {\n if (!config || typeof config === 'boolean' || typeof config !== 'object') return config;\n const cfg = config as CoreFilterConfig;\n if (!isComponentClass(cfg.filterPanelRenderer)) return config;\n\n type PluginFilterPanelRenderer = NonNullable<CoreFilterConfig['filterPanelRenderer']>;\n type PluginFilterPanelParams = Parameters<PluginFilterPanelRenderer>[1];\n\n const componentClass = cfg.filterPanelRenderer as Type<unknown>;\n const mount = adapter.mountComponentRenderer<PluginFilterPanelParams>(componentClass, (params) => ({ params }));\n const filterPanelRenderer: CoreFilterConfig['filterPanelRenderer'] = (container, params) => {\n container.appendChild(mount(params).hostElement);\n };\n return { ...cfg, filterPanelRenderer };\n});\n\n/**\n * Filtering methods returned from injectGridFiltering.\n *\n * Uses lazy discovery - the grid is found on first method call, not during initialization.\n */\nexport interface FilteringMethods {\n /**\n * Set a filter on a specific field.\n * @param field - The field name to filter\n * @param filter - Filter configuration, or null to remove\n * @param options - `{ silent: true }` applies the filter without emitting `filter-change`\n */\n setFilter: (field: string, filter: Omit<FilterModel, 'field'> | null, options?: { silent?: boolean }) => void;\n\n /**\n * Get the current filter for a field.\n */\n getFilter: (field: string) => FilterModel | undefined;\n\n /**\n * Get all active filters.\n */\n getFilters: () => FilterModel[];\n\n /**\n * Set all filters at once (replaces existing).\n * @param options - `{ silent: true }` applies filters without emitting `filter-change`\n */\n setFilterModel: (filters: FilterModel[], options?: { silent?: boolean }) => void;\n\n /**\n * Clear all active filters.\n * @param options - `{ silent: true }` clears filters without emitting `filter-change`\n */\n clearAllFilters: (options?: { silent?: boolean }) => void;\n\n /**\n * Clear filter for a specific field.\n * @param options - `{ silent: true }` clears filter without emitting `filter-change`\n */\n clearFieldFilter: (field: string, options?: { silent?: boolean }) => void;\n\n /**\n * Check if a field has an active filter.\n */\n isFieldFiltered: (field: string) => boolean;\n\n /**\n * Get the count of rows after filtering.\n */\n getFilteredRowCount: () => number;\n\n /**\n * Get unique values for a field (for building filter dropdowns).\n */\n getUniqueValues: (field: string) => unknown[];\n\n /**\n * Get set filters whose values no longer match any rows in the current data.\n */\n getStaleFilters: () => FilterModel[];\n\n /**\n * Get the current blank mode for a field.\n */\n getBlankMode: (field: string) => BlankMode;\n\n /**\n * Toggle blank filter mode for a field.\n */\n toggleBlankFilter: (field: string, mode: BlankMode) => void;\n\n /**\n * Signal indicating if grid is ready.\n */\n isReady: Signal<boolean>;\n}\n\n/**\n * Angular inject function for programmatic filter control.\n *\n * Uses **lazy grid discovery** - the grid element is found when methods are called,\n * not during initialization.\n *\n * @example\n * ```typescript\n * import { Component } from '@angular/core';\n * import { Grid } from '@toolbox-web/grid-angular';\n * import '@toolbox-web/grid-angular/features/filtering';\n * import { injectGridFiltering } from '@toolbox-web/grid-angular/features/filtering';\n *\n * @Component({\n * selector: 'app-my-grid',\n * imports: [Grid],\n * template: `\n * <input (input)=\"applyFilter($event)\" placeholder=\"Filter by name...\" />\n * <span>{{ filtering.getFilteredRowCount() }} results</span>\n * <button (click)=\"filtering.clearAllFilters()\">Clear</button>\n * <tbw-grid [rows]=\"rows\" [filtering]=\"true\"></tbw-grid>\n * `\n * })\n * export class MyGridComponent {\n * filtering = injectGridFiltering();\n *\n * applyFilter(event: Event) {\n * const value = (event.target as HTMLInputElement).value;\n * this.filtering.setFilter('name', value ? { operator: 'contains', value } : null);\n * }\n * }\n * ```\n *\n * @param selector - Optional CSS selector to target a specific grid element.\n * Defaults to `'tbw-grid'` (first grid in the component). Use when the\n * component contains multiple grids, e.g. `'tbw-grid.primary'` or `'#my-grid'`.\n */\nexport function injectGridFiltering(selector = 'tbw-grid'): FilteringMethods {\n const elementRef = inject(ElementRef);\n const destroyRef = inject(DestroyRef);\n const isReady = signal(false);\n\n let cachedGrid: DataGridElement | null = null;\n let readyPromiseStarted = false;\n\n const getGrid = (): DataGridElement | null => {\n if (cachedGrid) return cachedGrid;\n\n const grid = elementRef.nativeElement.querySelector(selector) as DataGridElement | null;\n if (grid) {\n cachedGrid = grid;\n if (!readyPromiseStarted) {\n readyPromiseStarted = true;\n grid.ready?.().then(() => {\n // If the plugin is already attached, signal readiness immediately.\n // Otherwise, Angular's Grid directive may not have applied gridConfig\n // yet (it uses effect + queueMicrotask). Defer to let pending\n // microtasks flush before signaling readiness.\n if (grid.getPluginByName('filtering')) {\n isReady.set(true);\n } else {\n setTimeout(() => isReady.set(true), 0);\n }\n });\n }\n }\n return grid;\n };\n\n const getPlugin = (): FilteringPlugin | undefined => {\n return getGrid()?.getPluginByName('filtering') as FilteringPlugin | undefined;\n };\n\n // Eagerly discover the grid after the first render so isReady updates\n // without requiring a programmatic method call. Falls back to a\n // MutationObserver for lazy-rendered tabs, *ngIf, @defer, etc.\n afterNextRender(() => {\n if (getGrid()) return;\n\n const host = elementRef.nativeElement as HTMLElement;\n const observer = new MutationObserver(() => {\n if (getGrid()) observer.disconnect();\n });\n observer.observe(host, { childList: true, subtree: true });\n\n destroyRef.onDestroy(() => observer.disconnect());\n });\n\n return {\n isReady: isReady.asReadonly(),\n\n setFilter: (field: string, filter: Omit<FilterModel, 'field'> | null, options?: { silent?: boolean }) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <tbw-grid [filtering]=\"true\" />`,\n );\n return;\n }\n plugin.setFilter(field, filter, options);\n },\n\n getFilter: (field: string) => getPlugin()?.getFilter(field),\n\n getFilters: () => getPlugin()?.getFilters() ?? [],\n\n setFilterModel: (filters: FilterModel[], options?: { silent?: boolean }) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <tbw-grid [filtering]=\"true\" />`,\n );\n return;\n }\n plugin.setFilterModel(filters, options);\n },\n\n clearAllFilters: (options?: { silent?: boolean }) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <tbw-grid [filtering]=\"true\" />`,\n );\n return;\n }\n plugin.clearAllFilters(options);\n },\n\n clearFieldFilter: (field: string, options?: { silent?: boolean }) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <tbw-grid [filtering]=\"true\" />`,\n );\n return;\n }\n plugin.clearFieldFilter(field, options);\n },\n\n isFieldFiltered: (field: string) => getPlugin()?.isFieldFiltered(field) ?? false,\n\n getFilteredRowCount: () => getPlugin()?.getFilteredRowCount() ?? 0,\n\n getUniqueValues: (field: string) => getPlugin()?.getUniqueValues(field) ?? [],\n\n getStaleFilters: () => getPlugin()?.getStaleFilters() ?? [],\n\n getBlankMode: (field: string) => getPlugin()?.getBlankMode(field) ?? 'all',\n\n toggleBlankFilter: (field: string, mode: BlankMode) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <tbw-grid [filtering]=\"true\" />`,\n );\n return;\n }\n plugin.toggleBlankFilter(field, mode);\n },\n };\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-filtering.mjs","sources":["../../../../libs/grid-angular/features/filtering/src/grid-filtering.directive.ts","../../../../libs/grid-angular/features/filtering/src/base-filter-panel.ts","../../../../libs/grid-angular/features/filtering/src/index.ts","../../../../libs/grid-angular/features/filtering/src/toolbox-web-grid-angular-features-filtering.ts"],"sourcesContent":["/**\n * `GridFilteringDirective` — attribute-selector directive that owns the\n * `filtering` input and the `filterChange` output on `<tbw-grid>`.\n *\n * ## Why this exists\n *\n * Historically these bindings lived on the central `Grid` directive in\n * `@toolbox-web/grid-angular`. That meant the typed surface for the\n * filtering plugin shipped in the core bundle of every consumer, even those\n * that never imported the filtering feature. Moving them here lets the\n * surface tree-shake away with the rest of the feature when it is not\n * imported, matching the philosophy of the React / Vue adapters and the\n * web-component core (where unloaded plugins simply don't exist on the\n * element).\n *\n * ## Usage\n *\n * ```typescript\n * import { Component } from '@angular/core';\n * import { Grid } from '@toolbox-web/grid-angular';\n * import { GridFilteringDirective } from '@toolbox-web/grid-angular/features/filtering';\n *\n * @Component({\n * selector: 'app-grid',\n * imports: [Grid, GridFilteringDirective],\n * template: `\n * <tbw-grid [rows]=\"rows\" [filtering]=\"true\" (filterChange)=\"onFilter($event)\" />\n * `,\n * })\n * export class AppGridComponent {}\n * ```\n *\n * ## Backward compatibility (v1.x)\n *\n * The matching `filtering` input and `filterChange` output also still exist\n * on `Grid` (marked `@deprecated`) so existing apps that bind them without\n * importing `GridFilteringDirective` continue to work — those will be\n * removed in v2.0.0. When both this directive and the deprecated bindings\n * are present, the directive wins via the per-grid claims registry in\n * `internal/feature-claims.ts`: `Grid` consults the registry and skips its\n * own plugin creation + event wiring for any claimed feature.\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 {\n claimEvent,\n registerFeatureClaim,\n unclaimEvent,\n unregisterFeatureClaim,\n type FilterPanel,\n} from '@toolbox-web/grid-angular';\nimport type { FilterConfig as CoreFilterConfig, FilterChangeDetail } from '@toolbox-web/grid/plugins/filtering';\n\n/**\n * Angular-specific filter config that allows an Angular component class as\n * the plugin-level `filterPanelRenderer`.\n *\n * Extends the core `FilterConfig` to accept a `Type<FilterPanel>` for\n * `filterPanelRenderer` in addition to the vanilla\n * `(container, params) => void` signature. Bridging to vanilla DOM is handled\n * by the side-effect import `@toolbox-web/grid-angular/features/filtering`.\n *\n * Re-exported from the feature entry under the same name as the core type\n * so Angular consumers see a single canonical `FilterConfig` from\n * `@toolbox-web/grid-angular/features/filtering`.\n *\n * @since 1.7.1\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type FilterConfig<TRow = any> = Omit<CoreFilterConfig<TRow>, 'filterPanelRenderer'> & {\n filterPanelRenderer?: CoreFilterConfig<TRow>['filterPanelRenderer'] | Type<FilterPanel>;\n};\n\n/**\n * Owns the `[filtering]` input and `(filterChange)` output on `<tbw-grid>`.\n *\n * Selector matches when *either* binding is present so users can pick the\n * style that suits their template — both go through the same claim and the\n * same wiring.\n * @category Directive\n */\n@Directive({\n selector: 'tbw-grid[filtering], tbw-grid[filterChange]',\n standalone: true,\n})\nexport class GridFilteringDirective implements OnInit, OnDestroy {\n private readonly elementRef = inject(ElementRef<DataGridElement>);\n\n /**\n * Enable column filtering. Identical semantics to the deprecated input on\n * `Grid` — this directive owns the binding when both are present.\n *\n * @example\n * ```html\n * <tbw-grid [filtering]=\"true\" />\n * <tbw-grid [filtering]=\"{ debounceMs: 200 }\" />\n * ```\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly filtering = input<boolean | FilterConfig<any>>();\n\n /**\n * Emitted when filter values change.\n *\n * @example\n * ```html\n * <tbw-grid (filterChange)=\"onFilterChange($event)\" />\n * ```\n */\n readonly filterChange = output<FilterChangeDetail>();\n\n // Listener kept so we can detach in `ngOnDestroy`.\n private listener?: (e: Event) => void;\n\n constructor() {\n const grid = this.elementRef.nativeElement;\n // Tell `Grid` we own this feature's input. Reading `this.filtering()`\n // inside the getter establishes a reactive dependency in `Grid`'s\n // `createFeaturePlugins` effect — when our input changes, that effect\n // re-runs and the plugin config is updated.\n registerFeatureClaim(grid, 'filtering', () => this.filtering());\n // Tell `Grid` we own the matching event so it doesn't double-emit on\n // its own deprecated `filterChange` output.\n claimEvent(grid, 'filter-change');\n }\n\n ngOnInit(): void {\n const grid = this.elementRef.nativeElement;\n this.listener = (e: Event) => {\n this.filterChange.emit((e as CustomEvent<FilterChangeDetail>).detail);\n };\n grid.addEventListener('filter-change', this.listener);\n }\n\n ngOnDestroy(): void {\n const grid = this.elementRef.nativeElement;\n if (this.listener) {\n grid.removeEventListener('filter-change', this.listener);\n this.listener = undefined;\n }\n // Drop the claims so that, if the directive is removed via *ngIf but\n // the host `<tbw-grid>` survives, `Grid`'s deprecated bindings take\n // back over without leaving stale ownership behind.\n unregisterFeatureClaim(grid, 'filtering');\n unclaimEvent(grid, 'filter-change');\n }\n}\n","import { Directive, input } from '@angular/core';\nimport type { FilterPanel } from '@toolbox-web/grid-angular';\n\ntype FilterPanelParams = ReturnType<FilterPanel['params']>;\n\n/**\n * Base class for Angular filter panel components.\n *\n * Provides a ready-made `params` input and common lifecycle helpers\n * (`applyAndClose`, `clearAndClose`) so consumers only need to implement\n * their filter logic in `applyFilter()`.\n *\n * ## Usage\n *\n * ```typescript\n * import { Component, viewChild, ElementRef } from '@angular/core';\n * import { BaseFilterPanel } from '@toolbox-web/grid-angular/features/filtering';\n *\n * @Component({\n * selector: 'app-text-filter',\n * template: `\n * <input #input (keydown.enter)=\"applyAndClose()\" />\n * <button (click)=\"applyAndClose()\">Apply</button>\n * <button (click)=\"clearAndClose()\">Clear</button>\n * `\n * })\n * export class TextFilterComponent extends BaseFilterPanel {\n * input = viewChild.required<ElementRef<HTMLInputElement>>('input');\n *\n * applyFilter(): void {\n * this.params().applyTextFilter('contains', this.input().nativeElement.value);\n * }\n * }\n * ```\n *\n * ## Template Syntax\n *\n * The grid's filtering plugin will mount this component and provide `params`\n * automatically. No manual wiring is required:\n *\n * ```typescript\n * gridConfig = {\n * columns: [\n * { field: 'name', filterable: true, filterPanel: TextFilterComponent },\n * ],\n * };\n * ```\n *\n * @typeParam TRow - The row data type (available via `params().column`)\n *\n * @since 0.13.0\n */\n@Directive()\nexport abstract class BaseFilterPanel implements FilterPanel {\n /**\n * Filter panel parameters injected by the grid's filtering plugin.\n *\n * Provides access to:\n * - `field` — the column field name\n * - `column` — full column configuration\n * - `uniqueValues` — distinct values in the column\n * - `excludedValues` — currently excluded values (set filter)\n * - `searchText` — current search text\n * - `applySetFilter(excluded)` — apply a set-based (include/exclude) filter\n * - `applyTextFilter(operator, value, valueTo?)` — apply a text/number filter\n * - `clearFilter()` — clear the filter for this column\n * - `closePanel()` — close the filter panel\n */\n readonly params = input.required<FilterPanelParams>();\n\n /**\n * Implement this to apply your filter logic.\n *\n * Called by {@link applyAndClose} before closing the panel.\n * Use `this.params()` to access the filter API.\n *\n * @example\n * ```typescript\n * applyFilter(): void {\n * this.params().applyTextFilter('contains', this.searchText);\n * }\n * ```\n */\n abstract applyFilter(): void;\n\n /**\n * Apply the filter then close the panel.\n *\n * Calls {@link applyFilter} followed by `params().closePanel()`.\n * Bind this to your \"Apply\" button or Enter key handler.\n */\n applyAndClose(): void {\n this.applyFilter();\n this.params().closePanel();\n }\n\n /**\n * Clear the filter then close the panel.\n *\n * Calls `params().clearFilter()` followed by `params().closePanel()`.\n * Bind this to your \"Clear\" / \"Reset\" button.\n */\n clearAndClose(): void {\n this.params().clearFilter();\n this.params().closePanel();\n }\n}\n","/**\n * Filtering feature for @toolbox-web/grid-angular\n *\n * Two ways to use:\n *\n * 1. **Recommended (tree-shakeable surface):** add `GridFilteringDirective`\n * to your component's `imports`. The directive owns the `[filtering]`\n * input and `(filterChange)` output, so the typed surface tree-shakes\n * away when the feature is not imported.\n * 2. **Legacy (non-breaking, deprecated):** side-effect import the feature\n * entry; the matching `[filtering]` / `(filterChange)` bindings on the\n * central `Grid` directive will work as in v1.x. These bindings on `Grid`\n * are marked `@deprecated` and will be removed in v2.0.0.\n *\n * Either way `injectGridFiltering()` is available for programmatic control.\n *\n * @example Recommended (directive-owned binding)\n * ```typescript\n * import { Grid } from '@toolbox-web/grid-angular';\n * import { GridFilteringDirective } from '@toolbox-web/grid-angular/features/filtering';\n *\n * @Component({\n * imports: [Grid, GridFilteringDirective],\n * template: `<tbw-grid [filtering]=\"true\" (filterChange)=\"onChange($event)\" />`,\n * })\n * ```\n *\n * @example Legacy (deprecated; works without importing the directive)\n * ```typescript\n * import '@toolbox-web/grid-angular/features/filtering';\n *\n * <tbw-grid [filtering]=\"true\" />\n * <tbw-grid [filtering]=\"{ debounceMs: 200 }\" />\n * ```\n *\n * @example Using injectGridFiltering\n * ```typescript\n * import { injectGridFiltering } from '@toolbox-web/grid-angular/features/filtering';\n *\n * @Component({...})\n * export class MyComponent {\n * private filtering = injectGridFiltering();\n *\n * filterByStatus(status: string) {\n * this.filtering.setFilter('status', { operator: 'equals', value: status });\n * }\n * }\n * ```\n *\n * @packageDocumentation\n */\n\nimport { afterNextRender, DestroyRef, ElementRef, inject, signal, type Signal, type Type } from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport {\n isComponentClass,\n registerFeatureConfigPreprocessor,\n registerFilterPanelTypeDefaultBridge,\n type FilterPanel,\n type GridAdapter,\n} from '@toolbox-web/grid-angular';\nimport '@toolbox-web/grid/features/filtering';\nimport {\n FilteringPlugin,\n type BlankMode,\n type FilterConfig as CoreFilterConfig,\n type FilterModel,\n} from '@toolbox-web/grid/plugins/filtering';\nexport type { _Augmentation as _FilteringAugmentation } from '@toolbox-web/grid/features/filtering';\n\n// Attribute-selector directive that owns the `[filtering]` input and\n// `(filterChange)` output on `<tbw-grid>`. Add to your component's `imports`\n// alongside `Grid` to opt into the feature directly via the binding. The\n// matching deprecated bindings on `Grid` remain as a v1.x compatibility\n// shim and will be removed in v2.0.0.\nexport { GridFilteringDirective } from './grid-filtering.directive';\nexport type { FilterConfig } from './grid-filtering.directive';\n\n// `BaseFilterPanel` is filtering-specific (implements `FilterPanel` from the\n// filtering plugin) and physically lives in this secondary entry.\nexport { BaseFilterPanel } from './base-filter-panel';\n\ntype FilterPanelParams = ReturnType<FilterPanel['params']>;\n\n// Bridge any Angular component classes used as `filterPanelRenderer` (in\n// `gridConfig.typeDefaults` or via `provideGridTypeDefaults`) to the\n// `(container, params) => void` form required by FilteringPlugin. Without\n// this import, component-class filterPanelRenderers are silently dropped \\u2014\n// the same precondition as the FilteringPlugin itself (TBW031).\nregisterFilterPanelTypeDefaultBridge((rendererValue: unknown, adapter: GridAdapter) => {\n const componentClass = rendererValue as Type<unknown>;\n const mount = adapter.mountComponentRenderer<FilterPanelParams>(componentClass, (params) => ({ params }));\n return (container: HTMLElement, params: FilterPanelParams) => {\n container.appendChild(mount(params).hostElement);\n };\n});\n\n/**\n * Bridge an Angular component class used as the plugin-level\n * `filterPanelRenderer` (in `FilterConfig`) to the `(container, params) => void`\n * form required by FilteringPlugin. Mirrors `registerFilterPanelTypeDefaultBridge`\n * above, but for the plugin-wide renderer rather than per-type defaults.\n *\n * Without this preprocessor, passing a component class as\n * `filtering.filterPanelRenderer` would be invoked as a function at render\n * time and crash.\n *\n * @since 1.7.1\n */\nregisterFeatureConfigPreprocessor('filtering', (config, adapter) => {\n if (!config || typeof config === 'boolean' || typeof config !== 'object') return config;\n const cfg = config as CoreFilterConfig;\n if (!isComponentClass(cfg.filterPanelRenderer)) return config;\n\n type PluginFilterPanelRenderer = NonNullable<CoreFilterConfig['filterPanelRenderer']>;\n type PluginFilterPanelParams = Parameters<PluginFilterPanelRenderer>[1];\n\n const componentClass = cfg.filterPanelRenderer as Type<unknown>;\n const mount = adapter.mountComponentRenderer<PluginFilterPanelParams>(componentClass, (params) => ({ params }));\n const filterPanelRenderer: CoreFilterConfig['filterPanelRenderer'] = (container, params) => {\n container.appendChild(mount(params).hostElement);\n };\n return { ...cfg, filterPanelRenderer };\n});\n\n/**\n * Filtering methods returned from injectGridFiltering.\n *\n * Uses lazy discovery - the grid is found on first method call, not during initialization.\n */\nexport interface FilteringMethods {\n /**\n * Set a filter on a specific field.\n * @param field - The field name to filter\n * @param filter - Filter configuration, or null to remove\n * @param options - `{ silent: true }` applies the filter without emitting `filter-change`\n */\n setFilter: (field: string, filter: Omit<FilterModel, 'field'> | null, options?: { silent?: boolean }) => void;\n\n /**\n * Get the current filter for a field.\n */\n getFilter: (field: string) => FilterModel | undefined;\n\n /**\n * Get all active filters.\n */\n getFilters: () => FilterModel[];\n\n /**\n * Set all filters at once (replaces existing).\n * @param options - `{ silent: true }` applies filters without emitting `filter-change`\n */\n setFilterModel: (filters: FilterModel[], options?: { silent?: boolean }) => void;\n\n /**\n * Clear all active filters.\n * @param options - `{ silent: true }` clears filters without emitting `filter-change`\n */\n clearAllFilters: (options?: { silent?: boolean }) => void;\n\n /**\n * Clear filter for a specific field.\n * @param options - `{ silent: true }` clears filter without emitting `filter-change`\n */\n clearFieldFilter: (field: string, options?: { silent?: boolean }) => void;\n\n /**\n * Check if a field has an active filter.\n */\n isFieldFiltered: (field: string) => boolean;\n\n /**\n * Get the count of rows after filtering.\n */\n getFilteredRowCount: () => number;\n\n /**\n * Get unique values for a field (for building filter dropdowns).\n */\n getUniqueValues: (field: string) => unknown[];\n\n /**\n * Get set filters whose values no longer match any rows in the current data.\n */\n getStaleFilters: () => FilterModel[];\n\n /**\n * Get the current blank mode for a field.\n */\n getBlankMode: (field: string) => BlankMode;\n\n /**\n * Toggle blank filter mode for a field.\n */\n toggleBlankFilter: (field: string, mode: BlankMode) => void;\n\n /**\n * Signal indicating if grid is ready.\n */\n isReady: Signal<boolean>;\n}\n\n/**\n * Angular inject function for programmatic filter control.\n *\n * Uses **lazy grid discovery** - the grid element is found when methods are called,\n * not during initialization.\n *\n * @example\n * ```typescript\n * import { Component } from '@angular/core';\n * import { Grid } from '@toolbox-web/grid-angular';\n * import '@toolbox-web/grid-angular/features/filtering';\n * import { injectGridFiltering } from '@toolbox-web/grid-angular/features/filtering';\n *\n * @Component({\n * selector: 'app-my-grid',\n * imports: [Grid],\n * template: `\n * <input (input)=\"applyFilter($event)\" placeholder=\"Filter by name...\" />\n * <span>{{ filtering.getFilteredRowCount() }} results</span>\n * <button (click)=\"filtering.clearAllFilters()\">Clear</button>\n * <tbw-grid [rows]=\"rows\" [filtering]=\"true\"></tbw-grid>\n * `\n * })\n * export class MyGridComponent {\n * filtering = injectGridFiltering();\n *\n * applyFilter(event: Event) {\n * const value = (event.target as HTMLInputElement).value;\n * this.filtering.setFilter('name', value ? { operator: 'contains', value } : null);\n * }\n * }\n * ```\n *\n * @param selector - Optional CSS selector to target a specific grid element.\n * Defaults to `'tbw-grid'` (first grid in the component). Use when the\n * component contains multiple grids, e.g. `'tbw-grid.primary'` or `'#my-grid'`.\n */\nexport function injectGridFiltering(selector = 'tbw-grid'): FilteringMethods {\n const elementRef = inject(ElementRef);\n const destroyRef = inject(DestroyRef);\n const isReady = signal(false);\n\n let cachedGrid: DataGridElement | null = null;\n let readyPromiseStarted = false;\n\n const getGrid = (): DataGridElement | null => {\n if (cachedGrid) return cachedGrid;\n\n const grid = elementRef.nativeElement.querySelector(selector) as DataGridElement | null;\n if (grid) {\n cachedGrid = grid;\n if (!readyPromiseStarted) {\n readyPromiseStarted = true;\n grid.ready?.().then(() => {\n // If the plugin is already attached, signal readiness immediately.\n // Otherwise, Angular's Grid directive may not have applied gridConfig\n // yet (it uses effect + queueMicrotask). Defer to let pending\n // microtasks flush before signaling readiness.\n if (grid.getPluginByName('filtering')) {\n isReady.set(true);\n } else {\n setTimeout(() => isReady.set(true), 0);\n }\n });\n }\n }\n return grid;\n };\n\n const getPlugin = (): FilteringPlugin | undefined => {\n return getGrid()?.getPluginByName('filtering') as FilteringPlugin | undefined;\n };\n\n // Eagerly discover the grid after the first render so isReady updates\n // without requiring a programmatic method call. Falls back to a\n // MutationObserver for lazy-rendered tabs, *ngIf, @defer, etc.\n afterNextRender(() => {\n if (getGrid()) return;\n\n const host = elementRef.nativeElement as HTMLElement;\n const observer = new MutationObserver(() => {\n if (getGrid()) observer.disconnect();\n });\n observer.observe(host, { childList: true, subtree: true });\n\n destroyRef.onDestroy(() => observer.disconnect());\n });\n\n return {\n isReady: isReady.asReadonly(),\n\n setFilter: (field: string, filter: Omit<FilterModel, 'field'> | null, options?: { silent?: boolean }) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <tbw-grid [filtering]=\"true\" />`,\n );\n return;\n }\n plugin.setFilter(field, filter, options);\n },\n\n getFilter: (field: string) => getPlugin()?.getFilter(field),\n\n getFilters: () => getPlugin()?.getFilters() ?? [],\n\n setFilterModel: (filters: FilterModel[], options?: { silent?: boolean }) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <tbw-grid [filtering]=\"true\" />`,\n );\n return;\n }\n plugin.setFilterModel(filters, options);\n },\n\n clearAllFilters: (options?: { silent?: boolean }) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <tbw-grid [filtering]=\"true\" />`,\n );\n return;\n }\n plugin.clearAllFilters(options);\n },\n\n clearFieldFilter: (field: string, options?: { silent?: boolean }) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <tbw-grid [filtering]=\"true\" />`,\n );\n return;\n }\n plugin.clearFieldFilter(field, options);\n },\n\n isFieldFiltered: (field: string) => getPlugin()?.isFieldFiltered(field) ?? false,\n\n getFilteredRowCount: () => getPlugin()?.getFilteredRowCount() ?? 0,\n\n getUniqueValues: (field: string) => getPlugin()?.getUniqueValues(field) ?? [],\n\n getStaleFilters: () => getPlugin()?.getStaleFilters() ?? [],\n\n getBlankMode: (field: string) => getPlugin()?.getBlankMode(field) ?? 'all',\n\n toggleBlankFilter: (field: string, mode: BlankMode) => {\n const plugin = getPlugin();\n if (!plugin) {\n console.warn(\n `[tbw-grid:filtering] FilteringPlugin not found.\\n\\n` +\n ` → Enable filtering on the grid:\\n` +\n ` <tbw-grid [filtering]=\"true\" />`,\n );\n return;\n }\n plugin.toggleBlankFilter(field, mode);\n },\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -17,17 +17,18 @@ import { inject, ElementRef, input, Directive } from '@angular/core';
17
17
  */
18
18
  class GridGroupingColumnsDirective {
19
19
  elementRef = inject((ElementRef));
20
- groupingColumns = input(...(ngDevMode ? [undefined, { debugName: "groupingColumns" }] : /* istanbul ignore next */ []));
20
+ groupingColumns = input(/* @ts-ignore */
21
+ ...(ngDevMode ? [undefined, { debugName: "groupingColumns" }] : /* istanbul ignore next */ []));
21
22
  constructor() {
22
23
  registerFeatureClaim(this.elementRef.nativeElement, 'groupingColumns', () => this.groupingColumns());
23
24
  }
24
25
  ngOnDestroy() {
25
26
  unregisterFeatureClaim(this.elementRef.nativeElement, 'groupingColumns');
26
27
  }
27
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridGroupingColumnsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
28
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: GridGroupingColumnsDirective, isStandalone: true, selector: "tbw-grid[groupingColumns]", inputs: { groupingColumns: { classPropertyName: "groupingColumns", publicName: "groupingColumns", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
28
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridGroupingColumnsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
29
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: GridGroupingColumnsDirective, isStandalone: true, selector: "tbw-grid[groupingColumns]", inputs: { groupingColumns: { classPropertyName: "groupingColumns", publicName: "groupingColumns", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
29
30
  }
30
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridGroupingColumnsDirective, decorators: [{
31
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridGroupingColumnsDirective, decorators: [{
31
32
  type: Directive,
32
33
  args: [{
33
34
  selector: 'tbw-grid[groupingColumns]',
@@ -1 +1 @@
1
- {"version":3,"file":"toolbox-web-grid-angular-features-grouping-columns.mjs","sources":["../../../../libs/grid-angular/features/grouping-columns/src/grid-grouping-columns.directive.ts","../../../../libs/grid-angular/features/grouping-columns/src/index.ts","../../../../libs/grid-angular/features/grouping-columns/src/toolbox-web-grid-angular-features-grouping-columns.ts"],"sourcesContent":["/**\n * `GridGroupingColumnsDirective` — owns `[groupingColumns]` on\n * `<tbw-grid>`. No event outputs. See `GridFilteringDirective` for the\n * full rationale.\n *\n * @category Directive\n */\nimport { Directive, ElementRef, inject, input, OnDestroy, type Type } from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport { registerFeatureClaim, unregisterFeatureClaim } from '@toolbox-web/grid-angular';\nimport type {\n ColumnGroupDefinition as CoreColumnGroupDefinition,\n GroupingColumnsConfig as CoreGroupingColumnsConfig,\n GroupHeaderRenderParams,\n} from '@toolbox-web/grid/plugins/grouping-columns';\n\n/**\n * Column group definition widened to accept an Angular component class as\n * the per-group `renderer`.\n *\n * @since 1.7.0\n */\nexport type ColumnGroupDefinition = Omit<CoreColumnGroupDefinition, 'renderer'> & {\n renderer?: CoreColumnGroupDefinition['renderer'] | Type<unknown>;\n};\n\n/**\n * Grouping-columns config widened to accept Angular component classes for\n * `groupHeaderRenderer` and per-group `renderer` inside `columnGroups`.\n *\n * Component instances receive the {@link GroupHeaderRenderParams} fields as\n * inputs (`id`, `label`, `columns`, `firstIndex`, `isImplicit`).\n *\n * @since 1.7.0\n */\nexport type GroupingColumnsConfig = Omit<CoreGroupingColumnsConfig, 'groupHeaderRenderer' | 'columnGroups'> & {\n columnGroups?: ColumnGroupDefinition[];\n groupHeaderRenderer?: CoreGroupingColumnsConfig['groupHeaderRenderer'] | Type<unknown>;\n};\n\n// ── Deprecated framework-prefixed aliases ────────────────────────────────\n// Retained for backwards compatibility. New code should use the canonical\n// (unprefixed) names above.\n\n/** @deprecated Use {@link ColumnGroupDefinition} instead. */\nexport type AngularColumnGroupDefinition = ColumnGroupDefinition;\n/** @deprecated Use {@link GroupingColumnsConfig} instead. */\nexport type AngularGroupingColumnsConfig = GroupingColumnsConfig;\n\n/**\n * Owns the binding(s) `[groupingColumns]` 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[groupingColumns]',\n standalone: true,\n})\nexport class GridGroupingColumnsDirective implements OnDestroy {\n private readonly elementRef = inject(ElementRef<DataGridElement>);\n\n readonly groupingColumns = input<boolean | GroupingColumnsConfig>();\n\n constructor() {\n registerFeatureClaim(this.elementRef.nativeElement, 'groupingColumns', () => this.groupingColumns());\n }\n\n ngOnDestroy(): void {\n unregisterFeatureClaim(this.elementRef.nativeElement, 'groupingColumns');\n }\n}\n","/**\n * Column grouping feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `groupingColumns` input on Grid directive.\n *\n * @example\n * ```typescript\n * import '@toolbox-web/grid-angular/features/grouping-columns';\n *\n * <tbw-grid [groupingColumns]=\"{ columnGroups: [...] }\" />\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { Type } from '@angular/core';\nimport { isComponentClass, registerFeatureConfigPreprocessor, type GridAdapter } from '@toolbox-web/grid-angular';\nimport '@toolbox-web/grid/features/grouping-columns';\nimport type {\n GroupingColumnsConfig as CoreGroupingColumnsConfig,\n GroupHeaderRenderParams,\n} from '@toolbox-web/grid/plugins/grouping-columns';\nexport {\n GridGroupingColumnsDirective,\n // Deprecated framework-prefixed aliases.\n type AngularColumnGroupDefinition,\n type AngularGroupingColumnsConfig,\n // Canonical (unprefixed) widening types.\n type ColumnGroupDefinition,\n type GroupingColumnsConfig,\n} from './grid-grouping-columns.directive';\nexport type { _Augmentation as _GroupingColumnsAugmentation } from '@toolbox-web/grid/features/grouping-columns';\n\n/**\n * Build a group-header renderer function from an Angular component class.\n * The component should accept group header inputs (id, label, columns, firstIndex, isImplicit).\n */\nfunction buildGroupHeaderRenderer(\n adapter: GridAdapter,\n componentClass: Type<unknown>,\n): (params: GroupHeaderRenderParams) => HTMLElement {\n const mount = adapter.mountComponentRenderer<GroupHeaderRenderParams>(componentClass, (p) => ({\n id: p.id,\n label: p.label,\n columns: p.columns,\n firstIndex: p.firstIndex,\n isImplicit: p.isImplicit,\n }));\n return (params) => mount(params).hostElement;\n}\n\n// Bridge any Angular component classes embedded in the user-supplied config\n// (e.g. group-header renderers) to plain renderer functions before the core\n// plugin factory consumes the config. Without this, raw component classes\n// would be invoked without `new`, causing runtime errors.\nregisterFeatureConfigPreprocessor('groupingColumns', (config, adapter) => {\n if (!config || typeof config !== 'object') return config;\n const cfg = config as CoreGroupingColumnsConfig;\n const processed = { ...cfg };\n let changed = false;\n\n // Bridge top-level groupHeaderRenderer component class\n if (cfg.groupHeaderRenderer && isComponentClass(cfg.groupHeaderRenderer)) {\n processed.groupHeaderRenderer = buildGroupHeaderRenderer(adapter, cfg.groupHeaderRenderer);\n changed = true;\n }\n\n // Bridge per-group renderer component classes inside columnGroups\n if (Array.isArray(cfg.columnGroups)) {\n let groupChanged = false;\n const mappedGroups = cfg.columnGroups.map((def) => {\n if (def.renderer && isComponentClass(def.renderer)) {\n groupChanged = true;\n return { ...def, renderer: buildGroupHeaderRenderer(adapter, def.renderer) };\n }\n return def;\n });\n if (groupChanged) {\n processed.columnGroups = mappedGroups;\n changed = true;\n }\n }\n\n return changed ? processed : cfg;\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-grouping-columns.mjs","sources":["../../../../libs/grid-angular/features/grouping-columns/src/grid-grouping-columns.directive.ts","../../../../libs/grid-angular/features/grouping-columns/src/index.ts","../../../../libs/grid-angular/features/grouping-columns/src/toolbox-web-grid-angular-features-grouping-columns.ts"],"sourcesContent":["/**\n * `GridGroupingColumnsDirective` — owns `[groupingColumns]` on\n * `<tbw-grid>`. No event outputs. See `GridFilteringDirective` for the\n * full rationale.\n *\n * @category Directive\n */\nimport { Directive, ElementRef, inject, input, OnDestroy, type Type } from '@angular/core';\nimport type { DataGridElement } from '@toolbox-web/grid';\nimport { registerFeatureClaim, unregisterFeatureClaim } from '@toolbox-web/grid-angular';\nimport type {\n ColumnGroupDefinition as CoreColumnGroupDefinition,\n GroupingColumnsConfig as CoreGroupingColumnsConfig,\n GroupHeaderRenderParams,\n} from '@toolbox-web/grid/plugins/grouping-columns';\n\n/**\n * Column group definition widened to accept an Angular component class as\n * the per-group `renderer`.\n *\n * @since 1.7.0\n */\nexport type ColumnGroupDefinition = Omit<CoreColumnGroupDefinition, 'renderer'> & {\n renderer?: CoreColumnGroupDefinition['renderer'] | Type<unknown>;\n};\n\n/**\n * Grouping-columns config widened to accept Angular component classes for\n * `groupHeaderRenderer` and per-group `renderer` inside `columnGroups`.\n *\n * Component instances receive the {@link GroupHeaderRenderParams} fields as\n * inputs (`id`, `label`, `columns`, `firstIndex`, `isImplicit`).\n *\n * @since 1.7.0\n */\nexport type GroupingColumnsConfig = Omit<CoreGroupingColumnsConfig, 'groupHeaderRenderer' | 'columnGroups'> & {\n columnGroups?: ColumnGroupDefinition[];\n groupHeaderRenderer?: CoreGroupingColumnsConfig['groupHeaderRenderer'] | Type<unknown>;\n};\n\n// ── Deprecated framework-prefixed aliases ────────────────────────────────\n// Retained for backwards compatibility. New code should use the canonical\n// (unprefixed) names above.\n\n/** @deprecated Use {@link ColumnGroupDefinition} instead. */\nexport type AngularColumnGroupDefinition = ColumnGroupDefinition;\n/** @deprecated Use {@link GroupingColumnsConfig} instead. */\nexport type AngularGroupingColumnsConfig = GroupingColumnsConfig;\n\n/**\n * Owns the binding(s) `[groupingColumns]` 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[groupingColumns]',\n standalone: true,\n})\nexport class GridGroupingColumnsDirective implements OnDestroy {\n private readonly elementRef = inject(ElementRef<DataGridElement>);\n\n readonly groupingColumns = input<boolean | GroupingColumnsConfig>();\n\n constructor() {\n registerFeatureClaim(this.elementRef.nativeElement, 'groupingColumns', () => this.groupingColumns());\n }\n\n ngOnDestroy(): void {\n unregisterFeatureClaim(this.elementRef.nativeElement, 'groupingColumns');\n }\n}\n","/**\n * Column grouping feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `groupingColumns` input on Grid directive.\n *\n * @example\n * ```typescript\n * import '@toolbox-web/grid-angular/features/grouping-columns';\n *\n * <tbw-grid [groupingColumns]=\"{ columnGroups: [...] }\" />\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { Type } from '@angular/core';\nimport { isComponentClass, registerFeatureConfigPreprocessor, type GridAdapter } from '@toolbox-web/grid-angular';\nimport '@toolbox-web/grid/features/grouping-columns';\nimport type {\n GroupingColumnsConfig as CoreGroupingColumnsConfig,\n GroupHeaderRenderParams,\n} from '@toolbox-web/grid/plugins/grouping-columns';\nexport {\n GridGroupingColumnsDirective,\n // Deprecated framework-prefixed aliases.\n type AngularColumnGroupDefinition,\n type AngularGroupingColumnsConfig,\n // Canonical (unprefixed) widening types.\n type ColumnGroupDefinition,\n type GroupingColumnsConfig,\n} from './grid-grouping-columns.directive';\nexport type { _Augmentation as _GroupingColumnsAugmentation } from '@toolbox-web/grid/features/grouping-columns';\n\n/**\n * Build a group-header renderer function from an Angular component class.\n * The component should accept group header inputs (id, label, columns, firstIndex, isImplicit).\n */\nfunction buildGroupHeaderRenderer(\n adapter: GridAdapter,\n componentClass: Type<unknown>,\n): (params: GroupHeaderRenderParams) => HTMLElement {\n const mount = adapter.mountComponentRenderer<GroupHeaderRenderParams>(componentClass, (p) => ({\n id: p.id,\n label: p.label,\n columns: p.columns,\n firstIndex: p.firstIndex,\n isImplicit: p.isImplicit,\n }));\n return (params) => mount(params).hostElement;\n}\n\n// Bridge any Angular component classes embedded in the user-supplied config\n// (e.g. group-header renderers) to plain renderer functions before the core\n// plugin factory consumes the config. Without this, raw component classes\n// would be invoked without `new`, causing runtime errors.\nregisterFeatureConfigPreprocessor('groupingColumns', (config, adapter) => {\n if (!config || typeof config !== 'object') return config;\n const cfg = config as CoreGroupingColumnsConfig;\n const processed = { ...cfg };\n let changed = false;\n\n // Bridge top-level groupHeaderRenderer component class\n if (cfg.groupHeaderRenderer && isComponentClass(cfg.groupHeaderRenderer)) {\n processed.groupHeaderRenderer = buildGroupHeaderRenderer(adapter, cfg.groupHeaderRenderer);\n changed = true;\n }\n\n // Bridge per-group renderer component classes inside columnGroups\n if (Array.isArray(cfg.columnGroups)) {\n let groupChanged = false;\n const mappedGroups = cfg.columnGroups.map((def) => {\n if (def.renderer && isComponentClass(def.renderer)) {\n groupChanged = true;\n return { ...def, renderer: buildGroupHeaderRenderer(adapter, def.renderer) };\n }\n return def;\n });\n if (groupChanged) {\n processed.columnGroups = mappedGroups;\n changed = true;\n }\n }\n\n return changed ? processed : cfg;\n});\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -17,7 +17,8 @@ import { inject, ElementRef, input, output, Directive } from '@angular/core';
17
17
  */
18
18
  class GridGroupingRowsDirective {
19
19
  elementRef = inject((ElementRef));
20
- groupingRows = input(...(ngDevMode ? [undefined, { debugName: "groupingRows" }] : /* istanbul ignore next */ []));
20
+ groupingRows = input(/* @ts-ignore */
21
+ ...(ngDevMode ? [undefined, { debugName: "groupingRows" }] : /* istanbul ignore next */ []));
21
22
  groupToggle = output();
22
23
  groupExpand = output();
23
24
  groupCollapse = output();
@@ -49,10 +50,10 @@ class GridGroupingRowsDirective {
49
50
  for (const ev of GridGroupingRowsDirective.EVENTS)
50
51
  unclaimEvent(grid, ev);
51
52
  }
52
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridGroupingRowsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
53
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: GridGroupingRowsDirective, isStandalone: true, selector: "tbw-grid[groupingRows], tbw-grid[groupToggle], tbw-grid[groupExpand], tbw-grid[groupCollapse]", inputs: { groupingRows: { classPropertyName: "groupingRows", publicName: "groupingRows", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { groupToggle: "groupToggle", groupExpand: "groupExpand", groupCollapse: "groupCollapse" }, ngImport: i0 });
53
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridGroupingRowsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
54
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: GridGroupingRowsDirective, isStandalone: true, selector: "tbw-grid[groupingRows], tbw-grid[groupToggle], tbw-grid[groupExpand], tbw-grid[groupCollapse]", inputs: { groupingRows: { classPropertyName: "groupingRows", publicName: "groupingRows", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { groupToggle: "groupToggle", groupExpand: "groupExpand", groupCollapse: "groupCollapse" }, ngImport: i0 });
54
55
  }
55
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridGroupingRowsDirective, decorators: [{
56
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridGroupingRowsDirective, decorators: [{
56
57
  type: Directive,
57
58
  args: [{
58
59
  selector: 'tbw-grid[groupingRows], tbw-grid[groupToggle], tbw-grid[groupExpand], tbw-grid[groupCollapse]',
@@ -1 +1 @@
1
- {"version":3,"file":"toolbox-web-grid-angular-features-grouping-rows.mjs","sources":["../../../../libs/grid-angular/features/grouping-rows/src/grid-grouping-rows.directive.ts","../../../../libs/grid-angular/features/grouping-rows/src/index.ts","../../../../libs/grid-angular/features/grouping-rows/src/toolbox-web-grid-angular-features-grouping-rows.ts"],"sourcesContent":["/**\n * `GridGroupingRowsDirective` — owns `[groupingRows]` and the group\n * toggle/expand/collapse outputs on `<tbw-grid>`. See\n * `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 GroupingRowsConfig as CoreGroupingRowsConfig,\n GroupCollapseDetail,\n GroupExpandDetail,\n GroupRowRenderParams,\n GroupToggleDetail,\n} from '@toolbox-web/grid/plugins/grouping-rows';\n\n/**\n * Grouping-rows config widened to accept an Angular component class as\n * `groupRowRenderer`.\n *\n * Component instances receive the {@link GroupRowRenderParams} fields as\n * inputs (`key`, `value`, `depth`, `rows`, `expanded`, `toggleExpand`).\n *\n * @since 1.7.0\n */\nexport type GroupingRowsConfig = Omit<CoreGroupingRowsConfig, 'groupRowRenderer'> & {\n groupRowRenderer?: CoreGroupingRowsConfig['groupRowRenderer'] | Type<unknown>;\n};\n\n// ── Deprecated framework-prefixed alias ─────────────────────────────────\n/** @deprecated Use {@link GroupingRowsConfig} instead. */\nexport type AngularGroupingRowsConfig = GroupingRowsConfig;\n\n/**\n * Owns the binding(s) `[groupingRows], [groupToggle], [groupExpand], [groupCollapse]` 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[groupingRows], tbw-grid[groupToggle], tbw-grid[groupExpand], tbw-grid[groupCollapse]',\n standalone: true,\n})\nexport class GridGroupingRowsDirective implements OnInit, OnDestroy {\n private readonly elementRef = inject(ElementRef<DataGridElement>);\n\n readonly groupingRows = input<GroupingRowsConfig>();\n readonly groupToggle = output<GroupToggleDetail>();\n readonly groupExpand = output<GroupExpandDetail>();\n readonly groupCollapse = output<GroupCollapseDetail>();\n\n private readonly listeners = new Map<string, (e: Event) => void>();\n private static readonly EVENTS = ['group-toggle', 'group-expand', 'group-collapse'] as const;\n\n constructor() {\n const grid = this.elementRef.nativeElement;\n registerFeatureClaim(grid, 'groupingRows', () => this.groupingRows());\n for (const ev of GridGroupingRowsDirective.EVENTS) claimEvent(grid, ev);\n }\n\n ngOnInit(): void {\n const grid = this.elementRef.nativeElement;\n const wire = <T>(name: string, out: { emit: (v: T) => void }): void => {\n const l = (e: Event): void => out.emit((e as CustomEvent<T>).detail);\n grid.addEventListener(name, l);\n this.listeners.set(name, l);\n };\n wire<GroupToggleDetail>('group-toggle', this.groupToggle);\n wire<GroupExpandDetail>('group-expand', this.groupExpand);\n wire<GroupCollapseDetail>('group-collapse', this.groupCollapse);\n }\n\n ngOnDestroy(): void {\n const grid = this.elementRef.nativeElement;\n for (const [name, l] of this.listeners) grid.removeEventListener(name, l);\n this.listeners.clear();\n unregisterFeatureClaim(grid, 'groupingRows');\n for (const ev of GridGroupingRowsDirective.EVENTS) unclaimEvent(grid, ev);\n }\n}\n","/**\n * Row grouping feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `groupingRows` input on Grid directive.\n *\n * @example\n * ```typescript\n * import '@toolbox-web/grid-angular/features/grouping-rows';\n *\n * <tbw-grid [groupingRows]=\"{ groupBy: ['department'] }\" />\n * ```\n *\n * @packageDocumentation\n */\n\nimport { isComponentClass, registerFeatureConfigPreprocessor } from '@toolbox-web/grid-angular';\nimport '@toolbox-web/grid/features/grouping-rows';\nimport type {\n GroupingRowsConfig as CoreGroupingRowsConfig,\n GroupRowRenderParams,\n} from '@toolbox-web/grid/plugins/grouping-rows';\nexport {\n GridGroupingRowsDirective,\n type AngularGroupingRowsConfig,\n type GroupingRowsConfig,\n} from './grid-grouping-rows.directive';\nexport type { _Augmentation as _GroupingRowsAugmentation } from '@toolbox-web/grid/features/grouping-rows';\n\n// Bridge any Angular component classes embedded in the user-supplied config\n// (e.g. group-row renderer) to plain renderer functions before the core\n// plugin factory consumes the config.\nregisterFeatureConfigPreprocessor('groupingRows', (config, adapter) => {\n if (!config || typeof config !== 'object') return config;\n const cfg = config as CoreGroupingRowsConfig;\n if (cfg.groupRowRenderer && isComponentClass(cfg.groupRowRenderer)) {\n const mount = adapter.mountComponentRenderer<GroupRowRenderParams>(cfg.groupRowRenderer, (p) => ({\n key: p.key,\n value: p.value,\n depth: p.depth,\n rows: p.rows,\n expanded: p.expanded,\n toggleExpand: p.toggleExpand,\n }));\n return { ...cfg, groupRowRenderer: (params: GroupRowRenderParams) => mount(params).hostElement };\n }\n return cfg;\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-grouping-rows.mjs","sources":["../../../../libs/grid-angular/features/grouping-rows/src/grid-grouping-rows.directive.ts","../../../../libs/grid-angular/features/grouping-rows/src/index.ts","../../../../libs/grid-angular/features/grouping-rows/src/toolbox-web-grid-angular-features-grouping-rows.ts"],"sourcesContent":["/**\n * `GridGroupingRowsDirective` — owns `[groupingRows]` and the group\n * toggle/expand/collapse outputs on `<tbw-grid>`. See\n * `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 GroupingRowsConfig as CoreGroupingRowsConfig,\n GroupCollapseDetail,\n GroupExpandDetail,\n GroupRowRenderParams,\n GroupToggleDetail,\n} from '@toolbox-web/grid/plugins/grouping-rows';\n\n/**\n * Grouping-rows config widened to accept an Angular component class as\n * `groupRowRenderer`.\n *\n * Component instances receive the {@link GroupRowRenderParams} fields as\n * inputs (`key`, `value`, `depth`, `rows`, `expanded`, `toggleExpand`).\n *\n * @since 1.7.0\n */\nexport type GroupingRowsConfig = Omit<CoreGroupingRowsConfig, 'groupRowRenderer'> & {\n groupRowRenderer?: CoreGroupingRowsConfig['groupRowRenderer'] | Type<unknown>;\n};\n\n// ── Deprecated framework-prefixed alias ─────────────────────────────────\n/** @deprecated Use {@link GroupingRowsConfig} instead. */\nexport type AngularGroupingRowsConfig = GroupingRowsConfig;\n\n/**\n * Owns the binding(s) `[groupingRows], [groupToggle], [groupExpand], [groupCollapse]` 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[groupingRows], tbw-grid[groupToggle], tbw-grid[groupExpand], tbw-grid[groupCollapse]',\n standalone: true,\n})\nexport class GridGroupingRowsDirective implements OnInit, OnDestroy {\n private readonly elementRef = inject(ElementRef<DataGridElement>);\n\n readonly groupingRows = input<GroupingRowsConfig>();\n readonly groupToggle = output<GroupToggleDetail>();\n readonly groupExpand = output<GroupExpandDetail>();\n readonly groupCollapse = output<GroupCollapseDetail>();\n\n private readonly listeners = new Map<string, (e: Event) => void>();\n private static readonly EVENTS = ['group-toggle', 'group-expand', 'group-collapse'] as const;\n\n constructor() {\n const grid = this.elementRef.nativeElement;\n registerFeatureClaim(grid, 'groupingRows', () => this.groupingRows());\n for (const ev of GridGroupingRowsDirective.EVENTS) claimEvent(grid, ev);\n }\n\n ngOnInit(): void {\n const grid = this.elementRef.nativeElement;\n const wire = <T>(name: string, out: { emit: (v: T) => void }): void => {\n const l = (e: Event): void => out.emit((e as CustomEvent<T>).detail);\n grid.addEventListener(name, l);\n this.listeners.set(name, l);\n };\n wire<GroupToggleDetail>('group-toggle', this.groupToggle);\n wire<GroupExpandDetail>('group-expand', this.groupExpand);\n wire<GroupCollapseDetail>('group-collapse', this.groupCollapse);\n }\n\n ngOnDestroy(): void {\n const grid = this.elementRef.nativeElement;\n for (const [name, l] of this.listeners) grid.removeEventListener(name, l);\n this.listeners.clear();\n unregisterFeatureClaim(grid, 'groupingRows');\n for (const ev of GridGroupingRowsDirective.EVENTS) unclaimEvent(grid, ev);\n }\n}\n","/**\n * Row grouping feature for @toolbox-web/grid-angular\n *\n * Import this module to enable the `groupingRows` input on Grid directive.\n *\n * @example\n * ```typescript\n * import '@toolbox-web/grid-angular/features/grouping-rows';\n *\n * <tbw-grid [groupingRows]=\"{ groupBy: ['department'] }\" />\n * ```\n *\n * @packageDocumentation\n */\n\nimport { isComponentClass, registerFeatureConfigPreprocessor } from '@toolbox-web/grid-angular';\nimport '@toolbox-web/grid/features/grouping-rows';\nimport type {\n GroupingRowsConfig as CoreGroupingRowsConfig,\n GroupRowRenderParams,\n} from '@toolbox-web/grid/plugins/grouping-rows';\nexport {\n GridGroupingRowsDirective,\n type AngularGroupingRowsConfig,\n type GroupingRowsConfig,\n} from './grid-grouping-rows.directive';\nexport type { _Augmentation as _GroupingRowsAugmentation } from '@toolbox-web/grid/features/grouping-rows';\n\n// Bridge any Angular component classes embedded in the user-supplied config\n// (e.g. group-row renderer) to plain renderer functions before the core\n// plugin factory consumes the config.\nregisterFeatureConfigPreprocessor('groupingRows', (config, adapter) => {\n if (!config || typeof config !== 'object') return config;\n const cfg = config as CoreGroupingRowsConfig;\n if (cfg.groupRowRenderer && isComponentClass(cfg.groupRowRenderer)) {\n const mount = adapter.mountComponentRenderer<GroupRowRenderParams>(cfg.groupRowRenderer, (p) => ({\n key: p.key,\n value: p.value,\n depth: p.depth,\n rows: p.rows,\n expanded: p.expanded,\n toggleExpand: p.toggleExpand,\n }));\n return { ...cfg, groupRowRenderer: (params: GroupRowRenderParams) => mount(params).hostElement };\n }\n return cfg;\n});\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -67,13 +67,16 @@ function getDetailTemplate(gridElement) {
67
67
  class GridDetailView {
68
68
  elementRef = inject((ElementRef));
69
69
  /** Whether to show the expand/collapse column. Default: true */
70
- showExpandColumn = input(true, ...(ngDevMode ? [{ debugName: "showExpandColumn" }] : /* istanbul ignore next */ []));
70
+ showExpandColumn = input(true, /* @ts-ignore */
71
+ ...(ngDevMode ? [{ debugName: "showExpandColumn" }] : /* istanbul ignore next */ []));
71
72
  /** Animation style for expand/collapse. Default: 'slide' */
72
- animation = input('slide', ...(ngDevMode ? [{ debugName: "animation" }] : /* istanbul ignore next */ []));
73
+ animation = input('slide', /* @ts-ignore */
74
+ ...(ngDevMode ? [{ debugName: "animation" }] : /* istanbul ignore next */ []));
73
75
  /**
74
76
  * Query for the ng-template content child.
75
77
  */
76
- template = contentChild((TemplateRef), ...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
78
+ template = contentChild((TemplateRef), /* @ts-ignore */
79
+ ...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
77
80
  /** Effect that triggers when the template is available */
78
81
  onTemplateReceived = effect(() => {
79
82
  const template = this.template();
@@ -81,7 +84,8 @@ class GridDetailView {
81
84
  // Register the template for this element
82
85
  detailTemplateRegistry.set(this.elementRef.nativeElement, template);
83
86
  }
84
- }, ...(ngDevMode ? [{ debugName: "onTemplateReceived" }] : /* istanbul ignore next */ []));
87
+ }, /* @ts-ignore */
88
+ ...(ngDevMode ? [{ debugName: "onTemplateReceived" }] : /* istanbul ignore next */ []));
85
89
  /**
86
90
  * Static type guard for template context.
87
91
  * Enables type inference in templates.
@@ -89,10 +93,10 @@ class GridDetailView {
89
93
  static ngTemplateContextGuard(dir, ctx) {
90
94
  return true;
91
95
  }
92
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridDetailView, deps: [], target: i0.ɵɵFactoryTarget.Directive });
93
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.5", type: GridDetailView, isStandalone: true, selector: "tbw-grid-detail", inputs: { showExpandColumn: { classPropertyName: "showExpandColumn", publicName: "showExpandColumn", isSignal: true, isRequired: false, transformFunction: null }, animation: { classPropertyName: "animation", publicName: "animation", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "template", first: true, predicate: (TemplateRef), descendants: true, isSignal: true }], ngImport: i0 });
96
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridDetailView, deps: [], target: i0.ɵɵFactoryTarget.Directive });
97
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "22.0.6", type: GridDetailView, isStandalone: true, selector: "tbw-grid-detail", inputs: { showExpandColumn: { classPropertyName: "showExpandColumn", publicName: "showExpandColumn", isSignal: true, isRequired: false, transformFunction: null }, animation: { classPropertyName: "animation", publicName: "animation", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "template", first: true, predicate: (TemplateRef), descendants: true, isSignal: true }], ngImport: i0 });
94
98
  }
95
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridDetailView, decorators: [{
99
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridDetailView, decorators: [{
96
100
  type: Directive,
97
101
  args: [{ selector: 'tbw-grid-detail' }]
98
102
  }], 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 }] }] } });
@@ -115,7 +119,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
115
119
  */
116
120
  class GridMasterDetailDirective {
117
121
  elementRef = inject((ElementRef));
118
- masterDetail = input(...(ngDevMode ? [undefined, { debugName: "masterDetail" }] : /* istanbul ignore next */ []));
122
+ masterDetail = input(/* @ts-ignore */
123
+ ...(ngDevMode ? [undefined, { debugName: "masterDetail" }] : /* istanbul ignore next */ []));
119
124
  detailExpand = output();
120
125
  listener;
121
126
  constructor() {
@@ -137,10 +142,10 @@ class GridMasterDetailDirective {
137
142
  unregisterFeatureClaim(grid, 'masterDetail');
138
143
  unclaimEvent(grid, 'detail-expand');
139
144
  }
140
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridMasterDetailDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
141
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: GridMasterDetailDirective, isStandalone: true, selector: "tbw-grid[masterDetail], tbw-grid[detailExpand]", inputs: { masterDetail: { classPropertyName: "masterDetail", publicName: "masterDetail", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { detailExpand: "detailExpand" }, ngImport: i0 });
145
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridMasterDetailDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
146
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: GridMasterDetailDirective, isStandalone: true, selector: "tbw-grid[masterDetail], tbw-grid[detailExpand]", inputs: { masterDetail: { classPropertyName: "masterDetail", publicName: "masterDetail", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { detailExpand: "detailExpand" }, ngImport: i0 });
142
147
  }
143
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridMasterDetailDirective, decorators: [{
148
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridMasterDetailDirective, decorators: [{
144
149
  type: Directive,
145
150
  args: [{
146
151
  selector: 'tbw-grid[masterDetail], tbw-grid[detailExpand]',