@toolbox-web/grid-angular 2.0.0-rc.1 → 2.1.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 (55) 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 +128 -72
  52. package/fesm2022/toolbox-web-grid-angular.mjs.map +1 -1
  53. package/package.json +2 -2
  54. package/types/toolbox-web-grid-angular.d.ts +5 -0
  55. package/types/toolbox-web-grid-angular.d.ts.map +1 -1
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ElementRef, contentChild, TemplateRef, effect, Directive, InjectionToken, Injectable, makeEnvironmentProviders, createComponent, DestroyRef, signal, afterNextRender, computed, EnvironmentInjector, ApplicationRef, ViewContainerRef, input, output } from '@angular/core';
2
+ import { inject, ElementRef, contentChild, TemplateRef, effect, Directive, InjectionToken, Injectable, makeEnvironmentProviders, createComponent, DestroyRef, signal, afterNextRender, computed, EnvironmentInjector, ApplicationRef, ViewContainerRef, untracked, input, output } from '@angular/core';
3
3
  import { createPluginFromFeature } from '@toolbox-web/grid/features/registry';
4
4
  export { clearFeatureRegistry, createPluginFromFeature, getFeatureFactory, getRegisteredFeatures, isFeatureRegistered, registerFeature } from '@toolbox-web/grid/features/registry';
5
5
  import { applyColumnDefaults, normalizeColumns, DataGridElement } from '@toolbox-web/grid';
@@ -84,7 +84,8 @@ class GridColumnView {
84
84
  /**
85
85
  * Query for the ng-template content child.
86
86
  */
87
- template = contentChild((TemplateRef), ...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
87
+ template = contentChild((TemplateRef), /* @ts-ignore */
88
+ ...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
88
89
  /** Effect that triggers when the template is available */
89
90
  onTemplateReceived = effect(() => {
90
91
  const template = this.template();
@@ -92,7 +93,8 @@ class GridColumnView {
92
93
  // Register the template for this element
93
94
  templateRegistry.set(this.elementRef.nativeElement, template);
94
95
  }
95
- }, ...(ngDevMode ? [{ debugName: "onTemplateReceived" }] : /* istanbul ignore next */ []));
96
+ }, /* @ts-ignore */
97
+ ...(ngDevMode ? [{ debugName: "onTemplateReceived" }] : /* istanbul ignore next */ []));
96
98
  /**
97
99
  * Static type guard for template context.
98
100
  * Enables type inference in templates.
@@ -100,10 +102,10 @@ class GridColumnView {
100
102
  static ngTemplateContextGuard(dir, ctx) {
101
103
  return true;
102
104
  }
103
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridColumnView, deps: [], target: i0.ɵɵFactoryTarget.Directive });
104
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.5", type: GridColumnView, isStandalone: true, selector: "tbw-grid-column-view", queries: [{ propertyName: "template", first: true, predicate: (TemplateRef), descendants: true, isSignal: true }], ngImport: i0 });
105
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridColumnView, deps: [], target: i0.ɵɵFactoryTarget.Directive });
106
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "22.0.6", type: GridColumnView, isStandalone: true, selector: "tbw-grid-column-view", queries: [{ propertyName: "template", first: true, predicate: (TemplateRef), descendants: true, isSignal: true }], ngImport: i0 });
105
107
  }
106
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridColumnView, decorators: [{
108
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridColumnView, decorators: [{
107
109
  type: Directive,
108
110
  args: [{ selector: 'tbw-grid-column-view' }]
109
111
  }], propDecorators: { template: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }] } });
@@ -214,10 +216,10 @@ class TbwRenderer {
214
216
  static ngTemplateContextGuard(dir, ctx) {
215
217
  return true;
216
218
  }
217
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TbwRenderer, deps: [], target: i0.ɵɵFactoryTarget.Directive });
218
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: TbwRenderer, isStandalone: true, selector: "[tbwRenderer]", ngImport: i0 });
219
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TbwRenderer, deps: [], target: i0.ɵɵFactoryTarget.Directive });
220
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: TbwRenderer, isStandalone: true, selector: "[tbwRenderer]", ngImport: i0 });
219
221
  }
220
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TbwRenderer, decorators: [{
222
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TbwRenderer, decorators: [{
221
223
  type: Directive,
222
224
  args: [{ selector: '[tbwRenderer]' }]
223
225
  }], ctorParameters: () => [] });
@@ -480,10 +482,10 @@ class GridTypeRegistry {
480
482
  // the actual functions that instantiate Angular components
481
483
  };
482
484
  }
483
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridTypeRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
484
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridTypeRegistry, providedIn: 'root' });
485
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridTypeRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
486
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridTypeRegistry, providedIn: 'root' });
485
487
  }
486
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridTypeRegistry, decorators: [{
488
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridTypeRegistry, decorators: [{
487
489
  type: Injectable,
488
490
  args: [{ providedIn: 'root' }]
489
491
  }], ctorParameters: () => [] });
@@ -1642,10 +1644,10 @@ class GridIconRegistry {
1642
1644
  getRegisteredIcons() {
1643
1645
  return Array.from(this.icons.keys());
1644
1646
  }
1645
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridIconRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1646
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridIconRegistry, providedIn: 'root' });
1647
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridIconRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1648
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridIconRegistry, providedIn: 'root' });
1647
1649
  }
1648
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GridIconRegistry, decorators: [{
1650
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridIconRegistry, decorators: [{
1649
1651
  type: Injectable,
1650
1652
  args: [{ providedIn: 'root' }]
1651
1653
  }], ctorParameters: () => [] });
@@ -1733,9 +1735,12 @@ function injectGrid(selector = 'tbw-grid') {
1733
1735
  const elementRef = inject(ElementRef);
1734
1736
  const destroyRef = inject(DestroyRef);
1735
1737
  // Reactive signals
1736
- const isReady = signal(false, ...(ngDevMode ? [{ debugName: "isReady" }] : /* istanbul ignore next */ []));
1737
- const config = signal(null, ...(ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []));
1738
- const element = signal(null, ...(ngDevMode ? [{ debugName: "element" }] : /* istanbul ignore next */ []));
1738
+ const isReady = signal(false, /* @ts-ignore */
1739
+ ...(ngDevMode ? [{ debugName: "isReady" }] : /* istanbul ignore next */ []));
1740
+ const config = signal(null, /* @ts-ignore */
1741
+ ...(ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []));
1742
+ const element = signal(null, /* @ts-ignore */
1743
+ ...(ngDevMode ? [{ debugName: "element" }] : /* istanbul ignore next */ []));
1739
1744
  // Track destruction so async work doesn't touch signals after teardown
1740
1745
  let destroyed = false;
1741
1746
  destroyRef.onDestroy(() => {
@@ -1773,7 +1778,8 @@ function injectGrid(selector = 'tbw-grid') {
1773
1778
  if (!currentConfig?.columns)
1774
1779
  return [];
1775
1780
  return currentConfig.columns.filter((col) => !col.hidden);
1776
- }, ...(ngDevMode ? [{ debugName: "visibleColumns" }] : /* istanbul ignore next */ []));
1781
+ }, /* @ts-ignore */
1782
+ ...(ngDevMode ? [{ debugName: "visibleColumns" }] : /* istanbul ignore next */ []));
1777
1783
  // ═══════════════════════════════════════════════════════════════════
1778
1784
  // CORE METHODS
1779
1785
  // ═══════════════════════════════════════════════════════════════════
@@ -1889,10 +1895,10 @@ function injectGrid(selector = 'tbw-grid') {
1889
1895
  * @since 0.13.0
1890
1896
  */
1891
1897
  class TbwGridColumn {
1892
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TbwGridColumn, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1893
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: TbwGridColumn, isStandalone: true, selector: "tbw-grid-column", ngImport: i0 });
1898
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TbwGridColumn, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1899
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: TbwGridColumn, isStandalone: true, selector: "tbw-grid-column", ngImport: i0 });
1894
1900
  }
1895
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TbwGridColumn, decorators: [{
1901
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TbwGridColumn, decorators: [{
1896
1902
  type: Directive,
1897
1903
  args: [{
1898
1904
  selector: 'tbw-grid-column',
@@ -1928,10 +1934,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
1928
1934
  * @since 0.13.0
1929
1935
  */
1930
1936
  class TbwGridHeader {
1931
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TbwGridHeader, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1932
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: TbwGridHeader, isStandalone: true, selector: "tbw-grid-header", ngImport: i0 });
1937
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TbwGridHeader, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1938
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: TbwGridHeader, isStandalone: true, selector: "tbw-grid-header", ngImport: i0 });
1933
1939
  }
1934
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TbwGridHeader, decorators: [{
1940
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TbwGridHeader, decorators: [{
1935
1941
  type: Directive,
1936
1942
  args: [{
1937
1943
  selector: 'tbw-grid-header',
@@ -1968,10 +1974,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
1968
1974
  * @since 0.13.0
1969
1975
  */
1970
1976
  class TbwGridToolButtons {
1971
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TbwGridToolButtons, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1972
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: TbwGridToolButtons, isStandalone: true, selector: "tbw-grid-tool-buttons", ngImport: i0 });
1977
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TbwGridToolButtons, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1978
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: TbwGridToolButtons, isStandalone: true, selector: "tbw-grid-tool-buttons", ngImport: i0 });
1973
1979
  }
1974
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TbwGridToolButtons, decorators: [{
1980
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TbwGridToolButtons, decorators: [{
1975
1981
  type: Directive,
1976
1982
  args: [{
1977
1983
  selector: 'tbw-grid-tool-buttons',
@@ -1988,10 +1994,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
1988
1994
  * @since 2.0.0
1989
1995
  */
1990
1996
  class TbwGridType {
1991
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TbwGridType, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1992
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.5", type: TbwGridType, isStandalone: true, selector: "tbw-grid-type", ngImport: i0 });
1997
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TbwGridType, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1998
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", type: TbwGridType, isStandalone: true, selector: "tbw-grid-type", ngImport: i0 });
1993
1999
  }
1994
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TbwGridType, decorators: [{
2000
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TbwGridType, decorators: [{
1995
2001
  type: Directive,
1996
2002
  args: [{
1997
2003
  selector: 'tbw-grid-type',
@@ -2079,6 +2085,36 @@ function unclaimEvent(grid, eventName) {
2079
2085
  eventClaims.get(grid)?.delete(eventName);
2080
2086
  }
2081
2087
 
2088
+ /**
2089
+ * Computes the minimal set of row updates needed when only values have changed
2090
+ * (same row count, same row IDs in the same order).
2091
+ *
2092
+ * Returns an array of updates (possibly empty) when the diff is value-only, or
2093
+ * `null` when a structural change is detected (different count, different IDs
2094
+ * in sequence, or initial load from an empty snapshot).
2095
+ *
2096
+ * Called by the Angular `Grid` directive's rows effect to decide whether to
2097
+ * call `grid.updateRows()` (value-only, fast path) or `grid.rows =` (full
2098
+ * replace). Kept as a pure helper so it can be unit-tested without Angular.
2099
+ */
2100
+ function computeRowDiff(next, prev, getId) {
2101
+ if (prev.length === 0 || next.length !== prev.length)
2102
+ return null;
2103
+ const updates = [];
2104
+ for (let i = 0; i < next.length; i++) {
2105
+ const nextRow = next[i];
2106
+ const prevRow = prev[i];
2107
+ const nextId = getId(nextRow);
2108
+ const prevId = getId(prevRow);
2109
+ if (nextId !== prevId)
2110
+ return null;
2111
+ if (prevRow !== nextRow) {
2112
+ updates.push({ id: nextId, changes: nextRow });
2113
+ }
2114
+ }
2115
+ return updates;
2116
+ }
2117
+
2082
2118
  /**
2083
2119
  * Directive that automatically registers the Angular adapter with tbw-grid elements.
2084
2120
  *
@@ -2139,6 +2175,11 @@ class Grid {
2139
2175
  viewContainerRef = inject(ViewContainerRef);
2140
2176
  iconRegistry = inject(GridIconRegistry, { optional: true });
2141
2177
  adapter = null;
2178
+ /**
2179
+ * Previous rows snapshot for in-place diffing — kept in sync by the rows
2180
+ * effect. Plain field so Angular's signal tracking ignores it.
2181
+ */
2182
+ prevRows = [];
2142
2183
  constructor() {
2143
2184
  // Effect to process gridConfig and apply to grid
2144
2185
  // This merges feature input plugins with the user's config plugins
@@ -2200,11 +2241,42 @@ class Grid {
2200
2241
  grid.loading = loadingValue;
2201
2242
  });
2202
2243
  // Effect to sync rows to the grid element
2244
+ //
2245
+ // Smart diff: when getRowId is configured and the same rows appear in the
2246
+ // same order with only their values changed, route through updateRows() to
2247
+ // patch in-place. This triggers only RenderPhase.VIRTUALIZATION instead of
2248
+ // the heavier ROWS phase, which rebuilds the row model and re-applies
2249
+ // sort/filter. Mirrors the React and Vue adapters.
2203
2250
  effect(() => {
2204
2251
  const rowsValue = this.rows();
2205
2252
  if (rowsValue === undefined)
2206
2253
  return;
2207
2254
  const grid = this.elementRef.nativeElement;
2255
+ const prev = this.prevRows;
2256
+ // Read getRowId without registering as a signal dependency so this effect
2257
+ // only re-runs on rows changes, not on every gridConfig change.
2258
+ const getId = untracked(() => this.gridConfig()?.getRowId);
2259
+ this.prevRows = rowsValue;
2260
+ if (getId) {
2261
+ const diff = computeRowDiff(rowsValue, prev, getId);
2262
+ if (diff !== null) {
2263
+ if (diff.length > 0) {
2264
+ // 'sync' source: authoritative host data, not a user edit — editing
2265
+ // plugin skips dirty marking / undo history for it.
2266
+ try {
2267
+ grid.updateRows(diff, 'sync');
2268
+ }
2269
+ catch {
2270
+ // getRowId changed alongside rows (grid still resolving ids with
2271
+ // the previous resolver) or an id vanished — fall back to a full
2272
+ // replace, which reapplies the whole array under the current resolver.
2273
+ grid.rows = rowsValue;
2274
+ }
2275
+ }
2276
+ return;
2277
+ }
2278
+ }
2279
+ // Structural change (adds/removes/reorder), no getRowId, or initial load — full replace.
2208
2280
  grid.rows = rowsValue;
2209
2281
  });
2210
2282
  // Effect to sync columns to the grid element
@@ -2266,7 +2338,8 @@ class Grid {
2266
2338
  * <tbw-grid [customStyles]="customStyles">...</tbw-grid>
2267
2339
  * ```
2268
2340
  */
2269
- customStyles = input(...(ngDevMode ? [undefined, { debugName: "customStyles" }] : /* istanbul ignore next */ []));
2341
+ customStyles = input(/* @ts-ignore */
2342
+ ...(ngDevMode ? [undefined, { debugName: "customStyles" }] : /* istanbul ignore next */ []));
2270
2343
  /**
2271
2344
  * Grid-wide sorting toggle.
2272
2345
  * When false, disables sorting for all columns regardless of their individual `sortable` setting.
@@ -2289,7 +2362,8 @@ class Grid {
2289
2362
  * <tbw-grid [sortable]="true" [multiSort]="true" />
2290
2363
  * ```
2291
2364
  */
2292
- sortable = input(...(ngDevMode ? [undefined, { debugName: "sortable" }] : /* istanbul ignore next */ []));
2365
+ sortable = input(/* @ts-ignore */
2366
+ ...(ngDevMode ? [undefined, { debugName: "sortable" }] : /* istanbul ignore next */ []));
2293
2367
  /**
2294
2368
  * Grid-wide filtering toggle.
2295
2369
  * When false, disables filtering for all columns regardless of their individual `filterable` setting.
@@ -2308,7 +2382,8 @@ class Grid {
2308
2382
  * <tbw-grid [filterable]="true" [filtering]="true" />
2309
2383
  * ```
2310
2384
  */
2311
- filterable = input(...(ngDevMode ? [undefined, { debugName: "filterable" }] : /* istanbul ignore next */ []));
2385
+ filterable = input(/* @ts-ignore */
2386
+ ...(ngDevMode ? [undefined, { debugName: "filterable" }] : /* istanbul ignore next */ []));
2312
2387
  /**
2313
2388
  * Grid-wide selection toggle.
2314
2389
  * When false, disables selection for all rows/cells.
@@ -2327,7 +2402,8 @@ class Grid {
2327
2402
  * <tbw-grid [selectable]="true" [selection]="'range'" />
2328
2403
  * ```
2329
2404
  */
2330
- selectable = input(...(ngDevMode ? [undefined, { debugName: "selectable" }] : /* istanbul ignore next */ []));
2405
+ selectable = input(/* @ts-ignore */
2406
+ ...(ngDevMode ? [undefined, { debugName: "selectable" }] : /* istanbul ignore next */ []));
2331
2407
  /**
2332
2408
  * Show a loading overlay on the grid.
2333
2409
  * Use this during initial data fetch or refresh operations.
@@ -2355,7 +2431,8 @@ class Grid {
2355
2431
  * }
2356
2432
  * ```
2357
2433
  */
2358
- loading = input(...(ngDevMode ? [undefined, { debugName: "loading" }] : /* istanbul ignore next */ []));
2434
+ loading = input(/* @ts-ignore */
2435
+ ...(ngDevMode ? [undefined, { debugName: "loading" }] : /* istanbul ignore next */ []));
2359
2436
  /**
2360
2437
  * The data rows to display in the grid.
2361
2438
  *
@@ -2368,7 +2445,8 @@ class Grid {
2368
2445
  * ```
2369
2446
  */
2370
2447
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
2371
- rows = input(...(ngDevMode ? [undefined, { debugName: "rows" }] : /* istanbul ignore next */ []));
2448
+ rows = input(/* @ts-ignore */
2449
+ ...(ngDevMode ? [undefined, { debugName: "rows" }] : /* istanbul ignore next */ []));
2372
2450
  /**
2373
2451
  * Column configuration array.
2374
2452
  *
@@ -2386,7 +2464,8 @@ class Grid {
2386
2464
  * ```
2387
2465
  */
2388
2466
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
2389
- columns = input(...(ngDevMode ? [undefined, { debugName: "columns" }] : /* istanbul ignore next */ []));
2467
+ columns = input(/* @ts-ignore */
2468
+ ...(ngDevMode ? [undefined, { debugName: "columns" }] : /* istanbul ignore next */ []));
2390
2469
  /**
2391
2470
  * Default column properties applied to every column in `columns`.
2392
2471
  * Individual column properties override these defaults.
@@ -2400,7 +2479,8 @@ class Grid {
2400
2479
  * ```
2401
2480
  */
2402
2481
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
2403
- columnDefaults = input(...(ngDevMode ? [undefined, { debugName: "columnDefaults" }] : /* istanbul ignore next */ []));
2482
+ columnDefaults = input(/* @ts-ignore */
2483
+ ...(ngDevMode ? [undefined, { debugName: "columnDefaults" }] : /* istanbul ignore next */ []));
2404
2484
  /**
2405
2485
  * Column sizing strategy.
2406
2486
  *
@@ -2416,7 +2496,8 @@ class Grid {
2416
2496
  * <tbw-grid [rows]="data" [fitMode]="dynamicMode()" />
2417
2497
  * ```
2418
2498
  */
2419
- fitMode = input(...(ngDevMode ? [undefined, { debugName: "fitMode" }] : /* istanbul ignore next */ []));
2499
+ fitMode = input(/* @ts-ignore */
2500
+ ...(ngDevMode ? [undefined, { debugName: "fitMode" }] : /* istanbul ignore next */ []));
2420
2501
  /**
2421
2502
  * How automatic column inference combines with explicitly provided columns.
2422
2503
  *
@@ -2429,7 +2510,8 @@ class Grid {
2429
2510
  * <tbw-grid [rows]="data" [columnInference]="mode()" />
2430
2511
  * ```
2431
2512
  */
2432
- columnInference = input(...(ngDevMode ? [undefined, { debugName: "columnInference" }] : /* istanbul ignore next */ []));
2513
+ columnInference = input(/* @ts-ignore */
2514
+ ...(ngDevMode ? [undefined, { debugName: "columnInference" }] : /* istanbul ignore next */ []));
2433
2515
  /**
2434
2516
  * Grid configuration object with optional Angular-specific extensions.
2435
2517
  *
@@ -2467,7 +2549,8 @@ class Grid {
2467
2549
  * ```
2468
2550
  */
2469
2551
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
2470
- gridConfig = input(...(ngDevMode ? [undefined, { debugName: "gridConfig" }] : /* istanbul ignore next */ []));
2552
+ gridConfig = input(/* @ts-ignore */
2553
+ ...(ngDevMode ? [undefined, { debugName: "gridConfig" }] : /* istanbul ignore next */ []));
2471
2554
  // ═══════════════════════════════════════════════════════════════════════════
2472
2555
  // EVENT OUTPUTS - All grid events
2473
2556
  // ═══════════════════════════════════════════════════════════════════════════
@@ -2610,33 +2693,6 @@ class Grid {
2610
2693
  tbwScroll: 'tbw-scroll',
2611
2694
  render: 'render',
2612
2695
  };
2613
- // ─────────────────────────────────────────────────────────────────────────
2614
- // Forward-only event coverage guard.
2615
- //
2616
- // Mirrors the React adapter's `_AssertFeaturePropsCoverCore` pattern. If a
2617
- // new event is added to core's `DataGridEventMap` (via plugin module
2618
- // augmentation in `/all`) but no `eventOutputMap` entry covers it, this
2619
- // type fails to evaluate to `true` and the build breaks. Adapter consumers
2620
- // never see a silently-dropped event.
2621
- //
2622
- // Reverse direction (extra `eventOutputMap` entries pointing at non-existent
2623
- // events) is already enforced by the `satisfies` clause above.
2624
- //
2625
- // To consciously omit an event from the `Grid` directive surface, add it to
2626
- // the `_intentionallyOmittedEvents` union below with a comment explaining why.
2627
- // ─────────────────────────────────────────────────────────────────────────
2628
- /**
2629
- * Events deliberately not exposed as outputs on the `Grid` directive.
2630
- *
2631
- * Every entry here is a **feature-owned** event surfaced by its per-feature
2632
- * directive instead (e.g. `GridEditingDirective` declares `(cellCommit)`,
2633
- * `GridSelectionDirective` declares `(selectionChange)`). The directive
2634
- * claims the DOM event via `claimEvent` so it is the sole emitter. The v1.x
2635
- * shims that forwarded these events from `Grid` were removed in v3.0.0 —
2636
- * consumers must import the relevant feature directive.
2637
- */
2638
- _intentionallyOmittedEvents;
2639
- _assertEventOutputMapCoversCore;
2640
2696
  // Store event listeners for cleanup
2641
2697
  eventListeners = new Map();
2642
2698
  ngOnInit() {
@@ -2799,10 +2855,10 @@ class Grid {
2799
2855
  this.adapter = null;
2800
2856
  }
2801
2857
  }
2802
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: Grid, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2803
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: Grid, isStandalone: true, selector: "tbw-grid,[data-tbw-grid]", inputs: { customStyles: { classPropertyName: "customStyles", publicName: "customStyles", isSignal: true, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, columnDefaults: { classPropertyName: "columnDefaults", publicName: "columnDefaults", isSignal: true, isRequired: false, transformFunction: null }, fitMode: { classPropertyName: "fitMode", publicName: "fitMode", isSignal: true, isRequired: false, transformFunction: null }, columnInference: { classPropertyName: "columnInference", publicName: "columnInference", isSignal: true, isRequired: false, transformFunction: null }, gridConfig: { classPropertyName: "gridConfig", publicName: "gridConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellClick: "cellClick", rowClick: "rowClick", cellActivate: "cellActivate", cellChange: "cellChange", dataChange: "dataChange", sortChange: "sortChange", columnResize: "columnResize", columnResizeReset: "columnResizeReset", columnStateChange: "columnStateChange", tbwScroll: "tbwScroll", render: "render" }, ngImport: i0 });
2858
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: Grid, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2859
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: Grid, isStandalone: true, selector: "tbw-grid,[data-tbw-grid]", inputs: { customStyles: { classPropertyName: "customStyles", publicName: "customStyles", isSignal: true, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, columnDefaults: { classPropertyName: "columnDefaults", publicName: "columnDefaults", isSignal: true, isRequired: false, transformFunction: null }, fitMode: { classPropertyName: "fitMode", publicName: "fitMode", isSignal: true, isRequired: false, transformFunction: null }, columnInference: { classPropertyName: "columnInference", publicName: "columnInference", isSignal: true, isRequired: false, transformFunction: null }, gridConfig: { classPropertyName: "gridConfig", publicName: "gridConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellClick: "cellClick", rowClick: "rowClick", cellActivate: "cellActivate", cellChange: "cellChange", dataChange: "dataChange", sortChange: "sortChange", columnResize: "columnResize", columnResizeReset: "columnResizeReset", columnStateChange: "columnStateChange", tbwScroll: "tbwScroll", render: "render" }, ngImport: i0 });
2804
2860
  }
2805
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: Grid, decorators: [{
2861
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: Grid, decorators: [{
2806
2862
  type: Directive,
2807
2863
  args: [{ selector: 'tbw-grid,[data-tbw-grid]' }]
2808
2864
  }], ctorParameters: () => [], propDecorators: { customStyles: [{ type: i0.Input, args: [{ isSignal: true, alias: "customStyles", required: false }] }], sortable: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortable", required: false }] }], filterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterable", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], columnDefaults: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnDefaults", required: false }] }], fitMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "fitMode", required: false }] }], columnInference: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnInference", required: false }] }], gridConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "gridConfig", required: false }] }], cellClick: [{ type: i0.Output, args: ["cellClick"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], cellActivate: [{ type: i0.Output, args: ["cellActivate"] }], cellChange: [{ type: i0.Output, args: ["cellChange"] }], dataChange: [{ type: i0.Output, args: ["dataChange"] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], columnResize: [{ type: i0.Output, args: ["columnResize"] }], columnResizeReset: [{ type: i0.Output, args: ["columnResizeReset"] }], columnStateChange: [{ type: i0.Output, args: ["columnStateChange"] }], tbwScroll: [{ type: i0.Output, args: ["tbwScroll"] }], render: [{ type: i0.Output, args: ["render"] }] } });