@agility-workbench/angular-grid 1.10.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -77,6 +77,13 @@ are not overwritten), `[pivotColumnMoveMode]` is live, `[pivotResultColumnDef]`
77
77
  `[sheets]` renders the footer tab strip with the same app-owned persistence contract as
78
78
  `[savedViews]`. See the core README for what pivot mode and sheets do.
79
79
 
80
+ Most inputs are live. The ones the grid reads only at creation (`rowHeight`, `getRowId`,
81
+ `rowIdKey`, `rowModelType`, `defaultColDef`, `groupColumnDef`, `pivotResultColumnDef`,
82
+ `initialSort`, … — the core's `CREATION_ONLY_OPTION_KEYS`, minus the bridged inputs) ignore later
83
+ changes; in development mode (`isDevMode()`) the grid logs one `console.warn` naming the input when
84
+ that happens. Re-create the `<awb-grid>` (for example under an `@if`, or a keyed `@for`) to apply
85
+ such a change. The Angular page of the documentation site has the full live-vs-creation table.
86
+
80
87
  ## Styling
81
88
 
82
89
  Nothing to do — the grid delivers its own stylesheet when it attaches, once per document, and
@@ -91,8 +98,11 @@ copies do not fight in the cascade.
91
98
  ## Angular components in the grid
92
99
 
93
100
  Column definitions accept Angular component classes wherever the core accepts a class component —
94
- `cellRenderer`, `cellEditor`, `tooltipComponent`, `headerTooltip`, and `actionFrameComponent`.
95
- A component receives its params either through an input named `params` or by implementing
101
+ `cellRenderer`, `cellEditor`, `tooltipComponent`, `headerTooltip`, `actionFrameComponent`, the
102
+ set-filter components in `filterParams`, and the header components `headerComponent` (header
103
+ content) and `headerCellComponent` (the whole header cell; contract `IHeaderNgComp`). The same slots
104
+ are adapted in `[defaultColDef]`, `[groupColumnDef]`, and `[pivotResultColumnDef]`. A component
105
+ receives its params either through an input named `params` or by implementing
96
106
  `awbInit(params)` (plus optional `awbRefresh(params)`):
97
107
 
98
108
  ```ts
@@ -1,7 +1,7 @@
1
- import { isClassRenderer, isClassTooltipComponent, isClassActionFrameComponent, isClassSetFilterComponent, createGrid } from '@agility-workbench/grid';
1
+ import { isClassRenderer, isClassTooltipComponent, isClassActionFrameComponent, isClassHeaderComponent, isClassSetFilterComponent, CREATION_ONLY_OPTION_KEYS, createGrid } from '@agility-workbench/grid';
2
2
  export * from '@agility-workbench/grid';
3
3
  import * as i0 from '@angular/core';
4
- import { reflectComponentType, createComponent, input, output, inject, ElementRef, NgZone, Injector, ApplicationRef, EnvironmentInjector, afterNextRender, untracked, effect, ChangeDetectionStrategy, Component } from '@angular/core';
4
+ import { reflectComponentType, createComponent, input, output, inject, ElementRef, NgZone, Injector, ApplicationRef, EnvironmentInjector, afterNextRender, isDevMode, untracked, isSignal, effect, ChangeDetectionStrategy, Component } from '@angular/core';
5
5
 
6
6
  /** True when `value` is a compiled Angular component class (vs a core class or plain function). */
7
7
  function isNgComponent(value) {
@@ -40,6 +40,7 @@ class NgAdapters {
40
40
  this.actionFrameCache = new WeakMap();
41
41
  this.editorCache = new WeakMap();
42
42
  this.setFilterComponentCache = new WeakMap();
43
+ this.headerComponentCache = new WeakMap();
43
44
  }
44
45
  /**
45
46
  * Create `component` with `hostElement` as its host, deliver params, attach it to the app for
@@ -225,6 +226,57 @@ class NgAdapters {
225
226
  }
226
227
  };
227
228
  }
229
+ // --- header components -----------------------------------------------------------------------
230
+ /**
231
+ * Adapt a `headerComponent` / `headerCellComponent`. Core class components and the core function
232
+ * form pass through; an Angular component is mounted into the header slot.
233
+ */
234
+ adaptHeaderComponent(comp) {
235
+ if (!comp)
236
+ return undefined;
237
+ if (typeof comp === "function" && isClassHeaderComponent(comp)) {
238
+ return comp;
239
+ }
240
+ if (!isNgComponent(comp))
241
+ return comp;
242
+ const cached = this.headerComponentCache.get(comp);
243
+ if (cached)
244
+ return cached;
245
+ const adapted = this.createHeaderComponentClass(comp);
246
+ this.headerComponentCache.set(comp, adapted);
247
+ return adapted;
248
+ }
249
+ createHeaderComponentClass(component) {
250
+ const adapters = this;
251
+ return class NgHeaderComponentAdapter {
252
+ constructor() {
253
+ this.el = document.createElement("div");
254
+ this.mounted = null;
255
+ }
256
+ init(params) {
257
+ // Same box the core gives its function form, so an Angular header lays out like a native one.
258
+ this.el.className = "pte-hcell-custom-root";
259
+ this.el.style.display = "flex";
260
+ this.el.style.alignItems = "center";
261
+ this.el.style.width = "100%";
262
+ this.el.style.height = "100%";
263
+ this.el.style.overflow = "hidden";
264
+ // One component instance per header cell; sort/filter refreshes re-deliver params (an
265
+ // awbRefresh returning false asks the grid to recreate it). Header rebuilds destroy it.
266
+ this.mounted = adapters.mount(component, params, this.el, "headerComponent");
267
+ }
268
+ getGui() {
269
+ return this.el;
270
+ }
271
+ refresh(params) {
272
+ return this.mounted?.refresh(params) ?? false;
273
+ }
274
+ destroy() {
275
+ this.mounted?.destroy();
276
+ this.mounted = null;
277
+ }
278
+ };
279
+ }
228
280
  // --- cell editors ----------------------------------------------------------------------------
229
281
  adaptCellEditor(editor) {
230
282
  if (editor == null)
@@ -345,6 +397,8 @@ class NgAdapters {
345
397
  headerTooltip: this.adaptHeaderTooltip(colDef.headerTooltip),
346
398
  actionFrameComponent: this.adaptActionFrame(colDef.actionFrameComponent),
347
399
  filterParams: this.adaptFilterParams(colDef.filterParams),
400
+ headerComponent: this.adaptHeaderComponent(colDef.headerComponent),
401
+ headerCellComponent: this.adaptHeaderComponent(colDef.headerCellComponent),
348
402
  children: colDef.children ? (this.adaptColumnDefs(colDef.children) ?? undefined) : undefined,
349
403
  };
350
404
  }
@@ -361,20 +415,37 @@ class NgAdapters {
361
415
  adaptDefaultColDef(defaultColDef) {
362
416
  if (defaultColDef == null)
363
417
  return undefined;
364
- const next = { ...defaultColDef };
365
- if ("cellRenderer" in defaultColDef)
366
- next.cellRenderer = this.adaptCellRenderer(defaultColDef.cellRenderer);
367
- if ("cellEditor" in defaultColDef)
368
- next.cellEditor = this.adaptCellEditor(defaultColDef.cellEditor);
369
- if ("tooltipComponent" in defaultColDef)
370
- next.tooltipComponent = this.adaptTooltip(defaultColDef.tooltipComponent);
371
- if ("headerTooltip" in defaultColDef)
372
- next.headerTooltip = this.adaptHeaderTooltip(defaultColDef.headerTooltip);
373
- if ("actionFrameComponent" in defaultColDef) {
374
- next.actionFrameComponent = this.adaptActionFrame(defaultColDef.actionFrameComponent);
418
+ return this.adaptPartial(defaultColDef);
419
+ }
420
+ /**
421
+ * Adapt `groupColumnDef` / `pivotResultColumnDef`, the partial defs the grid layers over its
422
+ * synthesized columns. Present-fields-only, like {@link adaptDefaultColDef}: the core layers these
423
+ * with object spread, where an explicit `undefined` would clobber the layer beneath.
424
+ */
425
+ adaptPartialColDef(def) {
426
+ if (def == null)
427
+ return undefined;
428
+ return this.adaptPartial(def);
429
+ }
430
+ adaptPartial(def) {
431
+ const next = { ...def };
432
+ if ("cellRenderer" in def)
433
+ next.cellRenderer = this.adaptCellRenderer(def.cellRenderer);
434
+ if ("cellEditor" in def)
435
+ next.cellEditor = this.adaptCellEditor(def.cellEditor);
436
+ if ("tooltipComponent" in def)
437
+ next.tooltipComponent = this.adaptTooltip(def.tooltipComponent);
438
+ if ("headerTooltip" in def)
439
+ next.headerTooltip = this.adaptHeaderTooltip(def.headerTooltip);
440
+ if ("actionFrameComponent" in def)
441
+ next.actionFrameComponent = this.adaptActionFrame(def.actionFrameComponent);
442
+ if ("filterParams" in def)
443
+ next.filterParams = this.adaptFilterParams(def.filterParams);
444
+ if ("headerComponent" in def)
445
+ next.headerComponent = this.adaptHeaderComponent(def.headerComponent);
446
+ if ("headerCellComponent" in def) {
447
+ next.headerCellComponent = this.adaptHeaderComponent(def.headerCellComponent);
375
448
  }
376
- if ("filterParams" in defaultColDef)
377
- next.filterParams = this.adaptFilterParams(defaultColDef.filterParams);
378
449
  return next;
379
450
  }
380
451
  }
@@ -404,6 +475,56 @@ function getActionFrameProps(params) {
404
475
  return { ...params, ...extraParams };
405
476
  }
406
477
 
478
+ /**
479
+ * Core creation-only options the Angular binding keeps live anyway: the value-returning hooks and
480
+ * `multiColumnMenu` are read through their input signals on every call. (The event callbacks are
481
+ * outputs, not inputs, so they never reach this list.) Everything else in core's
482
+ * {@link CREATION_ONLY_OPTION_KEYS} that `<awb-grid>` declares as an input is fixed once the grid
483
+ * exists.
484
+ */
485
+ const BRIDGED_INPUTS = new Set([
486
+ "onBeforeCellCommit",
487
+ "fillOperation",
488
+ "multiColumnMenu",
489
+ ]);
490
+ /** Core creation-only option names minus the inputs the binding bridges (derived from core). */
491
+ const CREATION_ONLY_INPUT_CANDIDATES = CREATION_ONLY_OPTION_KEYS.filter((key) => !BRIDGED_INPUTS.has(key));
492
+ /** The `treeData` members the binding reconciles live (via setTreeDataKeyboardNavigationOptions). */
493
+ const LIVE_TREE_DATA_KEYS = ["keyboardNavigationMode", "enableKeyboardNavigationModeSwitch"];
494
+ const UNCOMPARABLE = Symbol("uncomparable");
495
+ /**
496
+ * A structural fingerprint of an input value, so a template literal object or a function re-created
497
+ * with the same contents does not count as a change. Functions (and component classes) compare by
498
+ * source text; `treeData` ignores the members that are live. Values that cannot be serialized
499
+ * (cycles) compare by identity.
500
+ */
501
+ function inputFingerprint(key, value) {
502
+ let subject = value;
503
+ if (key === "treeData" && value != null && typeof value === "object") {
504
+ const rest = { ...value };
505
+ for (const live of LIVE_TREE_DATA_KEYS)
506
+ delete rest[live];
507
+ subject = rest;
508
+ }
509
+ try {
510
+ return JSON.stringify(subject, (_k, v) => {
511
+ if (typeof v === "function")
512
+ return `ƒ ${String(v)}`;
513
+ if (v === undefined)
514
+ return "∅undefined";
515
+ return v;
516
+ }) ?? "∅undefined";
517
+ }
518
+ catch {
519
+ return UNCOMPARABLE;
520
+ }
521
+ }
522
+ function creationOnlyWarning(key) {
523
+ return (`[agility-workbench] <awb-grid> input "${key}" changed after the grid was created. It is read ` +
524
+ `only at creation, so the change is ignored. Re-create the grid to apply it (for example, ` +
525
+ `render it under an @if or a keyed @for so Angular destroys and creates a new <awb-grid>).`);
526
+ }
527
+
407
528
  function setIfDefined(options, key, value) {
408
529
  if (value != null)
409
530
  options[key] = value;
@@ -430,7 +551,6 @@ function getGridOptions(grid, adapters) {
430
551
  setIfDefined(options, "maxColumnWidth", grid.maxColumnWidth());
431
552
  setIfDefined(options, "pivotMode", grid.pivotMode());
432
553
  setIfDefined(options, "pivotColumns", grid.pivotColumns());
433
- setIfDefined(options, "pivotResultColumnDef", grid.pivotResultColumnDef());
434
554
  setIfDefined(options, "maxPivotColumns", grid.maxPivotColumns());
435
555
  setIfDefined(options, "pivotColumnMoveMode", grid.pivotColumnMoveMode());
436
556
  setIfDefined(options, "autosizeColumnsOnDataChange", grid.autosizeColumnsOnDataChange());
@@ -481,7 +601,6 @@ function getGridOptions(grid, adapters) {
481
601
  setIfDefined(options, "commitOnBlur", grid.commitOnBlur());
482
602
  setIfDefined(options, "reevaluateOnEdit", grid.reevaluateOnEdit());
483
603
  setIfDefined(options, "groupDisplayType", grid.groupDisplayType());
484
- setIfDefined(options, "groupColumnDef", grid.groupColumnDef());
485
604
  setIfDefined(options, "groupDefaultExpanded", grid.groupDefaultExpanded());
486
605
  setIfDefined(options, "groupSortMode", grid.groupSortMode());
487
606
  setIfDefined(options, "treeData", grid.treeData());
@@ -514,6 +633,14 @@ function getGridOptions(grid, adapters) {
514
633
  const defaultColDef = grid.defaultColDef();
515
634
  if (defaultColDef != null)
516
635
  options.defaultColDef = adapters.adaptDefaultColDef(defaultColDef);
636
+ // The partial defs the grid layers over its synthesized columns carry component fields too.
637
+ const groupColumnDef = grid.groupColumnDef();
638
+ if (groupColumnDef != null)
639
+ options.groupColumnDef = adapters.adaptPartialColDef(groupColumnDef);
640
+ const pivotResultColumnDef = grid.pivotResultColumnDef();
641
+ if (pivotResultColumnDef != null) {
642
+ options.pivotResultColumnDef = adapters.adaptPartialColDef(pivotResultColumnDef);
643
+ }
517
644
  // Forward only the boolean intent to core: false disables the menu (native menu shows);
518
645
  // everything else (true / omitted / a function) leaves core at its "show menu" default and lets
519
646
  // the body-menu adapter apply the function arm (so TemplateRef slots are handled). This avoids
@@ -894,6 +1021,8 @@ class AwbGrid {
894
1021
  return created;
895
1022
  });
896
1023
  this.instance = instance;
1024
+ if (isDevMode())
1025
+ this.startCreationOnlyWarnings();
897
1026
  this.startSyncEffects(instance);
898
1027
  this.gridReady.emit(instance.api);
899
1028
  }
@@ -1080,6 +1209,39 @@ class AwbGrid {
1080
1209
  return () => api.updateGridOptions({ theme, icons: { ...theme?.getIcons(), ...icons } });
1081
1210
  });
1082
1211
  }
1212
+ /**
1213
+ * Development only. Creation-only inputs are read once, by createGrid; a later change to one is
1214
+ * ignored. Instead of letting that change vanish silently, warn once per input (per grid
1215
+ * instance), comparing against the value the grid was created with. The input list is core's
1216
+ * creation-only key list, intersected with the inputs this component declares.
1217
+ */
1218
+ startCreationOnlyWarnings() {
1219
+ const self = this;
1220
+ const inputs = CREATION_ONLY_INPUT_CANDIDATES.flatMap((key) => {
1221
+ const candidate = self[key];
1222
+ return isSignal(candidate) ? [{ key, read: candidate }] : [];
1223
+ });
1224
+ const created = new Map(inputs.map(({ key, read }) => {
1225
+ const value = untracked(read);
1226
+ return [key, { value, fingerprint: inputFingerprint(key, value) }];
1227
+ }));
1228
+ const warned = new Set();
1229
+ effect(() => {
1230
+ for (const { key, read } of inputs) {
1231
+ const value = read();
1232
+ if (warned.has(key))
1233
+ continue;
1234
+ const initial = created.get(key);
1235
+ if (Object.is(value, initial.value))
1236
+ continue;
1237
+ const fingerprint = inputFingerprint(key, value);
1238
+ if (fingerprint !== UNCOMPARABLE && fingerprint === initial.fingerprint)
1239
+ continue;
1240
+ warned.add(key);
1241
+ console.warn(creationOnlyWarning(key));
1242
+ }
1243
+ }, { injector: this.injector });
1244
+ }
1083
1245
  /**
1084
1246
  * Effect helper: `read` runs tracked (signal reads register dependencies) and returns the core
1085
1247
  * call to make, or null to skip; the call itself runs outside the Angular zone so core-side
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _agility_workbench_grid from '@agility-workbench/grid';
2
- import { ColDef, CellRenderer, CellEditor, TooltipComponent, ActionFrameComponent, FilterParams, SetFilterValueComponent, SetFilterSpecialValueComponent, SetFilterGroupComponent, NON_DEFAULTABLE_COLDEF_KEYS, RowPresentationParams, RowPresentation, RowTooltipPresentation, ActionFrameComponentParams, ICellEditorParams, CellRendererParams, SetFilterGroupComponentParams, SetFilterSpecialValueComponentParams, SetFilterValueComponentParams, TooltipComponentParams, MenuItem, ColumnMenuContext, BodyMenuContext, Column, IGridAPI, GridEventCellClickedParams, GridEventRowClickedParams, CellValueChangedParams, GridEventSelectionChangedParams, SortChangedParams, GridEventFilterChangedParams, GridEventQuickFilterFindChangedParams, GridEventHistoryChangedParams } from '@agility-workbench/grid';
2
+ import { ColDef, CellRenderer, CellEditor, TooltipComponent, ActionFrameComponent, FilterParams, SetFilterValueComponent, SetFilterSpecialValueComponent, SetFilterGroupComponent, HeaderComponent, NON_DEFAULTABLE_COLDEF_KEYS, RowPresentationParams, RowPresentation, RowTooltipPresentation, ActionFrameComponentParams, ICellEditorParams, CellRendererParams, HeaderComponentParams, SetFilterGroupComponentParams, SetFilterSpecialValueComponentParams, SetFilterValueComponentParams, TooltipComponentParams, MenuItem, ColumnMenuContext, BodyMenuContext, Column, IGridAPI, GridEventCellClickedParams, GridEventRowClickedParams, CellValueChangedParams, GridEventSelectionChangedParams, SortChangedParams, GridEventFilterChangedParams, GridEventQuickFilterFindChangedParams, GridEventHistoryChangedParams } from '@agility-workbench/grid';
3
3
  export * from '@agility-workbench/grid';
4
4
  import * as _angular_core from '@angular/core';
5
5
  import { Type, TemplateRef, OnDestroy } from '@angular/core';
@@ -25,6 +25,15 @@ interface IActionFrameNgComp<P extends ActionFrameComponentParams = ActionFrameC
25
25
  awbInit(params: P): void;
26
26
  awbRefresh?(params: P): boolean;
27
27
  }
28
+ /**
29
+ * Same contract as {@link ICellRendererNgComp}, for `headerComponent` / `headerCellComponent`.
30
+ * `awbRefresh` runs when the header's sort/filter state changes; without it the params are simply
31
+ * re-delivered.
32
+ */
33
+ interface IHeaderNgComp<P extends HeaderComponentParams = HeaderComponentParams> {
34
+ awbInit(params: P): void;
35
+ awbRefresh?(params: P): boolean;
36
+ }
28
37
  /** Angular component contract for a regular set-filter value label. */
29
38
  interface ISetFilterValueNgComp<P extends SetFilterValueComponentParams = SetFilterValueComponentParams> {
30
39
  awbInit(params: P): void;
@@ -57,7 +66,7 @@ interface ICellEditorNgComp<P extends ICellEditorParams = ICellEditorParams> {
57
66
  /** Return true to abort opening the editor. */
58
67
  isCancelBeforeStart?(): boolean;
59
68
  }
60
- /** An Angular component class usable as a cell renderer / tooltip / ActionFrame / editor. */
69
+ /** An Angular component class usable as a cell renderer / tooltip / ActionFrame / editor / header. */
61
70
  type NgComponent = Type<unknown>;
62
71
  type NgFilterParams = Omit<FilterParams, "valueComponent" | "selectAllComponent" | "blanksComponent" | "groupComponent"> & {
63
72
  valueComponent?: SetFilterValueComponent | NgComponent;
@@ -74,17 +83,20 @@ type NgRowPresentation = Omit<RowPresentation, "tooltip"> & {
74
83
  type NgGetRowPresentation = (params: RowPresentationParams) => NgRowPresentation | null | undefined;
75
84
  /**
76
85
  * Angular-aware column definition: identical to the core {@link ColDef}, but every component slot
77
- * (cellRenderer, cellEditor, tooltipComponent, headerTooltip, actionFrameComponent) may also be an
86
+ * (cellRenderer, cellEditor, tooltipComponent, headerTooltip, actionFrameComponent, headerComponent,
87
+ * headerCellComponent, and the set-filter components in filterParams) may also be an
78
88
  * Angular component class. Angular components are wrapped in core adapter classes; core renderer
79
89
  * classes and string aliases pass through unchanged.
80
90
  */
81
- type NgColDef = Omit<ColDef, "cellRenderer" | "cellEditor" | "children" | "tooltipComponent" | "headerTooltip" | "actionFrameComponent" | "filterParams"> & {
91
+ type NgColDef = Omit<ColDef, "cellRenderer" | "cellEditor" | "children" | "tooltipComponent" | "headerTooltip" | "actionFrameComponent" | "filterParams" | "headerComponent" | "headerCellComponent"> & {
82
92
  cellRenderer?: CellRenderer | NgComponent;
83
93
  cellEditor?: CellEditor | NgComponent;
84
94
  tooltipComponent?: TooltipComponent | NgComponent;
85
95
  headerTooltip?: string | TooltipComponent | NgComponent;
86
96
  actionFrameComponent?: ActionFrameComponent | NgComponent;
87
97
  filterParams?: NgFilterParams;
98
+ headerComponent?: HeaderComponent | NgComponent;
99
+ headerCellComponent?: HeaderComponent | NgComponent;
88
100
  children?: NgColDef[];
89
101
  };
90
102
  /**
@@ -93,6 +105,12 @@ type NgColDef = Omit<ColDef, "cellRenderer" | "cellEditor" | "children" | "toolt
93
105
  * `DefaultColDef`, but its component fields may be Angular components.
94
106
  */
95
107
  type NgDefaultColDef = Omit<NgColDef, (typeof NON_DEFAULTABLE_COLDEF_KEYS)[number]>;
108
+ /**
109
+ * Angular-aware shape of the partial column defs the grid layers over a synthesized column
110
+ * (`groupColumnDef`, `pivotResultColumnDef`): a `Partial<NgColDef>`, so component fields may be
111
+ * Angular components.
112
+ */
113
+ type NgPartialColDef = Partial<Omit<NgColDef, "children">>;
96
114
 
97
115
  /**
98
116
  * A menu-item slot in the Angular wrapper: a plain string, a ready-made element, or an
@@ -128,7 +146,7 @@ declare class AwbGrid implements OnDestroy {
128
146
  readonly maxColumnWidth: _angular_core.InputSignal<number | undefined>;
129
147
  readonly pivotMode: _angular_core.InputSignal<boolean | undefined>;
130
148
  readonly pivotColumns: _angular_core.InputSignal<string[] | undefined>;
131
- readonly pivotResultColumnDef: _angular_core.InputSignal<Partial<ColDef> | undefined>;
149
+ readonly pivotResultColumnDef: _angular_core.InputSignal<Partial<Omit<NgColDef, "children">> | undefined>;
132
150
  readonly maxPivotColumns: _angular_core.InputSignal<number | undefined>;
133
151
  readonly pivotColumnMoveMode: _angular_core.InputSignal<"measures" | "free" | undefined>;
134
152
  readonly autosizeColumnsOnDataChange: _angular_core.InputSignal<boolean | undefined>;
@@ -178,7 +196,7 @@ declare class AwbGrid implements OnDestroy {
178
196
  readonly quickFilter: _angular_core.InputSignal<boolean | _agility_workbench_grid.QuickFilterOptions | undefined>;
179
197
  readonly filterDebounceMs: _angular_core.InputSignal<number | undefined>;
180
198
  readonly groupDisplayType: _angular_core.InputSignal<_agility_workbench_grid.GroupDisplayType | undefined>;
181
- readonly groupColumnDef: _angular_core.InputSignal<Partial<ColDef> | undefined>;
199
+ readonly groupColumnDef: _angular_core.InputSignal<Partial<Omit<NgColDef, "children">> | undefined>;
182
200
  readonly groupDefaultExpanded: _angular_core.InputSignal<number | undefined>;
183
201
  readonly groupSortMode: _angular_core.InputSignal<_agility_workbench_grid.GroupSortMode | undefined>;
184
202
  readonly groupRowsSelectable: _angular_core.InputSignal<boolean | undefined>;
@@ -280,6 +298,13 @@ declare class AwbGrid implements OnDestroy {
280
298
  * rebuild UI on re-application skip their first run via `keyedEffect`.
281
299
  */
282
300
  private startSyncEffects;
301
+ /**
302
+ * Development only. Creation-only inputs are read once, by createGrid; a later change to one is
303
+ * ignored. Instead of letting that change vanish silently, warn once per input (per grid
304
+ * instance), comparing against the value the grid was created with. The input list is core's
305
+ * creation-only key list, intersected with the inputs this component declares.
306
+ */
307
+ private startCreationOnlyWarnings;
283
308
  /**
284
309
  * Effect helper: `read` runs tracked (signal reads register dependencies) and returns the core
285
310
  * call to make, or null to skip; the call itself runs outside the Angular zone so core-side
@@ -299,4 +324,4 @@ declare class AwbGrid implements OnDestroy {
299
324
  }
300
325
 
301
326
  export { AwbGrid };
302
- export type { IActionFrameNgComp, ICellEditorNgComp, ICellRendererNgComp, ISetFilterGroupNgComp, ISetFilterSpecialValueNgComp, ISetFilterValueNgComp, ITooltipNgComp, NgColDef, NgComponent, NgDefaultColDef, NgFilterParams, NgGetRowPresentation, NgMenuItem, NgMenuSlot, NgRowPresentation, NgRowTooltipPresentation };
327
+ export type { IActionFrameNgComp, ICellEditorNgComp, ICellRendererNgComp, IHeaderNgComp, ISetFilterGroupNgComp, ISetFilterSpecialValueNgComp, ISetFilterValueNgComp, ITooltipNgComp, NgColDef, NgComponent, NgDefaultColDef, NgFilterParams, NgGetRowPresentation, NgMenuItem, NgMenuSlot, NgPartialColDef, NgRowPresentation, NgRowTooltipPresentation };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agility-workbench/angular-grid",
3
- "version": "1.10.0",
3
+ "version": "1.11.0",
4
4
  "description": "Angular bindings for @agility-workbench/grid — a high-performance data grid. Supports Angular 20.3 through 22.",
5
5
  "license": "MIT",
6
6
  "author": "Himanshu M",
@@ -33,7 +33,7 @@
33
33
  "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
34
34
  },
35
35
  "dependencies": {
36
- "@agility-workbench/grid": "^1.10.0",
36
+ "@agility-workbench/grid": "^1.11.0",
37
37
  "tslib": "^2.3.0"
38
38
  },
39
39
  "peerDependencies": {