@toolbox-web/grid-angular 2.2.0 → 2.3.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,18 +77,17 @@ export class MyGridComponent {
77
77
 
78
78
  ## Enabling Features
79
79
 
80
- `<tbw-grid>` supports three patterns for turning on plugins. Pick whichever fits the
80
+ `<tbw-grid>` supports two patterns for turning on plugins. Pick whichever fits the
81
81
  component — they can be mixed.
82
82
 
83
- | Pattern | Best for | v2 status |
84
- | --------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
85
- | `gridConfig.features` (object literal) | Configuration-driven apps that prefer a single setup object | ✅ Unchanged — fully supported |
86
- | **Per-feature directive** (e.g. `GridFilteringDirective`) | Template-driven apps that want signal inputs/outputs **and** the smallest bundle | ✅ **Recommended** — the future-proof path |
87
- | Inputs/outputs on `Grid` (e.g. `[filtering]`) | v1.x apps already on this style | ⚠️ **Deprecated** — bindings remain for v1.x compatibility but will be removed in v2.0 |
83
+ | Pattern | Best for |
84
+ | --------------------------------------------------------- | -------------------------------------------------------------------------------- |
85
+ | `gridConfig.features` (object literal) | Configuration-driven apps that prefer a single setup object |
86
+ | **Per-feature directive** (e.g. `GridFilteringDirective`) | Template-driven apps that want signal inputs/outputs **and** the smallest bundle |
88
87
 
89
- > Apps that only use `gridConfig` are **not affected** by the v2 cleanup — only consumers
90
- > binding feature inputs directly on `<tbw-grid>` need to add the matching per-feature
91
- > directive to their component's `imports` before v2.
88
+ > **Upgrading from v2?** The per-feature inputs/outputs that used to live on the central
89
+ > `Grid` directive were removed in v3. The migration is a one-line `imports` addition per
90
+ > feature with zero template changes.
92
91
 
93
92
  ### Recommended: Per-Feature Directives
94
93
 
@@ -126,34 +125,24 @@ import { GridMultiSortDirective } from '@toolbox-web/grid-angular/features/multi
126
125
  - **Compile-time safety** — Angular errors with `Can't bind to 'filtering' since it isn't
127
126
  a known property of 'tbw-grid'` if you forget the directive (stronger than React/Vue,
128
127
  which silently drop unknown props, and stronger than the runtime guard on the WC core).
129
- - **Same bindings, same demos** — the directive's selector matches the existing
130
- attributes (`tbw-grid[filtering], tbw-grid[filterChange]`), so migrating from the
131
- legacy style is a one-line `imports` addition per feature with **zero template
132
- changes**.
133
-
134
- ### Legacy: Inputs/Outputs on `Grid` (deprecated)
135
-
136
- The v1.x style — declaring `[filtering]`, `(filterChange)`, etc. directly on the
137
- `Grid` directive without importing a per-feature directive — still works for the entire
138
- v1.x line and is mediated by a per-element claims registry so the two styles can coexist
139
- on the same grid without duplicate plugins or double-emitted events. The bindings are
140
- marked `@deprecated` in JSDoc; v2.0 will remove them, at which point a one-line directive
141
- import per feature is the migration.
128
+ - **Same bindings, same demos** — the directive's selector matches the plain
129
+ attributes (`tbw-grid[filtering], tbw-grid[filterChange]`), so the template markup is
130
+ identical no matter which pattern you came from.
142
131
 
143
132
  ### How the side-effect import works
144
133
 
145
134
  1. **Import the feature** — A side-effect import registers the feature factory with the
146
135
  core grid (`@toolbox-web/grid/features/<name>`).
147
- 2. **Bind the input** — The per-feature directive (or, in legacy code, the input on
148
- `Grid`) instantiates the plugin with the input value.
136
+ 2. **Bind the input** — The per-feature directive instantiates the plugin with the input
137
+ value.
149
138
 
150
139
  ```typescript
151
- // 1. Side-effect import — required for either pattern
140
+ // 1. Side-effect import
152
141
  import '@toolbox-web/grid-angular/features/selection';
153
142
  import '@toolbox-web/grid-angular/features/multi-sort';
154
143
  import '@toolbox-web/grid-angular/features/filtering';
155
144
 
156
- // 2a. Recommended — per-feature directives in `imports`
145
+ // 2. Per-feature directives in `imports`
157
146
  import { GridSelectionDirective } from '@toolbox-web/grid-angular/features/selection';
158
147
  import { GridMultiSortDirective } from '@toolbox-web/grid-angular/features/multi-sort';
159
148
  import { GridFilteringDirective } from '@toolbox-web/grid-angular/features/filtering';
@@ -170,20 +159,6 @@ import { GridFilteringDirective } from '@toolbox-web/grid-angular/features/filte
170
159
  </tbw-grid>
171
160
  `,
172
161
  })
173
-
174
- // 2b. Legacy / deprecated — same bindings on Grid alone (works in v1.x)
175
- @Component({
176
- imports: [Grid],
177
- template: `
178
- <tbw-grid
179
- [rows]="rows"
180
- [selection]="'range'"
181
- [multiSort]="true"
182
- [filtering]="true"
183
- style="height: 400px; display: block;">
184
- </tbw-grid>
185
- `,
186
- })
187
162
  ```
188
163
 
189
164
  ### Why Side-Effect Imports?
@@ -196,9 +171,7 @@ import { GridFilteringDirective } from '@toolbox-web/grid-angular/features/filte
196
171
  ### Available Features
197
172
 
198
173
  Import the **directive** from `@toolbox-web/grid-angular/features/<name>` and add it
199
- alongside `Grid` in your component's `imports` (recommended). The same `[input]` /
200
- `(output)` bindings on the `Grid` directive itself are still accepted in v1.x but are
201
- `@deprecated`.
174
+ alongside `Grid` in your component's `imports`.
202
175
 
203
176
  | Per-Feature Directive (recommended) | Input | Example |
204
177
  | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | -------------------------------------------------------------------------- |
@@ -489,7 +462,8 @@ export class MyGridComponent {
489
462
  Add custom sidebar panels with `GridToolPanel`:
490
463
 
491
464
  ```typescript
492
- import { Grid, GridToolPanel } from '@toolbox-web/grid-angular';
465
+ import { Grid } from '@toolbox-web/grid-angular';
466
+ import { GridToolPanel } from '@toolbox-web/grid-angular/features/shell';
493
467
 
494
468
  @Component({
495
469
  imports: [Grid, GridToolPanel, QuickFiltersPanelComponent],
@@ -1157,11 +1131,10 @@ export class TextFilterComponent extends BaseFilterPanel {
1157
1131
 
1158
1132
  ### Grid Directive Inputs
1159
1133
 
1160
- | Input | Type | Description |
1161
- | --------------- | ------------------ | ------------------------------------------------- |
1162
- | `gridConfig` | `GridConfig<TRow>` | Grid config with optional component class support |
1163
- | `angularConfig` | `GridConfig<TRow>` | **Deprecated** - use `gridConfig` instead |
1164
- | `customStyles` | `string` | Custom CSS styles to inject into the grid |
1134
+ | Input | Type | Description |
1135
+ | -------------- | ------------------ | ------------------------------------------------- |
1136
+ | `gridConfig` | `GridConfig<TRow>` | Grid config with optional component class support |
1137
+ | `customStyles` | `string` | Custom CSS styles to inject into the grid |
1165
1138
 
1166
1139
  ### Grid Directive Outputs
1167
1140
 
@@ -1184,6 +1157,9 @@ export class TextFilterComponent extends BaseFilterPanel {
1184
1157
  | `rowMove` | `OutputEmitterRef<RowMoveDetail>` | Row moved (drag & drop) |
1185
1158
  | `groupToggle` | `OutputEmitterRef<GroupToggleDetail>` | Group expanded/collapsed |
1186
1159
  | `treeExpand` | `OutputEmitterRef<TreeExpandDetail>` | Tree node expanded/collapsed |
1160
+ | `treeLoadStart` | `OutputEmitterRef<TreeLoadStartDetail>` | Lazy child loading started |
1161
+ | `treeLoadEnd` | `OutputEmitterRef<TreeLoadEndDetail>` | Lazy child loading finished |
1162
+ | `treeLoadError` | `OutputEmitterRef<TreeLoadErrorDetail>` | Lazy child loading failed |
1187
1163
  | `detailExpand` | `OutputEmitterRef<DetailExpandDetail>` | Detail panel toggled |
1188
1164
  | `responsiveChange` | `OutputEmitterRef<ResponsiveChangeDetail>` | Responsive mode changed |
1189
1165
  | `copy` | `OutputEmitterRef<CopyDetail>` | Data copied to clipboard |
@@ -1223,12 +1199,6 @@ import type {
1223
1199
  CellRenderer,
1224
1200
  CellEditor,
1225
1201
  TypeDefault,
1226
- // Deprecated aliases
1227
- AngularGridConfig,
1228
- AngularColumnConfig,
1229
- AngularCellRenderer,
1230
- AngularCellEditor,
1231
- AngularTypeDefault,
1232
1202
  } from '@toolbox-web/grid-angular';
1233
1203
 
1234
1204
  // Reactive Forms types live with the editing feature
@@ -1191,7 +1191,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
1191
1191
  * @category Directive
1192
1192
  */
1193
1193
  /**
1194
- * Owns the binding(s) `[editing], [cellCommit], [cellCancel], [rowCommit], [changedRowsReset], [editOpen], [beforeEditClose], [editClose], [dirtyChange]` on `<tbw-grid>` for the matching feature plugin. See `GridFilteringDirective` for the full rationale.
1194
+ * Owns the binding(s) `[editing], [cellCommit], [cellCancel], [rowCommit], [changedRowsReset], [editOpen], [beforeEditClose], [editClose], [dirtyChange], [baselinesCaptured]` on `<tbw-grid>` for the matching feature plugin. See `GridFilteringDirective` for the full rationale.
1195
1195
  *
1196
1196
  * @category Directive
1197
1197
  */
@@ -1212,6 +1212,14 @@ class GridEditingDirective {
1212
1212
  editClose = output();
1213
1213
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1214
1214
  dirtyChange = output();
1215
+ /**
1216
+ * Fired after the render pipeline captures new dirty-tracking baseline
1217
+ * snapshots. `detail.count` is the **total** number of tracked baselines,
1218
+ * not just the newly captured ones.
1219
+ *
1220
+ * @since 2.3.0
1221
+ */
1222
+ baselinesCaptured = output();
1215
1223
  listeners = new Map();
1216
1224
  static EVENTS = [
1217
1225
  'cell-commit',
@@ -1222,6 +1230,7 @@ class GridEditingDirective {
1222
1230
  'before-edit-close',
1223
1231
  'edit-close',
1224
1232
  'dirty-change',
1233
+ 'baselines-captured',
1225
1234
  ];
1226
1235
  constructor() {
1227
1236
  const grid = this.elementRef.nativeElement;
@@ -1249,6 +1258,7 @@ class GridEditingDirective {
1249
1258
  wire('edit-close', this.editClose);
1250
1259
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1251
1260
  wire('dirty-change', this.dirtyChange);
1261
+ wire('baselines-captured', this.baselinesCaptured);
1252
1262
  }
1253
1263
  ngOnDestroy() {
1254
1264
  const grid = this.elementRef.nativeElement;
@@ -1260,15 +1270,15 @@ class GridEditingDirective {
1260
1270
  unclaimEvent(grid, ev);
1261
1271
  }
1262
1272
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridEditingDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1263
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: GridEditingDirective, isStandalone: true, selector: "tbw-grid[editing], tbw-grid[cellCommit], tbw-grid[cellCancel], tbw-grid[rowCommit], tbw-grid[changedRowsReset], tbw-grid[editOpen], tbw-grid[beforeEditClose], tbw-grid[editClose], tbw-grid[dirtyChange]", inputs: { editing: { classPropertyName: "editing", publicName: "editing", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellCommit: "cellCommit", cellCancel: "cellCancel", rowCommit: "rowCommit", changedRowsReset: "changedRowsReset", editOpen: "editOpen", beforeEditClose: "beforeEditClose", editClose: "editClose", dirtyChange: "dirtyChange" }, ngImport: i0 });
1273
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: GridEditingDirective, isStandalone: true, selector: "tbw-grid[editing], tbw-grid[cellCommit], tbw-grid[cellCancel], tbw-grid[rowCommit], tbw-grid[changedRowsReset], tbw-grid[editOpen], tbw-grid[beforeEditClose], tbw-grid[editClose], tbw-grid[dirtyChange], tbw-grid[baselinesCaptured]", inputs: { editing: { classPropertyName: "editing", publicName: "editing", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellCommit: "cellCommit", cellCancel: "cellCancel", rowCommit: "rowCommit", changedRowsReset: "changedRowsReset", editOpen: "editOpen", beforeEditClose: "beforeEditClose", editClose: "editClose", dirtyChange: "dirtyChange", baselinesCaptured: "baselinesCaptured" }, ngImport: i0 });
1264
1274
  }
1265
1275
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: GridEditingDirective, decorators: [{
1266
1276
  type: Directive,
1267
1277
  args: [{
1268
- selector: 'tbw-grid[editing], tbw-grid[cellCommit], tbw-grid[cellCancel], tbw-grid[rowCommit], tbw-grid[changedRowsReset], tbw-grid[editOpen], tbw-grid[beforeEditClose], tbw-grid[editClose], tbw-grid[dirtyChange]',
1278
+ selector: 'tbw-grid[editing], tbw-grid[cellCommit], tbw-grid[cellCancel], tbw-grid[rowCommit], tbw-grid[changedRowsReset], tbw-grid[editOpen], tbw-grid[beforeEditClose], tbw-grid[editClose], tbw-grid[dirtyChange], tbw-grid[baselinesCaptured]',
1269
1279
  standalone: true,
1270
1280
  }]
1271
- }], ctorParameters: () => [], propDecorators: { editing: [{ type: i0.Input, args: [{ isSignal: true, alias: "editing", required: false }] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], cellCancel: [{ type: i0.Output, args: ["cellCancel"] }], rowCommit: [{ type: i0.Output, args: ["rowCommit"] }], changedRowsReset: [{ type: i0.Output, args: ["changedRowsReset"] }], editOpen: [{ type: i0.Output, args: ["editOpen"] }], beforeEditClose: [{ type: i0.Output, args: ["beforeEditClose"] }], editClose: [{ type: i0.Output, args: ["editClose"] }], dirtyChange: [{ type: i0.Output, args: ["dirtyChange"] }] } });
1281
+ }], ctorParameters: () => [], propDecorators: { editing: [{ type: i0.Input, args: [{ isSignal: true, alias: "editing", required: false }] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], cellCancel: [{ type: i0.Output, args: ["cellCancel"] }], rowCommit: [{ type: i0.Output, args: ["rowCommit"] }], changedRowsReset: [{ type: i0.Output, args: ["changedRowsReset"] }], editOpen: [{ type: i0.Output, args: ["editOpen"] }], beforeEditClose: [{ type: i0.Output, args: ["beforeEditClose"] }], editClose: [{ type: i0.Output, args: ["editClose"] }], dirtyChange: [{ type: i0.Output, args: ["dirtyChange"] }], baselinesCaptured: [{ type: i0.Output, args: ["baselinesCaptured"] }] } });
1272
1282
 
1273
1283
  /**
1274
1284
  * Base class for grid cell editors.