@toolbox-web/grid-angular 1.9.1 → 2.0.0-beta
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/fesm2022/toolbox-web-grid-angular-features-editing.mjs +2317 -4
- package/fesm2022/toolbox-web-grid-angular-features-editing.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-filtering.mjs +91 -2
- package/fesm2022/toolbox-web-grid-angular-features-filtering.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-master-detail.mjs +97 -4
- package/fesm2022/toolbox-web-grid-angular-features-master-detail.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-pinned-rows.mjs +1 -15
- package/fesm2022/toolbox-web-grid-angular-features-pinned-rows.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-responsive.mjs +109 -3
- package/fesm2022/toolbox-web-grid-angular-features-responsive.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-shell.mjs +452 -0
- package/fesm2022/toolbox-web-grid-angular-features-shell.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular.mjs +740 -4649
- package/fesm2022/toolbox-web-grid-angular.mjs.map +1 -1
- package/package.json +2 -6
- package/types/toolbox-web-grid-angular-features-editing.d.ts +1181 -4
- package/types/toolbox-web-grid-angular-features-editing.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-filtering.d.ts +102 -7
- package/types/toolbox-web-grid-angular-features-filtering.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-master-detail.d.ts +88 -4
- package/types/toolbox-web-grid-angular-features-master-detail.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-pinned-rows.d.ts +2 -7
- package/types/toolbox-web-grid-angular-features-pinned-rows.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-responsive.d.ts +109 -3
- package/types/toolbox-web-grid-angular-features-responsive.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular-features-shell.d.ts +229 -0
- package/types/toolbox-web-grid-angular-features-shell.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular.d.ts +483 -2929
- package/types/toolbox-web-grid-angular.d.ts.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-reorder-rows.mjs +0 -70
- package/fesm2022/toolbox-web-grid-angular-features-reorder-rows.mjs.map +0 -1
- package/types/toolbox-web-grid-angular-features-reorder-rows.d.ts +0 -25
- package/types/toolbox-web-grid-angular-features-reorder-rows.d.ts.map +0 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
export { _Augmentation as _EditingAugmentation } from '@toolbox-web/grid/features/editing';
|
|
2
2
|
import * as _angular_core from '@angular/core';
|
|
3
|
-
import { OnInit, OnDestroy } from '@angular/core';
|
|
3
|
+
import { OnInit, OnDestroy, ElementRef, TemplateRef } from '@angular/core';
|
|
4
4
|
import { CellCommitEvent, RowCommitEvent } from '@toolbox-web/grid-angular';
|
|
5
|
-
export { BaseGridEditor, BaseGridEditorCVA, BaseOverlayEditor, FormArrayContext, GridColumnEditor, GridEditorContext, GridFormArray, GridLazyForm, LazyFormFactory, OverlayPosition, RowFormChangeEvent, StructuralEditorContext, TbwEditor, getFormArrayContext, getLazyFormContext } from '@toolbox-web/grid-angular';
|
|
6
5
|
import { EditingConfig, CellCancelDetail, ChangedRowsResetDetail, EditOpenDetail, BeforeEditCloseDetail, EditCloseDetail, DirtyChangeDetail } from '@toolbox-web/grid/plugins/editing';
|
|
6
|
+
import { AbstractControl, ControlValueAccessor, FormGroup, FormArray } from '@angular/forms';
|
|
7
|
+
import { ColumnConfig } from '@toolbox-web/grid';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* 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.
|
|
@@ -12,7 +13,7 @@ import { EditingConfig, CellCancelDetail, ChangedRowsResetDetail, EditOpenDetail
|
|
|
12
13
|
*/
|
|
13
14
|
declare class GridEditingDirective implements OnInit, OnDestroy {
|
|
14
15
|
private readonly elementRef;
|
|
15
|
-
readonly editing: _angular_core.InputSignal<boolean |
|
|
16
|
+
readonly editing: _angular_core.InputSignal<boolean | "click" | EditingConfig | "dblclick" | "manual" | undefined>;
|
|
16
17
|
readonly cellCommit: _angular_core.OutputEmitterRef<CellCommitEvent<unknown, unknown>>;
|
|
17
18
|
readonly cellCancel: _angular_core.OutputEmitterRef<CellCancelDetail>;
|
|
18
19
|
readonly rowCommit: _angular_core.OutputEmitterRef<RowCommitEvent<unknown>>;
|
|
@@ -30,5 +31,1181 @@ declare class GridEditingDirective implements OnInit, OnDestroy {
|
|
|
30
31
|
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<GridEditingDirective, "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]", never, { "editing": { "alias": "editing"; "required": false; "isSignal": true; }; }, { "cellCommit": "cellCommit"; "cellCancel": "cellCancel"; "rowCommit": "rowCommit"; "changedRowsReset": "changedRowsReset"; "editOpen": "editOpen"; "beforeEditClose": "beforeEditClose"; "editClose": "editClose"; "dirtyChange": "dirtyChange"; }, never, never, true, never>;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Base class for grid cell editors.
|
|
36
|
+
*
|
|
37
|
+
* Provides common functionality for Angular cell editors:
|
|
38
|
+
* - Automatic value resolution from FormControl or value input
|
|
39
|
+
* - Common inputs (value, row, column, control)
|
|
40
|
+
* - Common outputs (commit, cancel)
|
|
41
|
+
* - Validation state helpers
|
|
42
|
+
*
|
|
43
|
+
* ## Usage
|
|
44
|
+
*
|
|
45
|
+
* ```typescript
|
|
46
|
+
* import { Component } from '@angular/core';
|
|
47
|
+
* import { BaseGridEditor } from '@toolbox-web/grid-angular/features/editing';
|
|
48
|
+
*
|
|
49
|
+
* @Component({
|
|
50
|
+
* selector: 'app-my-editor',
|
|
51
|
+
* template: \`
|
|
52
|
+
* <input
|
|
53
|
+
* [value]="currentValue()"
|
|
54
|
+
* [class.is-invalid]="isInvalid()"
|
|
55
|
+
* (input)="commitValue($event.target.value)"
|
|
56
|
+
* (keydown.escape)="cancelEdit()"
|
|
57
|
+
* />
|
|
58
|
+
* @if (hasErrors()) {
|
|
59
|
+
* <div class="error">{{ firstErrorMessage() }}</div>
|
|
60
|
+
* }
|
|
61
|
+
* \`
|
|
62
|
+
* })
|
|
63
|
+
* export class MyEditorComponent extends BaseGridEditor<MyRow, string> {
|
|
64
|
+
* // Override to customize error messages
|
|
65
|
+
* protected override getErrorMessage(errorKey: string): string {
|
|
66
|
+
* if (errorKey === 'required') return 'This field is required';
|
|
67
|
+
* if (errorKey === 'minlength') return 'Too short';
|
|
68
|
+
* return super.getErrorMessage(errorKey);
|
|
69
|
+
* }
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* ## Template Syntax
|
|
74
|
+
*
|
|
75
|
+
* When using the base class, you only need to pass the control:
|
|
76
|
+
*
|
|
77
|
+
* ```html
|
|
78
|
+
* <tbw-grid-column field="name">
|
|
79
|
+
* <app-my-editor *tbwEditor="let _; control as control" [control]="control" />
|
|
80
|
+
* </tbw-grid-column>
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* Or without FormArray binding (fallback to value):
|
|
84
|
+
*
|
|
85
|
+
* ```html
|
|
86
|
+
* <tbw-grid-column field="name">
|
|
87
|
+
* <app-my-editor *tbwEditor="let value" [value]="value" />
|
|
88
|
+
* </tbw-grid-column>
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @typeParam TRow - The row data type
|
|
92
|
+
* @typeParam TValue - The cell value type
|
|
93
|
+
*
|
|
94
|
+
* @since 0.5.0
|
|
95
|
+
*/
|
|
96
|
+
declare abstract class BaseGridEditor<TRow = unknown, TValue = unknown> {
|
|
97
|
+
protected readonly elementRef: ElementRef<any>;
|
|
98
|
+
private readonly _destroyRef;
|
|
99
|
+
/** Cleanup function for the edit-close listener */
|
|
100
|
+
private _editCloseCleanup;
|
|
101
|
+
/**
|
|
102
|
+
* The cell value. Used when FormControl is not available.
|
|
103
|
+
* When a FormControl is provided, value is derived from control.value instead.
|
|
104
|
+
*/
|
|
105
|
+
readonly value: _angular_core.InputSignal<TValue | undefined>;
|
|
106
|
+
/**
|
|
107
|
+
* The full row data object.
|
|
108
|
+
*/
|
|
109
|
+
readonly row: _angular_core.InputSignal<TRow | undefined>;
|
|
110
|
+
/**
|
|
111
|
+
* The column configuration.
|
|
112
|
+
*/
|
|
113
|
+
readonly column: _angular_core.InputSignal<ColumnConfig<TRow> | undefined>;
|
|
114
|
+
/**
|
|
115
|
+
* The FormControl for this cell, if the grid is bound to a FormArray.
|
|
116
|
+
* When provided, the editor uses control.value instead of the value input.
|
|
117
|
+
*/
|
|
118
|
+
readonly control: _angular_core.InputSignal<AbstractControl<any, any, any> | undefined>;
|
|
119
|
+
/**
|
|
120
|
+
* Emits when the user commits a new value.
|
|
121
|
+
* Emits `null` when a nullable field is cleared.
|
|
122
|
+
*/
|
|
123
|
+
readonly commit: _angular_core.OutputEmitterRef<TValue | null>;
|
|
124
|
+
/**
|
|
125
|
+
* Emits when the user cancels editing.
|
|
126
|
+
*/
|
|
127
|
+
readonly cancel: _angular_core.OutputEmitterRef<void>;
|
|
128
|
+
/**
|
|
129
|
+
* The current value, derived from FormControl if available, otherwise from value input.
|
|
130
|
+
* This is the recommended way to get the current value in your editor template.
|
|
131
|
+
*/
|
|
132
|
+
readonly currentValue: _angular_core.Signal<TValue | undefined>;
|
|
133
|
+
/**
|
|
134
|
+
* Whether the control is invalid (has validation errors).
|
|
135
|
+
* Returns false if no FormControl is available.
|
|
136
|
+
*/
|
|
137
|
+
readonly isInvalid: _angular_core.Signal<boolean>;
|
|
138
|
+
/**
|
|
139
|
+
* Whether the control is dirty (has been modified).
|
|
140
|
+
* Returns false if no FormControl is available.
|
|
141
|
+
*/
|
|
142
|
+
readonly isDirty: _angular_core.Signal<boolean>;
|
|
143
|
+
/**
|
|
144
|
+
* Whether the control has been touched.
|
|
145
|
+
* Returns false if no FormControl is available.
|
|
146
|
+
*/
|
|
147
|
+
readonly isTouched: _angular_core.Signal<boolean>;
|
|
148
|
+
/**
|
|
149
|
+
* Whether the control has any validation errors.
|
|
150
|
+
*/
|
|
151
|
+
readonly hasErrors: _angular_core.Signal<boolean>;
|
|
152
|
+
/**
|
|
153
|
+
* The first error message from the control's validation errors.
|
|
154
|
+
* Returns an empty string if no errors.
|
|
155
|
+
*/
|
|
156
|
+
readonly firstErrorMessage: _angular_core.Signal<string>;
|
|
157
|
+
/**
|
|
158
|
+
* All error messages from the control's validation errors.
|
|
159
|
+
*/
|
|
160
|
+
readonly allErrorMessages: _angular_core.Signal<string[]>;
|
|
161
|
+
constructor();
|
|
162
|
+
private _initEditCloseListener;
|
|
163
|
+
/**
|
|
164
|
+
* Whether this editor's cell is the currently focused cell.
|
|
165
|
+
*
|
|
166
|
+
* In row editing mode the grid creates editors for every editable cell
|
|
167
|
+
* in the row simultaneously. Use this to conditionally auto-focus inputs
|
|
168
|
+
* or open panels only in the active cell.
|
|
169
|
+
*
|
|
170
|
+
* Performs a synchronous DOM check — safe to call from `ngAfterViewInit`.
|
|
171
|
+
*/
|
|
172
|
+
protected isCellFocused(): boolean;
|
|
173
|
+
/**
|
|
174
|
+
* Called **before** the grid clears editing state and destroys editor DOM.
|
|
175
|
+
*
|
|
176
|
+
* At this point the commit callback is still active, so subclasses can
|
|
177
|
+
* call {@link commitValue} to flush any pending/deferred values.
|
|
178
|
+
*
|
|
179
|
+
* This fires only on the **commit** path (not on revert/cancel).
|
|
180
|
+
* Use {@link onEditClose} for cleanup that should happen on both paths.
|
|
181
|
+
*/
|
|
182
|
+
protected onBeforeEditClose(): void;
|
|
183
|
+
/**
|
|
184
|
+
* Called when the grid ends the editing session for this cell.
|
|
185
|
+
*
|
|
186
|
+
* Override to perform cleanup such as closing overlay panels, autocomplete
|
|
187
|
+
* dropdowns, or other floating UI that lives at `<body>` level and would
|
|
188
|
+
* otherwise persist after the editor DOM is removed.
|
|
189
|
+
*
|
|
190
|
+
* The listener is set up automatically via `afterNextRender` — no manual
|
|
191
|
+
* wiring required.
|
|
192
|
+
*/
|
|
193
|
+
protected onEditClose(): void;
|
|
194
|
+
/**
|
|
195
|
+
* Called by the grid adapter when the cell value changes externally
|
|
196
|
+
* (e.g., via `updateRow()` cascade or undo/redo).
|
|
197
|
+
*
|
|
198
|
+
* Override in subclasses to reset internal state (search text, selection
|
|
199
|
+
* flags, etc.) so the editor displays the updated value.
|
|
200
|
+
*
|
|
201
|
+
* This runs **synchronously** before the value input is updated, giving
|
|
202
|
+
* the editor a chance to clear stale state before the next change-detection
|
|
203
|
+
* pass re-reads the template.
|
|
204
|
+
*
|
|
205
|
+
* @param _newVal The new cell value being pushed from the grid
|
|
206
|
+
*/
|
|
207
|
+
onExternalValueChange(_newVal: TValue): void;
|
|
208
|
+
/**
|
|
209
|
+
* Commit a new value. Emits the commit output AND dispatches a DOM event.
|
|
210
|
+
* The DOM event enables the grid's auto-wiring to catch the commit.
|
|
211
|
+
* Call this when the user confirms their edit.
|
|
212
|
+
*/
|
|
213
|
+
commitValue(newValue: TValue | null): void;
|
|
214
|
+
/**
|
|
215
|
+
* Cancel editing. Emits the cancel output AND dispatches a DOM event.
|
|
216
|
+
* Call this when the user cancels (e.g., presses Escape).
|
|
217
|
+
*/
|
|
218
|
+
cancelEdit(): void;
|
|
219
|
+
/**
|
|
220
|
+
* Get a human-readable error message for a validation error.
|
|
221
|
+
* Override this method to customize error messages for your editor.
|
|
222
|
+
*
|
|
223
|
+
* @param errorKey - The validation error key (e.g., 'required', 'minlength')
|
|
224
|
+
* @param errorValue - The error value (e.g., { requiredLength: 5, actualLength: 3 })
|
|
225
|
+
* @returns A human-readable error message
|
|
226
|
+
*/
|
|
227
|
+
protected getErrorMessage(errorKey: string, errorValue?: unknown): string;
|
|
228
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseGridEditor<any, any>, never>;
|
|
229
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BaseGridEditor<any, any>, never, never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "row": { "alias": "row"; "required": false; "isSignal": true; }; "column": { "alias": "column"; "required": false; "isSignal": true; }; "control": { "alias": "control"; "required": false; "isSignal": true; }; }, { "commit": "commit"; "cancel": "cancel"; }, never, never, true, never>;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Base class for grid editors that also work as Angular form controls.
|
|
234
|
+
*
|
|
235
|
+
* Combines `BaseGridEditor` with `ControlValueAccessor` so the same component
|
|
236
|
+
* can be used inside a `<tbw-grid>` **and** in a standalone `<form>`.
|
|
237
|
+
*
|
|
238
|
+
* ## What it provides
|
|
239
|
+
*
|
|
240
|
+
* | Member | Purpose |
|
|
241
|
+
* |--------|---------|
|
|
242
|
+
* | `cvaValue` | Signal holding the value written by the form control |
|
|
243
|
+
* | `disabledState` | Signal tracking `setDisabledState` calls |
|
|
244
|
+
* | `displayValue` | Computed that prefers grid value (`currentValue`) and falls back to `cvaValue` |
|
|
245
|
+
* | `commitBoth(v)` | Commits via both CVA `onChange` and grid `commitValue` |
|
|
246
|
+
* | `writeValue` / `registerOn*` / `setDisabledState` | Full CVA implementation |
|
|
247
|
+
*
|
|
248
|
+
* ## Usage
|
|
249
|
+
*
|
|
250
|
+
* ```typescript
|
|
251
|
+
* import { Component, forwardRef } from '@angular/core';
|
|
252
|
+
* import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
253
|
+
* import { BaseGridEditorCVA } from '@toolbox-web/grid-angular/features/editing';
|
|
254
|
+
*
|
|
255
|
+
* @Component({
|
|
256
|
+
* selector: 'app-date-picker',
|
|
257
|
+
* providers: [{
|
|
258
|
+
* provide: NG_VALUE_ACCESSOR,
|
|
259
|
+
* useExisting: forwardRef(() => DatePickerComponent),
|
|
260
|
+
* multi: true,
|
|
261
|
+
* }],
|
|
262
|
+
* template: `
|
|
263
|
+
* <input
|
|
264
|
+
* type="date"
|
|
265
|
+
* [value]="displayValue()"
|
|
266
|
+
* [disabled]="disabledState()"
|
|
267
|
+
* (change)="commitBoth($event.target.value)"
|
|
268
|
+
* (keydown.escape)="cancelEdit()"
|
|
269
|
+
* />
|
|
270
|
+
* `
|
|
271
|
+
* })
|
|
272
|
+
* export class DatePickerComponent extends BaseGridEditorCVA<MyRow, string> {}
|
|
273
|
+
* ```
|
|
274
|
+
*
|
|
275
|
+
* > **Note:** Subclasses must still provide `NG_VALUE_ACCESSOR` themselves
|
|
276
|
+
* > because `forwardRef(() => ConcreteClass)` must reference the concrete
|
|
277
|
+
* > component — this is an Angular limitation.
|
|
278
|
+
*
|
|
279
|
+
* @typeParam TRow - The row data type
|
|
280
|
+
* @typeParam TValue - The cell/control value type
|
|
281
|
+
*
|
|
282
|
+
* @since 0.13.0
|
|
283
|
+
*/
|
|
284
|
+
declare abstract class BaseGridEditorCVA<TRow = unknown, TValue = unknown> extends BaseGridEditor<TRow, TValue> implements ControlValueAccessor {
|
|
285
|
+
/** Internal onChange callback registered by the form control. */
|
|
286
|
+
private _onChange;
|
|
287
|
+
/** Internal onTouched callback registered by the form control. */
|
|
288
|
+
private _onTouched;
|
|
289
|
+
/**
|
|
290
|
+
* Signal holding the value written by the form control via `writeValue()`.
|
|
291
|
+
* Updated when the form control pushes a new value (e.g. `patchValue`, `setValue`).
|
|
292
|
+
*/
|
|
293
|
+
protected readonly cvaValue: _angular_core.WritableSignal<TValue | null>;
|
|
294
|
+
/**
|
|
295
|
+
* Signal tracking the disabled state set by the form control.
|
|
296
|
+
* Updated when `setDisabledState()` is called by Angular's forms module.
|
|
297
|
+
*/
|
|
298
|
+
readonly disabledState: _angular_core.WritableSignal<boolean>;
|
|
299
|
+
/**
|
|
300
|
+
* Resolved display value.
|
|
301
|
+
*
|
|
302
|
+
* Prefers `currentValue()` (grid context — from `control.value` or `value` input)
|
|
303
|
+
* and falls back to `cvaValue()` (standalone form context — from `writeValue`).
|
|
304
|
+
*
|
|
305
|
+
* Use this in your template instead of reading `currentValue()` directly
|
|
306
|
+
* so the component works in both grid and standalone form contexts.
|
|
307
|
+
*/
|
|
308
|
+
readonly displayValue: _angular_core.Signal<TValue | null>;
|
|
309
|
+
/**
|
|
310
|
+
* Called by Angular forms when the form control value changes programmatically.
|
|
311
|
+
*/
|
|
312
|
+
writeValue(value: TValue | null): void;
|
|
313
|
+
/**
|
|
314
|
+
* Called by Angular forms to register a change callback.
|
|
315
|
+
*/
|
|
316
|
+
registerOnChange(fn: (value: TValue | null) => void): void;
|
|
317
|
+
/**
|
|
318
|
+
* Called by Angular forms to register a touched callback.
|
|
319
|
+
*/
|
|
320
|
+
registerOnTouched(fn: () => void): void;
|
|
321
|
+
/**
|
|
322
|
+
* Called by Angular forms to set the disabled state.
|
|
323
|
+
*/
|
|
324
|
+
setDisabledState(isDisabled: boolean): void;
|
|
325
|
+
/**
|
|
326
|
+
* Commit a value through both the CVA (form control) and the grid.
|
|
327
|
+
*
|
|
328
|
+
* - Calls the CVA `onChange` callback (updates the form control)
|
|
329
|
+
* - Marks the control as touched
|
|
330
|
+
* - Calls `commitValue()` (emits grid commit event + DOM `CustomEvent`)
|
|
331
|
+
*
|
|
332
|
+
* Use this instead of `commitValue()` when your editor doubles as a form control.
|
|
333
|
+
*
|
|
334
|
+
* @param value - The new value to commit
|
|
335
|
+
*/
|
|
336
|
+
protected commitBoth(value: TValue | null): void;
|
|
337
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseGridEditorCVA<any, any>, never>;
|
|
338
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BaseGridEditorCVA<any, any>, never, never, {}, {}, never, never, true, never>;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Position of the overlay panel relative to its anchor cell.
|
|
343
|
+
*
|
|
344
|
+
* - `'below'` — panel appears below the cell, left-aligned (default)
|
|
345
|
+
* - `'above'` — panel appears above the cell, left-aligned
|
|
346
|
+
* - `'below-right'` — panel appears below the cell, right-aligned
|
|
347
|
+
* - `'over-top-left'` — panel top-left corner aligns with cell top-left corner (opens downward)
|
|
348
|
+
* - `'over-bottom-left'` — panel bottom-left corner aligns with cell bottom-left corner (opens upward)
|
|
349
|
+
* @since 0.13.0
|
|
350
|
+
*/
|
|
351
|
+
type OverlayPosition = 'below' | 'above' | 'below-right' | 'over-top-left' | 'over-bottom-left';
|
|
352
|
+
/**
|
|
353
|
+
* Base class for grid editors that display a floating overlay panel.
|
|
354
|
+
*
|
|
355
|
+
* Provides infrastructure for:
|
|
356
|
+
* - **Overlay positioning** — CSS Anchor Positioning with JS fallback
|
|
357
|
+
* - **Focus gating** — in row editing mode, the panel only opens for the focused cell
|
|
358
|
+
* - **Click-outside detection** — closes the panel when clicking outside
|
|
359
|
+
* - **MutationObserver** — detects cell focus changes (row editing mode)
|
|
360
|
+
* - **Escape handling** — closes the panel and returns focus to the inline input
|
|
361
|
+
* - **Synthetic Tab dispatch** — advances grid focus after overlay close
|
|
362
|
+
* - **Automatic teardown** — removes the panel from `<body>` and cleans up listeners
|
|
363
|
+
* - **External focus registration** — auto-registers the panel via `grid.registerExternalFocusContainer()` so the grid keeps `data-has-focus` and editors stay open while the overlay has focus
|
|
364
|
+
*
|
|
365
|
+
* ## Usage
|
|
366
|
+
*
|
|
367
|
+
* ```typescript
|
|
368
|
+
* import { Component, viewChild, ElementRef, effect } from '@angular/core';
|
|
369
|
+
* import { BaseOverlayEditor } from '@toolbox-web/grid-angular/features/editing';
|
|
370
|
+
*
|
|
371
|
+
* @Component({
|
|
372
|
+
* selector: 'app-date-editor',
|
|
373
|
+
* template: `
|
|
374
|
+
* <input
|
|
375
|
+
* #inlineInput
|
|
376
|
+
* readonly
|
|
377
|
+
* [value]="currentValue()"
|
|
378
|
+
* (click)="onInlineClick()"
|
|
379
|
+
* (keydown)="onInlineKeydown($event)"
|
|
380
|
+
* />
|
|
381
|
+
* <div #panel class="tbw-overlay-panel" style="width: 280px;">
|
|
382
|
+
* <!-- your date picker UI here -->
|
|
383
|
+
* <div class="actions">
|
|
384
|
+
* <button (click)="selectAndClose(selectedDate)">OK</button>
|
|
385
|
+
* <button (click)="hideOverlay()">Cancel</button>
|
|
386
|
+
* </div>
|
|
387
|
+
* </div>
|
|
388
|
+
* `
|
|
389
|
+
* })
|
|
390
|
+
* export class DateEditorComponent extends BaseOverlayEditor<MyRow, string> {
|
|
391
|
+
* panelRef = viewChild.required<ElementRef<HTMLElement>>('panel');
|
|
392
|
+
* inputRef = viewChild.required<ElementRef<HTMLInputElement>>('inlineInput');
|
|
393
|
+
*
|
|
394
|
+
* protected override overlayPosition = 'below' as const;
|
|
395
|
+
*
|
|
396
|
+
* constructor() {
|
|
397
|
+
* super();
|
|
398
|
+
* effect(() => {
|
|
399
|
+
* const panel = this.panelRef().nativeElement;
|
|
400
|
+
* this.initOverlay(panel);
|
|
401
|
+
* if (this.isCellFocused()) this.showOverlay();
|
|
402
|
+
* });
|
|
403
|
+
* }
|
|
404
|
+
*
|
|
405
|
+
* protected getInlineInput(): HTMLInputElement | null {
|
|
406
|
+
* return this.inputRef()?.nativeElement ?? null;
|
|
407
|
+
* }
|
|
408
|
+
*
|
|
409
|
+
* protected onOverlayOutsideClick(): void {
|
|
410
|
+
* this.hideOverlay();
|
|
411
|
+
* }
|
|
412
|
+
*
|
|
413
|
+
* selectAndClose(date: string): void {
|
|
414
|
+
* this.commitValue(date);
|
|
415
|
+
* this.hideOverlay();
|
|
416
|
+
* }
|
|
417
|
+
* }
|
|
418
|
+
* ```
|
|
419
|
+
*
|
|
420
|
+
* @example
|
|
421
|
+
* ```typescript
|
|
422
|
+
* @Component({
|
|
423
|
+
* template: `
|
|
424
|
+
* <input #inlineInput readonly [value]="currentValue()"
|
|
425
|
+
* (click)="onInlineClick()" (keydown)="onInlineKeydown($event)" />
|
|
426
|
+
* <div #panel style="width: 280px">
|
|
427
|
+
* <!-- overlay content -->
|
|
428
|
+
* </div>
|
|
429
|
+
* `
|
|
430
|
+
* })
|
|
431
|
+
* export class MyEditor extends BaseOverlayEditor<MyRow, string> {
|
|
432
|
+
* panelRef = viewChild.required<ElementRef<HTMLElement>>('panel');
|
|
433
|
+
* inputRef = viewChild.required<ElementRef<HTMLInputElement>>('inlineInput');
|
|
434
|
+
*
|
|
435
|
+
* constructor() {
|
|
436
|
+
* super();
|
|
437
|
+
* effect(() => this.initOverlay(this.panelRef().nativeElement));
|
|
438
|
+
* }
|
|
439
|
+
*
|
|
440
|
+
* protected getInlineInput() { return this.inputRef()?.nativeElement ?? null; }
|
|
441
|
+
* protected onOverlayOutsideClick() { this.hideOverlay(); }
|
|
442
|
+
* }
|
|
443
|
+
* ```
|
|
444
|
+
*
|
|
445
|
+
* @typeParam TRow - The row data type
|
|
446
|
+
* @typeParam TValue - The cell value type
|
|
447
|
+
*
|
|
448
|
+
* @since 0.13.0
|
|
449
|
+
*/
|
|
450
|
+
declare abstract class BaseOverlayEditor<TRow = unknown, TValue = unknown> extends BaseGridEditor<TRow, TValue> {
|
|
451
|
+
private readonly _elementRef;
|
|
452
|
+
private readonly _overlayDestroyRef;
|
|
453
|
+
/**
|
|
454
|
+
* Position of the overlay panel relative to the anchor cell.
|
|
455
|
+
* Override in subclasses to change the default position.
|
|
456
|
+
*
|
|
457
|
+
* @default 'below'
|
|
458
|
+
*/
|
|
459
|
+
protected overlayPosition: OverlayPosition;
|
|
460
|
+
/** The overlay panel element (set via `initOverlay()`). */
|
|
461
|
+
private _panel;
|
|
462
|
+
/** Whether the overlay is currently visible. */
|
|
463
|
+
protected _isOpen: boolean;
|
|
464
|
+
/** Unique anchor ID for CSS Anchor Positioning. */
|
|
465
|
+
private _anchorId;
|
|
466
|
+
/** Whether the browser supports CSS Anchor Positioning. */
|
|
467
|
+
private _supportsAnchor;
|
|
468
|
+
/** AbortController for all overlay-related listeners. */
|
|
469
|
+
private _abortCtrl;
|
|
470
|
+
/** MutationObserver watching cell focus class changes. */
|
|
471
|
+
protected _focusObserver: MutationObserver | null;
|
|
472
|
+
constructor();
|
|
473
|
+
/**
|
|
474
|
+
* Initialise the overlay with the panel element.
|
|
475
|
+
*
|
|
476
|
+
* Call this in an `effect()` or `afterNextRender()` with your `viewChild` panel reference.
|
|
477
|
+
* The panel is moved to `<body>` and hidden until {@link showOverlay} is called.
|
|
478
|
+
*
|
|
479
|
+
* @param panel - The overlay panel DOM element
|
|
480
|
+
*/
|
|
481
|
+
protected initOverlay(panel: HTMLElement): void;
|
|
482
|
+
/**
|
|
483
|
+
* Show the overlay panel.
|
|
484
|
+
*
|
|
485
|
+
* If CSS Anchor Positioning is not supported, falls back to JS-based
|
|
486
|
+
* positioning using `getBoundingClientRect()`.
|
|
487
|
+
*/
|
|
488
|
+
protected showOverlay(): void;
|
|
489
|
+
/**
|
|
490
|
+
* Hide the overlay panel.
|
|
491
|
+
*
|
|
492
|
+
* @param suppressTabAdvance - When `true`, skip synthetic Tab dispatch
|
|
493
|
+
* (useful when hiding is triggered by an external focus change).
|
|
494
|
+
*/
|
|
495
|
+
protected hideOverlay(suppressTabAdvance?: boolean): void;
|
|
496
|
+
/**
|
|
497
|
+
* Close and immediately re-open the overlay.
|
|
498
|
+
* Useful after the panel content changes size and needs repositioning.
|
|
499
|
+
*/
|
|
500
|
+
protected reopenOverlay(): void;
|
|
501
|
+
/**
|
|
502
|
+
* Remove the overlay from the DOM and clean up all listeners.
|
|
503
|
+
*
|
|
504
|
+
* Called automatically on `DestroyRef.onDestroy`. Can also be called
|
|
505
|
+
* manually if the editor needs early cleanup.
|
|
506
|
+
*/
|
|
507
|
+
protected teardownOverlay(): void;
|
|
508
|
+
/**
|
|
509
|
+
* Override in `edit-close` handler to also hide the overlay.
|
|
510
|
+
* This is called automatically by `BaseGridEditor` when the grid
|
|
511
|
+
* ends the editing session.
|
|
512
|
+
*/
|
|
513
|
+
protected onEditClose(): void;
|
|
514
|
+
/**
|
|
515
|
+
* Keydown handler for the inline readonly input.
|
|
516
|
+
*
|
|
517
|
+
* - **Enter / Space / ArrowDown / F2** → open overlay
|
|
518
|
+
* - **Escape** → calls {@link handleEscape}
|
|
519
|
+
*
|
|
520
|
+
* Bind this to `(keydown)` on your inline input element.
|
|
521
|
+
*/
|
|
522
|
+
onInlineKeydown(event: KeyboardEvent): void;
|
|
523
|
+
/**
|
|
524
|
+
* Click handler for the inline input.
|
|
525
|
+
* Opens the overlay and calls {@link onOverlayOpened}.
|
|
526
|
+
*
|
|
527
|
+
* Bind this to `(click)` on your inline input element.
|
|
528
|
+
*/
|
|
529
|
+
onInlineClick(): void;
|
|
530
|
+
/**
|
|
531
|
+
* Handle Escape key press.
|
|
532
|
+
*
|
|
533
|
+
* If the overlay is open, closes it and returns focus to the inline input.
|
|
534
|
+
* If the overlay is already closed, cancels the edit entirely.
|
|
535
|
+
*/
|
|
536
|
+
protected handleEscape(event: Event): void;
|
|
537
|
+
/**
|
|
538
|
+
* Dispatch a synthetic Tab key event to advance grid focus.
|
|
539
|
+
*
|
|
540
|
+
* Call this after committing a value and closing the overlay so the
|
|
541
|
+
* grid moves focus to the next cell.
|
|
542
|
+
*
|
|
543
|
+
* @param backward - When `true`, dispatch Shift+Tab to move backwards.
|
|
544
|
+
*/
|
|
545
|
+
protected advanceGridFocus(backward?: boolean): void;
|
|
546
|
+
/**
|
|
547
|
+
* Return the inline input element, if any.
|
|
548
|
+
*
|
|
549
|
+
* Used by overlay infrastructure to return focus after hiding.
|
|
550
|
+
* Return `null` if there is no inline input.
|
|
551
|
+
*/
|
|
552
|
+
protected abstract getInlineInput(): HTMLInputElement | null;
|
|
553
|
+
/**
|
|
554
|
+
* Called when a pointerdown event occurs outside the overlay panel
|
|
555
|
+
* and outside the editor's host element.
|
|
556
|
+
*
|
|
557
|
+
* Typically, subclasses call `hideOverlay()` here.
|
|
558
|
+
*/
|
|
559
|
+
protected abstract onOverlayOutsideClick(): void;
|
|
560
|
+
/**
|
|
561
|
+
* Called after the overlay is shown.
|
|
562
|
+
*
|
|
563
|
+
* Override to focus an element inside the panel, start animations, etc.
|
|
564
|
+
* Default implementation is a no-op.
|
|
565
|
+
*/
|
|
566
|
+
protected onOverlayOpened(): void;
|
|
567
|
+
/** Find the parent cell element for this editor. */
|
|
568
|
+
private _getCell;
|
|
569
|
+
/** Find the parent `<tbw-grid>` element for this editor. */
|
|
570
|
+
private _getGridElement;
|
|
571
|
+
/**
|
|
572
|
+
* JS fallback positioning for browsers without CSS Anchor Positioning.
|
|
573
|
+
* Uses `getBoundingClientRect()` with viewport overflow detection.
|
|
574
|
+
*/
|
|
575
|
+
private _positionWithJs;
|
|
576
|
+
/**
|
|
577
|
+
* Document pointerdown handler for click-outside detection.
|
|
578
|
+
* Fires `onOverlayOutsideClick()` if the click is outside the panel
|
|
579
|
+
* and outside the editor's host element.
|
|
580
|
+
*/
|
|
581
|
+
private _onDocumentPointerDown;
|
|
582
|
+
/**
|
|
583
|
+
* Handle the grid's `tbw-scroll` CustomEvent while the overlay is open.
|
|
584
|
+
*
|
|
585
|
+
* When the viewport scrolls, the anchored overlay would otherwise float
|
|
586
|
+
* over content that no longer corresponds to the edited cell (or the
|
|
587
|
+
* cell may be virtualized out entirely). Treat scroll as a dismissal
|
|
588
|
+
* signal equivalent to clicking outside so subclasses' overlay-outside
|
|
589
|
+
* handler drives the appropriate commit/cancel path.
|
|
590
|
+
*/
|
|
591
|
+
private _onGridScroll;
|
|
592
|
+
/**
|
|
593
|
+
* Set up a MutationObserver on the parent cell to watch for
|
|
594
|
+
* `cell-focus` class changes. This handles row-editing mode where
|
|
595
|
+
* all editors exist simultaneously but only the focused cell's
|
|
596
|
+
* editor should have its overlay visible.
|
|
597
|
+
*
|
|
598
|
+
* A `justOpened` flash guard suppresses the observer from
|
|
599
|
+
* immediately closing the overlay when `beginBulkEdit()` moves
|
|
600
|
+
* focus to the first editable column. Without this guard,
|
|
601
|
+
* double-click triggers a "flash open then close" effect.
|
|
602
|
+
*/
|
|
603
|
+
protected _setupFocusObserver(): void;
|
|
604
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseOverlayEditor<any, any>, never>;
|
|
605
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BaseOverlayEditor<any, any>, never, never, {}, {}, never, never, true, never>;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* Context object passed to the cell editor template.
|
|
610
|
+
* Contains the cell value, row data, column configuration, and commit/cancel functions.
|
|
611
|
+
* @since 0.1.0
|
|
612
|
+
*/
|
|
613
|
+
interface GridEditorContext<TValue = unknown, TRow = unknown> {
|
|
614
|
+
/** The cell value for this column */
|
|
615
|
+
$implicit: TValue;
|
|
616
|
+
/** The cell value (explicit binding) */
|
|
617
|
+
value: TValue;
|
|
618
|
+
/** The full row data object */
|
|
619
|
+
row: TRow;
|
|
620
|
+
/** Field name being edited */
|
|
621
|
+
field: string;
|
|
622
|
+
/** The column configuration */
|
|
623
|
+
column: unknown;
|
|
624
|
+
/** Stable row identifier (from `getRowId`). Empty string if no `getRowId` is configured. */
|
|
625
|
+
rowId: string;
|
|
626
|
+
/**
|
|
627
|
+
* Callback function to commit the edited value.
|
|
628
|
+
* Use with Angular event binding: `(commit)="onCommit($event)"`
|
|
629
|
+
*/
|
|
630
|
+
onCommit: (value: TValue) => void;
|
|
631
|
+
/**
|
|
632
|
+
* Callback function to cancel editing.
|
|
633
|
+
* Use with Angular event binding: `(cancel)="onCancel()"`
|
|
634
|
+
*/
|
|
635
|
+
onCancel: () => void;
|
|
636
|
+
/**
|
|
637
|
+
* Update other fields in this row while the editor is open.
|
|
638
|
+
* Changes trigger `cell-change` events with source `'cascade'`.
|
|
639
|
+
*/
|
|
640
|
+
updateRow: (changes: Partial<TRow>) => void;
|
|
641
|
+
/**
|
|
642
|
+
* Register a callback to receive value updates when the cell is modified
|
|
643
|
+
* externally (e.g., via `updateRow()` from another cell's commit).
|
|
644
|
+
*
|
|
645
|
+
* The framework adapter auto-patches `value`/`$implicit` for template editors,
|
|
646
|
+
* but custom components may use this for additional reactivity.
|
|
647
|
+
*/
|
|
648
|
+
onValueChange?: (callback: (newValue: TValue) => void) => void;
|
|
649
|
+
/**
|
|
650
|
+
* The FormControl for this cell, if the grid is bound to a FormArray with FormGroups.
|
|
651
|
+
*
|
|
652
|
+
* This allows custom editors to bind directly to the control for validation display:
|
|
653
|
+
* ```html
|
|
654
|
+
* <input *tbwEditor="let value; control as ctrl"
|
|
655
|
+
* [formControl]="ctrl"
|
|
656
|
+
* [class.is-invalid]="ctrl?.invalid && ctrl?.touched" />
|
|
657
|
+
* ```
|
|
658
|
+
*
|
|
659
|
+
* Returns `undefined` if:
|
|
660
|
+
* - The grid is not bound to a FormArray
|
|
661
|
+
* - The FormArray doesn't contain FormGroups
|
|
662
|
+
* - The field doesn't exist in the FormGroup
|
|
663
|
+
*/
|
|
664
|
+
control?: AbstractControl;
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Gets the editor template registered for a given element.
|
|
668
|
+
* Used by AngularGridAdapter to retrieve templates at render time.
|
|
669
|
+
*/
|
|
670
|
+
declare function getEditorTemplate(element: HTMLElement): TemplateRef<GridEditorContext> | undefined;
|
|
671
|
+
/**
|
|
672
|
+
* Directive that captures an `<ng-template>` for use as a cell editor.
|
|
673
|
+
*
|
|
674
|
+
* This enables declarative Angular component usage with proper input bindings
|
|
675
|
+
* that satisfy Angular's AOT compiler.
|
|
676
|
+
*
|
|
677
|
+
* ## Usage
|
|
678
|
+
*
|
|
679
|
+
* ```html
|
|
680
|
+
* <tbw-grid-column field="status" editable>
|
|
681
|
+
* <tbw-grid-column-editor>
|
|
682
|
+
* <ng-template let-value let-row="row" let-onCommit="onCommit" let-onCancel="onCancel">
|
|
683
|
+
* <app-status-select
|
|
684
|
+
* [value]="value"
|
|
685
|
+
* [row]="row"
|
|
686
|
+
* (commit)="onCommit($event)"
|
|
687
|
+
* (cancel)="onCancel()"
|
|
688
|
+
* />
|
|
689
|
+
* </ng-template>
|
|
690
|
+
* </tbw-grid-column-editor>
|
|
691
|
+
* </tbw-grid-column>
|
|
692
|
+
* ```
|
|
693
|
+
*
|
|
694
|
+
* The template context provides:
|
|
695
|
+
* - `$implicit` / `value`: The cell value
|
|
696
|
+
* - `row`: The full row data object
|
|
697
|
+
* - `column`: The column configuration
|
|
698
|
+
* - `onCommit`: Callback function to commit the new value
|
|
699
|
+
* - `onCancel`: Callback function to cancel editing
|
|
700
|
+
*
|
|
701
|
+
* Import the directive in your component:
|
|
702
|
+
*
|
|
703
|
+
* ```typescript
|
|
704
|
+
* import { GridColumnEditor } from '@toolbox-web/grid-angular/features/editing';
|
|
705
|
+
*
|
|
706
|
+
* @Component({
|
|
707
|
+
* imports: [GridColumnEditor],
|
|
708
|
+
* // ...
|
|
709
|
+
* })
|
|
710
|
+
* ```
|
|
711
|
+
*
|
|
712
|
+
* @category Directive
|
|
713
|
+
*
|
|
714
|
+
* @since 0.1.0
|
|
715
|
+
*/
|
|
716
|
+
declare class GridColumnEditor {
|
|
717
|
+
private elementRef;
|
|
718
|
+
/**
|
|
719
|
+
* Query for the ng-template content child.
|
|
720
|
+
*/
|
|
721
|
+
template: _angular_core.Signal<TemplateRef<any> | undefined>;
|
|
722
|
+
/** Effect that triggers when the template is available */
|
|
723
|
+
private onTemplateReceived;
|
|
724
|
+
/**
|
|
725
|
+
* Static type guard for template context.
|
|
726
|
+
* Enables type inference in templates.
|
|
727
|
+
*/
|
|
728
|
+
static ngTemplateContextGuard(dir: GridColumnEditor, ctx: unknown): ctx is GridEditorContext;
|
|
729
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<GridColumnEditor, never>;
|
|
730
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<GridColumnEditor, "tbw-grid-column-editor", never, {}, {}, ["template"], never, true, never>;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Context provided to the grid containing form-related information.
|
|
735
|
+
* This can be accessed by other directives to get form controls.
|
|
736
|
+
* @since 0.5.0
|
|
737
|
+
*/
|
|
738
|
+
interface FormArrayContext {
|
|
739
|
+
/** Get the row data at a specific index */
|
|
740
|
+
getRow<T = unknown>(rowIndex: number): T | null;
|
|
741
|
+
/** Update a field value at a specific row */
|
|
742
|
+
updateField(rowIndex: number, field: string, value: unknown): void;
|
|
743
|
+
/** Get the current form value (all rows) */
|
|
744
|
+
getValue<T = unknown>(): T[];
|
|
745
|
+
/**
|
|
746
|
+
* Get the FormControl for a specific cell.
|
|
747
|
+
* Only available when using FormArray with FormGroup rows.
|
|
748
|
+
*
|
|
749
|
+
* @param rowIndex - The row index
|
|
750
|
+
* @param field - The field name
|
|
751
|
+
* @returns The AbstractControl for the cell, or undefined if not available
|
|
752
|
+
*/
|
|
753
|
+
getControl(rowIndex: number, field: string): AbstractControl | undefined;
|
|
754
|
+
/**
|
|
755
|
+
* Whether the grid is backed by a FormArray of FormGroups.
|
|
756
|
+
* When true, `getControl()` will return cell-level controls.
|
|
757
|
+
*/
|
|
758
|
+
hasFormGroups: boolean;
|
|
759
|
+
/**
|
|
760
|
+
* Get the FormGroup for a specific row.
|
|
761
|
+
* Only available when using FormArray with FormGroup rows.
|
|
762
|
+
*
|
|
763
|
+
* @param rowIndex - The row index
|
|
764
|
+
* @returns The FormGroup for the row, or undefined if not available
|
|
765
|
+
*/
|
|
766
|
+
getRowFormGroup(rowIndex: number): FormGroup | undefined;
|
|
767
|
+
/**
|
|
768
|
+
* Check if a row is valid (all controls in the FormGroup are valid).
|
|
769
|
+
* Returns true if not using FormArray or if the row doesn't exist.
|
|
770
|
+
*
|
|
771
|
+
* @param rowIndex - The row index
|
|
772
|
+
* @returns true if the row is valid, false if any control is invalid
|
|
773
|
+
*/
|
|
774
|
+
isRowValid(rowIndex: number): boolean;
|
|
775
|
+
/**
|
|
776
|
+
* Check if a row has been touched (any control in the FormGroup is touched).
|
|
777
|
+
* Returns false if not using FormArray or if the row doesn't exist.
|
|
778
|
+
*
|
|
779
|
+
* @param rowIndex - The row index
|
|
780
|
+
* @returns true if any control in the row is touched
|
|
781
|
+
*/
|
|
782
|
+
isRowTouched(rowIndex: number): boolean;
|
|
783
|
+
/**
|
|
784
|
+
* Check if a row is dirty (any control in the FormGroup is dirty).
|
|
785
|
+
* Returns false if not using FormArray or if the row doesn't exist.
|
|
786
|
+
*
|
|
787
|
+
* @param rowIndex - The row index
|
|
788
|
+
* @returns true if any control in the row is dirty
|
|
789
|
+
*/
|
|
790
|
+
isRowDirty(rowIndex: number): boolean;
|
|
791
|
+
/**
|
|
792
|
+
* Get validation errors for a specific row.
|
|
793
|
+
* Aggregates errors from all controls in the FormGroup.
|
|
794
|
+
*
|
|
795
|
+
* @param rowIndex - The row index
|
|
796
|
+
* @returns Object with field names as keys and their errors, or null if no errors
|
|
797
|
+
*/
|
|
798
|
+
getRowErrors(rowIndex: number): Record<string, unknown> | null;
|
|
799
|
+
}
|
|
800
|
+
/**
|
|
801
|
+
* Gets the FormArrayContext from a grid element, if present.
|
|
802
|
+
* @internal
|
|
803
|
+
* @since 0.5.0
|
|
804
|
+
*/
|
|
805
|
+
declare function getFormArrayContext(gridElement: HTMLElement): FormArrayContext | undefined;
|
|
806
|
+
/**
|
|
807
|
+
* Directive that binds a FormArray directly to the grid.
|
|
808
|
+
*
|
|
809
|
+
* This is the recommended way to integrate tbw-grid with Angular Reactive Forms.
|
|
810
|
+
* Use a FormArray of FormGroups for row-level validation and cell-level control access.
|
|
811
|
+
*
|
|
812
|
+
* ## Usage
|
|
813
|
+
*
|
|
814
|
+
* ```typescript
|
|
815
|
+
* import { Component, inject } from '@angular/core';
|
|
816
|
+
* import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
|
|
817
|
+
* import { Grid, GridFormArray } from '@toolbox-web/grid-angular/features/editing';
|
|
818
|
+
*
|
|
819
|
+
* @Component({
|
|
820
|
+
* imports: [Grid, GridFormArray, ReactiveFormsModule],
|
|
821
|
+
* template: \`
|
|
822
|
+
* <form [formGroup]="form">
|
|
823
|
+
* <tbw-grid [formArray]="form.controls.rows" [columns]="columns" />
|
|
824
|
+
* </form>
|
|
825
|
+
* \`
|
|
826
|
+
* })
|
|
827
|
+
* export class MyComponent {
|
|
828
|
+
* private fb = inject(FormBuilder);
|
|
829
|
+
*
|
|
830
|
+
* form = this.fb.group({
|
|
831
|
+
* rows: this.fb.array([
|
|
832
|
+
* this.fb.group({ name: 'Alice', age: 30 }),
|
|
833
|
+
* this.fb.group({ name: 'Bob', age: 25 }),
|
|
834
|
+
* ])
|
|
835
|
+
* });
|
|
836
|
+
*
|
|
837
|
+
* columns = [
|
|
838
|
+
* { field: 'name', header: 'Name', editable: true },
|
|
839
|
+
* { field: 'age', header: 'Age', editable: true }
|
|
840
|
+
* ];
|
|
841
|
+
* }
|
|
842
|
+
* ```
|
|
843
|
+
*
|
|
844
|
+
* ## How It Works
|
|
845
|
+
*
|
|
846
|
+
* - **FormArray → Grid**: The grid displays the FormArray's value as rows
|
|
847
|
+
* - **Grid → FormArray**: When a cell is edited, the corresponding FormControl is updated
|
|
848
|
+
* - FormArrayContext is available for accessing cell-level controls
|
|
849
|
+
*
|
|
850
|
+
* ## Features
|
|
851
|
+
*
|
|
852
|
+
* - Works naturally with FormArray inside a FormGroup
|
|
853
|
+
* - Provides cell-level FormControl access for validation
|
|
854
|
+
* - Supports row-level validation state aggregation
|
|
855
|
+
* - Automatically syncs FormArray changes to the grid
|
|
856
|
+
*
|
|
857
|
+
* @example
|
|
858
|
+
* ```html
|
|
859
|
+
* <form [formGroup]="form">
|
|
860
|
+
* <tbw-grid [formArray]="form.controls.rows" [columns]="columns" />
|
|
861
|
+
* </form>
|
|
862
|
+
* ```
|
|
863
|
+
*
|
|
864
|
+
* @category Directive
|
|
865
|
+
*
|
|
866
|
+
* @since 0.5.0
|
|
867
|
+
*/
|
|
868
|
+
declare class GridFormArray implements OnInit, OnDestroy {
|
|
869
|
+
#private;
|
|
870
|
+
private readonly destroyRef;
|
|
871
|
+
private elementRef;
|
|
872
|
+
private cellCommitUnsub;
|
|
873
|
+
private cellCancelUnsub;
|
|
874
|
+
private rowCommitUnsub;
|
|
875
|
+
private touchListener;
|
|
876
|
+
private valueChangesSubscription;
|
|
877
|
+
private statusChangesSubscriptions;
|
|
878
|
+
/**
|
|
879
|
+
* The FormArray to bind to the grid.
|
|
880
|
+
*/
|
|
881
|
+
readonly formArray: _angular_core.InputSignal<FormArray<any>>;
|
|
882
|
+
/**
|
|
883
|
+
* Whether to automatically sync Angular validation state to grid's visual invalid styling.
|
|
884
|
+
*
|
|
885
|
+
* When enabled:
|
|
886
|
+
* - After a cell commit, if the FormControl is invalid, the cell is marked with `setInvalid()`
|
|
887
|
+
* - When a FormControl becomes valid, `clearInvalid()` is called
|
|
888
|
+
* - On `row-commit`, if the row's FormGroup has invalid controls, the commit is prevented
|
|
889
|
+
* - In grid mode: validation state is synced on initial render and updated reactively
|
|
890
|
+
*
|
|
891
|
+
* @default true
|
|
892
|
+
*/
|
|
893
|
+
readonly syncValidation: _angular_core.InputSignal<boolean>;
|
|
894
|
+
/**
|
|
895
|
+
* Effect that sets up valueChanges subscription when FormArray changes.
|
|
896
|
+
* This handles both initial binding and when the FormArray reference changes.
|
|
897
|
+
*/
|
|
898
|
+
private syncFormArrayToGrid;
|
|
899
|
+
ngOnInit(): void;
|
|
900
|
+
ngOnDestroy(): void;
|
|
901
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<GridFormArray, never>;
|
|
902
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<GridFormArray, "tbw-grid[formArray]", never, { "formArray": { "alias": "formArray"; "required": true; "isSignal": true; }; "syncValidation": { "alias": "syncValidation"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
/**
|
|
906
|
+
* Gets the FormArrayContext from a grid element, if present.
|
|
907
|
+
* @internal
|
|
908
|
+
* @since 0.11.0
|
|
909
|
+
*/
|
|
910
|
+
declare function getLazyFormContext(gridElement: HTMLElement): FormArrayContext | undefined;
|
|
911
|
+
/**
|
|
912
|
+
* Factory function type for creating FormGroups lazily.
|
|
913
|
+
* Called when a row enters edit mode for the first time.
|
|
914
|
+
*
|
|
915
|
+
* @template TRow The row data type
|
|
916
|
+
* @param row The row data object
|
|
917
|
+
* @param rowIndex The row index in the grid
|
|
918
|
+
* @returns A FormGroup for the row (only include editable fields)
|
|
919
|
+
* @since 0.11.0
|
|
920
|
+
*/
|
|
921
|
+
type LazyFormFactory<TRow = unknown> = (row: TRow, rowIndex: number) => FormGroup;
|
|
922
|
+
/**
|
|
923
|
+
* Event emitted when a row's form values have changed.
|
|
924
|
+
* @since 0.11.0
|
|
925
|
+
*/
|
|
926
|
+
interface RowFormChangeEvent<TRow = unknown> {
|
|
927
|
+
/** The row index */
|
|
928
|
+
rowIndex: number;
|
|
929
|
+
/** The row ID (if available) */
|
|
930
|
+
rowId?: string;
|
|
931
|
+
/** The original row data */
|
|
932
|
+
row: TRow;
|
|
933
|
+
/** The FormGroup for this row */
|
|
934
|
+
formGroup: FormGroup;
|
|
935
|
+
/** The current form values */
|
|
936
|
+
values: Partial<TRow>;
|
|
937
|
+
/** Whether the form is valid */
|
|
938
|
+
valid: boolean;
|
|
939
|
+
/** Whether the form is dirty */
|
|
940
|
+
dirty: boolean;
|
|
941
|
+
}
|
|
942
|
+
/**
|
|
943
|
+
* Directive that provides lazy FormGroup creation for grid editing.
|
|
944
|
+
*
|
|
945
|
+
* Unlike `GridFormArray` which creates all FormGroups upfront, this directive
|
|
946
|
+
* creates FormGroups on-demand only when a row enters edit mode. This provides
|
|
947
|
+
* much better performance for large datasets while still enabling full
|
|
948
|
+
* Angular Reactive Forms integration.
|
|
949
|
+
*
|
|
950
|
+
* ## Key Benefits
|
|
951
|
+
*
|
|
952
|
+
* - **Performance**: Only creates FormGroups for rows being edited (20-100x fewer controls)
|
|
953
|
+
* - **Same DX**: Editors still receive `control` in their context for validation
|
|
954
|
+
* - **Memory efficient**: FormGroups are cleaned up when rows exit edit mode
|
|
955
|
+
*
|
|
956
|
+
* ## Usage
|
|
957
|
+
*
|
|
958
|
+
* ```typescript
|
|
959
|
+
* import { Component, inject, signal } from '@angular/core';
|
|
960
|
+
* import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
|
|
961
|
+
* import { Grid, GridLazyForm, TbwEditor } from '@toolbox-web/grid-angular/features/editing';
|
|
962
|
+
*
|
|
963
|
+
* @Component({
|
|
964
|
+
* imports: [Grid, GridLazyForm, TbwEditor, ReactiveFormsModule],
|
|
965
|
+
* template: \`
|
|
966
|
+
* <tbw-grid
|
|
967
|
+
* [rows]="employees()"
|
|
968
|
+
* [lazyForm]="createRowForm"
|
|
969
|
+
* [gridConfig]="config">
|
|
970
|
+
*
|
|
971
|
+
* <tbw-grid-column field="firstName">
|
|
972
|
+
* <input *tbwEditor="let _; control as ctrl"
|
|
973
|
+
* [formControl]="ctrl"
|
|
974
|
+
* [class.is-invalid]="ctrl?.invalid && ctrl?.touched" />
|
|
975
|
+
* </tbw-grid-column>
|
|
976
|
+
* </tbw-grid>
|
|
977
|
+
* \`
|
|
978
|
+
* })
|
|
979
|
+
* export class MyComponent {
|
|
980
|
+
* private fb = inject(FormBuilder);
|
|
981
|
+
* employees = signal(generateEmployees(1000));
|
|
982
|
+
*
|
|
983
|
+
* // Factory called when editing starts - only include editable fields!
|
|
984
|
+
* createRowForm = (row: Employee): FormGroup => this.fb.group({
|
|
985
|
+
* firstName: [row.firstName, Validators.required],
|
|
986
|
+
* lastName: [row.lastName, Validators.minLength(2)],
|
|
987
|
+
* salary: [row.salary, [Validators.required, Validators.min(0)]],
|
|
988
|
+
* });
|
|
989
|
+
*
|
|
990
|
+
* gridConfig = { columns: [...] };
|
|
991
|
+
* }
|
|
992
|
+
* ```
|
|
993
|
+
*
|
|
994
|
+
* ## How It Works
|
|
995
|
+
*
|
|
996
|
+
* 1. Rows come from `[rows]` input (plain data array)
|
|
997
|
+
* 2. When a cell enters edit mode, the FormGroup is created lazily
|
|
998
|
+
* 3. Editors receive the FormControl in their template context
|
|
999
|
+
* 4. On commit, FormGroup values are synced back to the row
|
|
1000
|
+
* 5. FormGroup is cleaned up when the row exits edit mode (configurable)
|
|
1001
|
+
*
|
|
1002
|
+
* ## Performance Comparison
|
|
1003
|
+
*
|
|
1004
|
+
* | Rows | GridFormArray (20 fields) | GridLazyForm |
|
|
1005
|
+
* |------|---------------------------|--------------|
|
|
1006
|
+
* | 100 | 2,000 controls | ~20 controls |
|
|
1007
|
+
* | 500 | 10,000 controls | ~20 controls |
|
|
1008
|
+
* | 1000 | 20,000 controls | ~20 controls |
|
|
1009
|
+
*
|
|
1010
|
+
* @example
|
|
1011
|
+
* ```html
|
|
1012
|
+
* <tbw-grid [rows]="employees()" [lazyForm]="createRowForm" [gridConfig]="gridConfig" />
|
|
1013
|
+
* ```
|
|
1014
|
+
*
|
|
1015
|
+
* @see GridFormArray For small datasets with full upfront validation
|
|
1016
|
+
* @category Directive
|
|
1017
|
+
*
|
|
1018
|
+
* @since 0.11.0
|
|
1019
|
+
*/
|
|
1020
|
+
declare class GridLazyForm<TRow = unknown> implements OnInit, OnDestroy {
|
|
1021
|
+
#private;
|
|
1022
|
+
private elementRef;
|
|
1023
|
+
private formGroupCache;
|
|
1024
|
+
private rowIndexMap;
|
|
1025
|
+
private editingRowIndex;
|
|
1026
|
+
private cellCommitUnsub;
|
|
1027
|
+
private rowCommitUnsub;
|
|
1028
|
+
private rowsChangeUnsub;
|
|
1029
|
+
/**
|
|
1030
|
+
* Factory function to create a FormGroup for a row.
|
|
1031
|
+
* Called lazily when the row first enters edit mode.
|
|
1032
|
+
*
|
|
1033
|
+
* @example
|
|
1034
|
+
* ```typescript
|
|
1035
|
+
* createRowForm = (row: Employee): FormGroup => this.fb.group({
|
|
1036
|
+
* firstName: [row.firstName, Validators.required],
|
|
1037
|
+
* lastName: [row.lastName],
|
|
1038
|
+
* salary: [row.salary, [Validators.min(0)]],
|
|
1039
|
+
* });
|
|
1040
|
+
* ```
|
|
1041
|
+
*/
|
|
1042
|
+
readonly lazyForm: _angular_core.InputSignal<LazyFormFactory<TRow>>;
|
|
1043
|
+
/**
|
|
1044
|
+
* Whether to automatically sync Angular validation state to grid's visual invalid styling.
|
|
1045
|
+
*
|
|
1046
|
+
* When enabled:
|
|
1047
|
+
* - After a cell commit, if the FormControl is invalid, the cell is marked with `setInvalid()`
|
|
1048
|
+
* - When a FormControl becomes valid, `clearInvalid()` is called
|
|
1049
|
+
* - On `row-commit`, if the row's FormGroup has invalid controls, the commit is prevented
|
|
1050
|
+
*
|
|
1051
|
+
* @default true
|
|
1052
|
+
*/
|
|
1053
|
+
readonly syncValidation: _angular_core.InputSignal<boolean>;
|
|
1054
|
+
/**
|
|
1055
|
+
* Whether to keep FormGroups cached after a row exits edit mode.
|
|
1056
|
+
*
|
|
1057
|
+
* - `true`: FormGroups are kept, preserving dirty/touched state across edit sessions
|
|
1058
|
+
* - `false`: FormGroups are disposed when the row exits edit mode (default)
|
|
1059
|
+
*
|
|
1060
|
+
* @default false
|
|
1061
|
+
*/
|
|
1062
|
+
readonly keepFormGroups: _angular_core.InputSignal<boolean>;
|
|
1063
|
+
/**
|
|
1064
|
+
* Emitted when a row's form values change.
|
|
1065
|
+
* Useful for auto-save, validation display, or syncing to external state.
|
|
1066
|
+
*/
|
|
1067
|
+
readonly rowFormChange: _angular_core.OutputEmitterRef<RowFormChangeEvent<TRow>>;
|
|
1068
|
+
ngOnInit(): void;
|
|
1069
|
+
ngOnDestroy(): void;
|
|
1070
|
+
/**
|
|
1071
|
+
* Gets the FormGroup for a row, if it exists.
|
|
1072
|
+
* Unlike the context methods, this does NOT create a FormGroup lazily.
|
|
1073
|
+
*
|
|
1074
|
+
* @param rowIndex The row index
|
|
1075
|
+
* @returns The FormGroup or undefined
|
|
1076
|
+
*/
|
|
1077
|
+
getFormGroup(rowIndex: number): FormGroup | undefined;
|
|
1078
|
+
/**
|
|
1079
|
+
* Gets all cached FormGroups.
|
|
1080
|
+
* Useful for bulk validation or inspection.
|
|
1081
|
+
*
|
|
1082
|
+
* @returns Map of row objects to their FormGroups
|
|
1083
|
+
*/
|
|
1084
|
+
getAllFormGroups(): ReadonlyMap<TRow, FormGroup>;
|
|
1085
|
+
/**
|
|
1086
|
+
* Clears all cached FormGroups.
|
|
1087
|
+
* Useful when the underlying data changes significantly.
|
|
1088
|
+
*/
|
|
1089
|
+
clearAllFormGroups(): void;
|
|
1090
|
+
/**
|
|
1091
|
+
* Validates all currently cached FormGroups.
|
|
1092
|
+
*
|
|
1093
|
+
* @returns true if all FormGroups are valid, false otherwise
|
|
1094
|
+
*/
|
|
1095
|
+
validateAll(): boolean;
|
|
1096
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<GridLazyForm<any>, never>;
|
|
1097
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<GridLazyForm<any>, "tbw-grid[lazyForm]", never, { "lazyForm": { "alias": "lazyForm"; "required": true; "isSignal": true; }; "syncValidation": { "alias": "syncValidation"; "required": false; "isSignal": true; }; "keepFormGroups": { "alias": "keepFormGroups"; "required": false; "isSignal": true; }; }, { "rowFormChange": "rowFormChange"; }, never, never, true, never>;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
/**
|
|
1101
|
+
* Context type for structural editor directives with `any` defaults.
|
|
1102
|
+
* This provides better ergonomics in templates without requiring explicit type annotations.
|
|
1103
|
+
*
|
|
1104
|
+
* @internal Use `GridEditorContext` in application code for stricter typing.
|
|
1105
|
+
* @since 0.1.1
|
|
1106
|
+
*/
|
|
1107
|
+
interface StructuralEditorContext<TValue = any, TRow = any> {
|
|
1108
|
+
/** The cell value for this column */
|
|
1109
|
+
$implicit: TValue;
|
|
1110
|
+
/** The cell value (explicit binding) */
|
|
1111
|
+
value: TValue;
|
|
1112
|
+
/** The full row data object */
|
|
1113
|
+
row: TRow;
|
|
1114
|
+
/** The column configuration */
|
|
1115
|
+
column: any;
|
|
1116
|
+
/**
|
|
1117
|
+
* Callback function to commit the edited value.
|
|
1118
|
+
*/
|
|
1119
|
+
onCommit: (value: TValue) => void;
|
|
1120
|
+
/**
|
|
1121
|
+
* Callback function to cancel editing.
|
|
1122
|
+
*/
|
|
1123
|
+
onCancel: () => void;
|
|
1124
|
+
/**
|
|
1125
|
+
* The FormControl for this cell, if the grid is bound to a FormArray with FormGroups.
|
|
1126
|
+
*
|
|
1127
|
+
* Returns `undefined` if:
|
|
1128
|
+
* - The grid is not bound to a FormArray
|
|
1129
|
+
* - The FormArray doesn't contain FormGroups
|
|
1130
|
+
* - The field doesn't exist in the FormGroup
|
|
1131
|
+
*/
|
|
1132
|
+
control?: AbstractControl;
|
|
1133
|
+
}
|
|
1134
|
+
/**
|
|
1135
|
+
* Gets the editor template registered by the structural directive for a given column element.
|
|
1136
|
+
* Falls back to the non-structural directive registry.
|
|
1137
|
+
*/
|
|
1138
|
+
declare function getStructuralEditorTemplate(columnElement: HTMLElement): TemplateRef<StructuralEditorContext> | undefined;
|
|
1139
|
+
/**
|
|
1140
|
+
* Structural directive for cell editor rendering.
|
|
1141
|
+
*
|
|
1142
|
+
* This provides a cleaner syntax for defining custom cell editors without
|
|
1143
|
+
* the nested `<tbw-grid-column-editor>` and `<ng-template>` boilerplate.
|
|
1144
|
+
*
|
|
1145
|
+
* ## Usage
|
|
1146
|
+
*
|
|
1147
|
+
* ```html
|
|
1148
|
+
* <!-- Instead of this verbose syntax: -->
|
|
1149
|
+
* <tbw-grid-column field="status">
|
|
1150
|
+
* <tbw-grid-column-editor>
|
|
1151
|
+
* <ng-template let-value let-onCommit="onCommit" let-onCancel="onCancel">
|
|
1152
|
+
* <app-status-editor [value]="value" (commit)="onCommit($event)" (cancel)="onCancel()" />
|
|
1153
|
+
* </ng-template>
|
|
1154
|
+
* </tbw-grid-column-editor>
|
|
1155
|
+
* </tbw-grid-column>
|
|
1156
|
+
*
|
|
1157
|
+
* <!-- Use this cleaner syntax (with auto-wiring - no explicit bindings needed!): -->
|
|
1158
|
+
* <tbw-grid-column field="status">
|
|
1159
|
+
* <app-status-editor *tbwEditor="let value" [value]="value" />
|
|
1160
|
+
* </tbw-grid-column>
|
|
1161
|
+
* ```
|
|
1162
|
+
*
|
|
1163
|
+
* ## Template Context
|
|
1164
|
+
*
|
|
1165
|
+
* The structural directive provides the same context as `GridColumnEditor`:
|
|
1166
|
+
* - `$implicit` / `value`: The cell value
|
|
1167
|
+
* - `row`: The full row data object
|
|
1168
|
+
* - `column`: The column configuration
|
|
1169
|
+
* - `onCommit`: Callback function to commit the new value (optional - auto-wired if component emits `commit` event)
|
|
1170
|
+
* - `onCancel`: Callback function to cancel editing (optional - auto-wired if component emits `cancel` event)
|
|
1171
|
+
*
|
|
1172
|
+
* ## Import
|
|
1173
|
+
*
|
|
1174
|
+
* ```typescript
|
|
1175
|
+
* import { TbwEditor } from '@toolbox-web/grid-angular/features/editing';
|
|
1176
|
+
*
|
|
1177
|
+
* @Component({
|
|
1178
|
+
* imports: [TbwEditor],
|
|
1179
|
+
* // ...
|
|
1180
|
+
* })
|
|
1181
|
+
* ```
|
|
1182
|
+
*
|
|
1183
|
+
* @example
|
|
1184
|
+
* ```html
|
|
1185
|
+
* <tbw-grid-column field="status" editable>
|
|
1186
|
+
* <app-status-editor *tbwEditor="let value" [value]="value" />
|
|
1187
|
+
* </tbw-grid-column>
|
|
1188
|
+
* ```
|
|
1189
|
+
*
|
|
1190
|
+
* @category Directive
|
|
1191
|
+
* @since 0.1.1
|
|
1192
|
+
*/
|
|
1193
|
+
declare class TbwEditor implements OnDestroy {
|
|
1194
|
+
private template;
|
|
1195
|
+
private elementRef;
|
|
1196
|
+
private columnElement;
|
|
1197
|
+
constructor();
|
|
1198
|
+
private registerTemplate;
|
|
1199
|
+
ngOnDestroy(): void;
|
|
1200
|
+
/**
|
|
1201
|
+
* Static type guard for template context.
|
|
1202
|
+
* Uses `any` defaults for ergonomic template usage.
|
|
1203
|
+
*/
|
|
1204
|
+
static ngTemplateContextGuard(dir: TbwEditor, ctx: unknown): ctx is StructuralEditorContext;
|
|
1205
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<TbwEditor, never>;
|
|
1206
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TbwEditor, "[tbwEditor]", never, {}, {}, never, never, true, never>;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
export { BaseGridEditor, BaseGridEditorCVA, BaseOverlayEditor, GridColumnEditor, GridEditingDirective, GridFormArray, GridLazyForm, TbwEditor, getEditorTemplate, getFormArrayContext, getLazyFormContext, getStructuralEditorTemplate };
|
|
1210
|
+
export type { FormArrayContext, GridEditorContext, LazyFormFactory, OverlayPosition, RowFormChangeEvent, StructuralEditorContext };
|
|
34
1211
|
//# sourceMappingURL=toolbox-web-grid-angular-features-editing.d.ts.map
|