@toolbox-web/grid-angular 0.12.1 → 0.13.1

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.
@@ -1,8 +1,8 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { Type, EnvironmentInjector, ApplicationRef, ViewContainerRef, InjectionToken, EnvironmentProviders, Signal, TemplateRef, EventEmitter, OnInit, OnDestroy, AfterContentInit } from '@angular/core';
3
- import { GridConfig as GridConfig$1, ColumnConfig as ColumnConfig$1, FrameworkAdapter, TypeDefault as TypeDefault$1, ColumnViewRenderer, ColumnEditorSpec, GridIcons, DataGridElement, ExpandCollapseAnimation, CellClickDetail, RowClickDetail, CellActivateDetail, CellChangeDetail, SortChangeDetail, ColumnResizeDetail, GridColumnState } from '@toolbox-web/grid';
3
+ import { GridConfig as GridConfig$1, ColumnConfig as ColumnConfig$1, FrameworkAdapter, TypeDefault as TypeDefault$1, ColumnViewRenderer, ColumnEditorSpec, GridIcons, DataGridElement, ExpandCollapseAnimation, FitMode, CellClickDetail, RowClickDetail, CellActivateDetail, CellChangeDetail, SortChangeDetail, ColumnResizeDetail, GridColumnState } from '@toolbox-web/grid';
4
4
  import { FilterPanelRenderer, FilterPanelParams } from '@toolbox-web/grid/plugins/filtering';
5
- import { AbstractControl, FormArray, FormGroup } from '@angular/forms';
5
+ import { AbstractControl, ControlValueAccessor, FormGroup, FormArray } from '@angular/forms';
6
6
  import { EditingConfig, ChangedRowsResetDetail } from '@toolbox-web/grid/plugins/editing';
7
7
  import { SelectionConfig, ClipboardConfig, ContextMenuConfig, MultiSortConfig, FilterConfig, ReorderConfig, VisibilityConfig, GroupingColumnsConfig, ColumnVirtualizationConfig, RowReorderConfig, GroupingRowsConfig, PinnedRowsConfig, TreeConfig, MasterDetailConfig, ResponsivePluginConfig, UndoRedoConfig, ExportConfig, PrintConfig, PivotConfig, ServerSideConfig, FilterChangeDetail, ColumnMoveDetail, ColumnVisibilityDetail, SelectionChangeDetail, RowMoveDetail, GroupToggleDetail, TreeExpandDetail, DetailExpandDetail, ResponsiveChangeDetail, CopyDetail, PasteDetail, UndoRedoDetail, ExportCompleteDetail, PrintStartDetail, PrintCompleteDetail } from '@toolbox-web/grid/all';
8
8
 
@@ -336,6 +336,10 @@ declare class GridAdapter implements FrameworkAdapter {
336
336
  private viewContainerRef;
337
337
  private viewRefs;
338
338
  private componentRefs;
339
+ /** Editor-specific view refs tracked separately for per-cell cleanup via releaseCell. */
340
+ private editorViewRefs;
341
+ /** Editor-specific component refs tracked separately for per-cell cleanup via releaseCell. */
342
+ private editorComponentRefs;
339
343
  private typeRegistry;
340
344
  constructor(injector: EnvironmentInjector, appRef: ApplicationRef, viewContainerRef: ViewContainerRef);
341
345
  /**
@@ -508,6 +512,16 @@ declare class GridAdapter implements FrameworkAdapter {
508
512
  * @internal
509
513
  */
510
514
  private setComponentInputs;
515
+ /**
516
+ * Called when a cell's content is about to be wiped (e.g., exiting edit mode,
517
+ * scroll-recycling a row, or rebuilding a row).
518
+ *
519
+ * Destroys any editor embedded views or component refs whose DOM is
520
+ * inside the given cell element. This prevents memory leaks from
521
+ * orphaned Angular views that would otherwise stay in the change
522
+ * detection tree indefinitely.
523
+ */
524
+ releaseCell(cellEl: HTMLElement): void;
511
525
  /**
512
526
  * Clean up all view references and component references.
513
527
  * Call this when your app/component is destroyed.
@@ -989,6 +1003,99 @@ declare function createPluginFromFeature<TConfig = unknown>(name: FeatureName, c
989
1003
  */
990
1004
  declare function clearFeatureRegistry(): void;
991
1005
 
1006
+ /**
1007
+ * Base class for Angular filter panel components.
1008
+ *
1009
+ * Provides a ready-made `params` input and common lifecycle helpers
1010
+ * (`applyAndClose`, `clearAndClose`) so consumers only need to implement
1011
+ * their filter logic in `applyFilter()`.
1012
+ *
1013
+ * ## Usage
1014
+ *
1015
+ * ```typescript
1016
+ * import { Component } from '@angular/core';
1017
+ * import { BaseFilterPanel } from '@toolbox-web/grid-angular';
1018
+ *
1019
+ * @Component({
1020
+ * selector: 'app-text-filter',
1021
+ * template: `
1022
+ * <input #input (keydown.enter)="applyAndClose()" />
1023
+ * <button (click)="applyAndClose()">Apply</button>
1024
+ * <button (click)="clearAndClose()">Clear</button>
1025
+ * `
1026
+ * })
1027
+ * export class TextFilterComponent extends BaseFilterPanel {
1028
+ * @ViewChild('input') input!: ElementRef<HTMLInputElement>;
1029
+ *
1030
+ * applyFilter(): void {
1031
+ * this.params().applyTextFilter('contains', this.input.nativeElement.value);
1032
+ * }
1033
+ * }
1034
+ * ```
1035
+ *
1036
+ * ## Template Syntax
1037
+ *
1038
+ * The grid's filtering plugin will mount this component and provide `params`
1039
+ * automatically. No manual wiring is required:
1040
+ *
1041
+ * ```typescript
1042
+ * gridConfig = {
1043
+ * columns: [
1044
+ * { field: 'name', filterable: true, filterPanel: TextFilterComponent },
1045
+ * ],
1046
+ * };
1047
+ * ```
1048
+ *
1049
+ * @typeParam TRow - The row data type (available via `params().column`)
1050
+ */
1051
+ declare abstract class BaseFilterPanel implements FilterPanel {
1052
+ /**
1053
+ * Filter panel parameters injected by the grid's filtering plugin.
1054
+ *
1055
+ * Provides access to:
1056
+ * - `field` — the column field name
1057
+ * - `column` — full column configuration
1058
+ * - `uniqueValues` — distinct values in the column
1059
+ * - `excludedValues` — currently excluded values (set filter)
1060
+ * - `searchText` — current search text
1061
+ * - `applySetFilter(excluded)` — apply a set-based (include/exclude) filter
1062
+ * - `applyTextFilter(operator, value, valueTo?)` — apply a text/number filter
1063
+ * - `clearFilter()` — clear the filter for this column
1064
+ * - `closePanel()` — close the filter panel
1065
+ */
1066
+ readonly params: _angular_core.InputSignal<FilterPanelParams>;
1067
+ /**
1068
+ * Implement this to apply your filter logic.
1069
+ *
1070
+ * Called by {@link applyAndClose} before closing the panel.
1071
+ * Use `this.params()` to access the filter API.
1072
+ *
1073
+ * @example
1074
+ * ```typescript
1075
+ * applyFilter(): void {
1076
+ * this.params().applyTextFilter('contains', this.searchText);
1077
+ * }
1078
+ * ```
1079
+ */
1080
+ abstract applyFilter(): void;
1081
+ /**
1082
+ * Apply the filter then close the panel.
1083
+ *
1084
+ * Calls {@link applyFilter} followed by `params().closePanel()`.
1085
+ * Bind this to your "Apply" button or Enter key handler.
1086
+ */
1087
+ applyAndClose(): void;
1088
+ /**
1089
+ * Clear the filter then close the panel.
1090
+ *
1091
+ * Calls `params().clearFilter()` followed by `params().closePanel()`.
1092
+ * Bind this to your "Clear" / "Reset" button.
1093
+ */
1094
+ clearAndClose(): void;
1095
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseFilterPanel, never>;
1096
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BaseFilterPanel, never, never, { "params": { "alias": "params"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
1097
+ }
1098
+
992
1099
  /**
993
1100
  * Base class for grid cell editors.
994
1101
  *
@@ -1160,6 +1267,330 @@ declare abstract class BaseGridEditor<TRow = unknown, TValue = unknown> {
1160
1267
  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>;
1161
1268
  }
1162
1269
 
1270
+ /**
1271
+ * Base class for grid editors that also work as Angular form controls.
1272
+ *
1273
+ * Combines `BaseGridEditor` with `ControlValueAccessor` so the same component
1274
+ * can be used inside a `<tbw-grid>` **and** in a standalone `<form>`.
1275
+ *
1276
+ * ## What it provides
1277
+ *
1278
+ * | Member | Purpose |
1279
+ * |--------|---------|
1280
+ * | `cvaValue` | Signal holding the value written by the form control |
1281
+ * | `disabledState` | Signal tracking `setDisabledState` calls |
1282
+ * | `displayValue` | Computed that prefers grid value (`currentValue`) and falls back to `cvaValue` |
1283
+ * | `commitBoth(v)` | Commits via both CVA `onChange` and grid `commitValue` |
1284
+ * | `writeValue` / `registerOn*` / `setDisabledState` | Full CVA implementation |
1285
+ *
1286
+ * ## Usage
1287
+ *
1288
+ * ```typescript
1289
+ * import { Component, forwardRef } from '@angular/core';
1290
+ * import { NG_VALUE_ACCESSOR } from '@angular/forms';
1291
+ * import { BaseGridEditorCVA } from '@toolbox-web/grid-angular';
1292
+ *
1293
+ * @Component({
1294
+ * selector: 'app-date-picker',
1295
+ * providers: [{
1296
+ * provide: NG_VALUE_ACCESSOR,
1297
+ * useExisting: forwardRef(() => DatePickerComponent),
1298
+ * multi: true,
1299
+ * }],
1300
+ * template: `
1301
+ * <input
1302
+ * type="date"
1303
+ * [value]="displayValue()"
1304
+ * [disabled]="disabledState()"
1305
+ * (change)="commitBoth($event.target.value)"
1306
+ * (keydown.escape)="cancelEdit()"
1307
+ * />
1308
+ * `
1309
+ * })
1310
+ * export class DatePickerComponent extends BaseGridEditorCVA<MyRow, string> {}
1311
+ * ```
1312
+ *
1313
+ * > **Note:** Subclasses must still provide `NG_VALUE_ACCESSOR` themselves
1314
+ * > because `forwardRef(() => ConcreteClass)` must reference the concrete
1315
+ * > component — this is an Angular limitation.
1316
+ *
1317
+ * @typeParam TRow - The row data type
1318
+ * @typeParam TValue - The cell/control value type
1319
+ */
1320
+ declare abstract class BaseGridEditorCVA<TRow = unknown, TValue = unknown> extends BaseGridEditor<TRow, TValue> implements ControlValueAccessor {
1321
+ /** Internal onChange callback registered by the form control. */
1322
+ private _onChange;
1323
+ /** Internal onTouched callback registered by the form control. */
1324
+ private _onTouched;
1325
+ /**
1326
+ * Signal holding the value written by the form control via `writeValue()`.
1327
+ * Updated when the form control pushes a new value (e.g. `patchValue`, `setValue`).
1328
+ */
1329
+ protected readonly cvaValue: _angular_core.WritableSignal<TValue | null>;
1330
+ /**
1331
+ * Signal tracking the disabled state set by the form control.
1332
+ * Updated when `setDisabledState()` is called by Angular's forms module.
1333
+ */
1334
+ readonly disabledState: _angular_core.WritableSignal<boolean>;
1335
+ /**
1336
+ * Resolved display value.
1337
+ *
1338
+ * Prefers `currentValue()` (grid context — from `control.value` or `value` input)
1339
+ * and falls back to `cvaValue()` (standalone form context — from `writeValue`).
1340
+ *
1341
+ * Use this in your template instead of reading `currentValue()` directly
1342
+ * so the component works in both grid and standalone form contexts.
1343
+ */
1344
+ readonly displayValue: _angular_core.Signal<TValue | null>;
1345
+ /**
1346
+ * Called by Angular forms when the form control value changes programmatically.
1347
+ */
1348
+ writeValue(value: TValue | null): void;
1349
+ /**
1350
+ * Called by Angular forms to register a change callback.
1351
+ */
1352
+ registerOnChange(fn: (value: TValue | null) => void): void;
1353
+ /**
1354
+ * Called by Angular forms to register a touched callback.
1355
+ */
1356
+ registerOnTouched(fn: () => void): void;
1357
+ /**
1358
+ * Called by Angular forms to set the disabled state.
1359
+ */
1360
+ setDisabledState(isDisabled: boolean): void;
1361
+ /**
1362
+ * Commit a value through both the CVA (form control) and the grid.
1363
+ *
1364
+ * - Calls the CVA `onChange` callback (updates the form control)
1365
+ * - Marks the control as touched
1366
+ * - Calls `commitValue()` (emits grid commit event + DOM `CustomEvent`)
1367
+ *
1368
+ * Use this instead of `commitValue()` when your editor doubles as a form control.
1369
+ *
1370
+ * @param value - The new value to commit
1371
+ */
1372
+ protected commitBoth(value: TValue | null): void;
1373
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseGridEditorCVA<any, any>, never>;
1374
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BaseGridEditorCVA<any, any>, never, never, {}, {}, never, never, true, never>;
1375
+ }
1376
+
1377
+ /**
1378
+ * Position of the overlay panel relative to its anchor cell.
1379
+ *
1380
+ * - `'below'` — panel appears below the cell, left-aligned (default)
1381
+ * - `'above'` — panel appears above the cell, left-aligned
1382
+ * - `'below-right'` — panel appears below the cell, right-aligned
1383
+ * - `'over-top-left'` — panel top-left corner aligns with cell top-left corner (opens downward)
1384
+ * - `'over-bottom-left'` — panel bottom-left corner aligns with cell bottom-left corner (opens upward)
1385
+ */
1386
+ type OverlayPosition = 'below' | 'above' | 'below-right' | 'over-top-left' | 'over-bottom-left';
1387
+ /**
1388
+ * Base class for grid editors that display a floating overlay panel.
1389
+ *
1390
+ * Provides infrastructure for:
1391
+ * - **Overlay positioning** — CSS Anchor Positioning with JS fallback
1392
+ * - **Focus gating** — in row editing mode, the panel only opens for the focused cell
1393
+ * - **Click-outside detection** — closes the panel when clicking outside
1394
+ * - **MutationObserver** — detects cell focus changes (row editing mode)
1395
+ * - **Escape handling** — closes the panel and returns focus to the inline input
1396
+ * - **Synthetic Tab dispatch** — advances grid focus after overlay close
1397
+ * - **Automatic teardown** — removes the panel from `<body>` and cleans up listeners
1398
+ *
1399
+ * ## Usage
1400
+ *
1401
+ * ```typescript
1402
+ * import { Component, ViewChild, ElementRef } from '@angular/core';
1403
+ * import { BaseOverlayEditor } from '@toolbox-web/grid-angular';
1404
+ *
1405
+ * @Component({
1406
+ * selector: 'app-date-editor',
1407
+ * template: `
1408
+ * <input
1409
+ * #inlineInput
1410
+ * readonly
1411
+ * [value]="currentValue()"
1412
+ * (click)="onInlineClick()"
1413
+ * (keydown)="onInlineKeydown($event)"
1414
+ * />
1415
+ * <div #panel class="tbw-overlay-panel" style="width: 280px;">
1416
+ * <!-- your date picker UI here -->
1417
+ * <div class="actions">
1418
+ * <button (click)="selectAndClose(selectedDate)">OK</button>
1419
+ * <button (click)="hideOverlay()">Cancel</button>
1420
+ * </div>
1421
+ * </div>
1422
+ * `
1423
+ * })
1424
+ * export class DateEditorComponent extends BaseOverlayEditor<MyRow, string> {
1425
+ * @ViewChild('panel') panelRef!: ElementRef<HTMLElement>;
1426
+ * @ViewChild('inlineInput') inputRef!: ElementRef<HTMLInputElement>;
1427
+ *
1428
+ * protected override overlayPosition = 'below' as const;
1429
+ *
1430
+ * ngAfterViewInit(): void {
1431
+ * this.initOverlay(this.panelRef.nativeElement);
1432
+ * if (this.isCellFocused()) this.showOverlay();
1433
+ * }
1434
+ *
1435
+ * protected getInlineInput(): HTMLInputElement | null {
1436
+ * return this.inputRef?.nativeElement ?? null;
1437
+ * }
1438
+ *
1439
+ * protected onOverlayOutsideClick(): void {
1440
+ * this.hideOverlay();
1441
+ * }
1442
+ *
1443
+ * selectAndClose(date: string): void {
1444
+ * this.commitValue(date);
1445
+ * this.hideOverlay();
1446
+ * }
1447
+ * }
1448
+ * ```
1449
+ *
1450
+ * @typeParam TRow - The row data type
1451
+ * @typeParam TValue - The cell value type
1452
+ */
1453
+ declare abstract class BaseOverlayEditor<TRow = unknown, TValue = unknown> extends BaseGridEditor<TRow, TValue> {
1454
+ private readonly _elementRef;
1455
+ private readonly _overlayDestroyRef;
1456
+ /**
1457
+ * Position of the overlay panel relative to the anchor cell.
1458
+ * Override in subclasses to change the default position.
1459
+ *
1460
+ * @default 'below'
1461
+ */
1462
+ protected overlayPosition: OverlayPosition;
1463
+ /** The overlay panel element (set via `initOverlay()`). */
1464
+ private _panel;
1465
+ /** Whether the overlay is currently visible. */
1466
+ private _isOpen;
1467
+ /** Unique anchor ID for CSS Anchor Positioning. */
1468
+ private _anchorId;
1469
+ /** Whether the browser supports CSS Anchor Positioning. */
1470
+ private _supportsAnchor;
1471
+ /** AbortController for all overlay-related listeners. */
1472
+ private _abortCtrl;
1473
+ /** MutationObserver watching cell focus class changes. */
1474
+ private _focusObserver;
1475
+ constructor();
1476
+ /**
1477
+ * Initialise the overlay with the panel element.
1478
+ *
1479
+ * Call this in `ngAfterViewInit` with your `@ViewChild` panel reference.
1480
+ * The panel is moved to `<body>` and hidden until {@link showOverlay} is called.
1481
+ *
1482
+ * @param panel - The overlay panel DOM element
1483
+ */
1484
+ protected initOverlay(panel: HTMLElement): void;
1485
+ /**
1486
+ * Show the overlay panel.
1487
+ *
1488
+ * If CSS Anchor Positioning is not supported, falls back to JS-based
1489
+ * positioning using `getBoundingClientRect()`.
1490
+ */
1491
+ protected showOverlay(): void;
1492
+ /**
1493
+ * Hide the overlay panel.
1494
+ *
1495
+ * @param suppressTabAdvance - When `true`, skip synthetic Tab dispatch
1496
+ * (useful when hiding is triggered by an external focus change).
1497
+ */
1498
+ protected hideOverlay(suppressTabAdvance?: boolean): void;
1499
+ /**
1500
+ * Close and immediately re-open the overlay.
1501
+ * Useful after the panel content changes size and needs repositioning.
1502
+ */
1503
+ protected reopenOverlay(): void;
1504
+ /**
1505
+ * Remove the overlay from the DOM and clean up all listeners.
1506
+ *
1507
+ * Called automatically on `DestroyRef.onDestroy`. Can also be called
1508
+ * manually if the editor needs early cleanup.
1509
+ */
1510
+ protected teardownOverlay(): void;
1511
+ /**
1512
+ * Override in `edit-close` handler to also hide the overlay.
1513
+ * This is called automatically by `BaseGridEditor` when the grid
1514
+ * ends the editing session.
1515
+ */
1516
+ protected onEditClose(): void;
1517
+ /**
1518
+ * Keydown handler for the inline readonly input.
1519
+ *
1520
+ * - **Enter / Space / ArrowDown / F2** → open overlay
1521
+ * - **Escape** → calls {@link handleEscape}
1522
+ *
1523
+ * Bind this to `(keydown)` on your inline input element.
1524
+ */
1525
+ onInlineKeydown(event: KeyboardEvent): void;
1526
+ /**
1527
+ * Click handler for the inline input.
1528
+ * Opens the overlay and calls {@link onOverlayOpened}.
1529
+ *
1530
+ * Bind this to `(click)` on your inline input element.
1531
+ */
1532
+ onInlineClick(): void;
1533
+ /**
1534
+ * Handle Escape key press.
1535
+ *
1536
+ * If the overlay is open, closes it and returns focus to the inline input.
1537
+ * If the overlay is already closed, cancels the edit entirely.
1538
+ */
1539
+ protected handleEscape(event: Event): void;
1540
+ /**
1541
+ * Dispatch a synthetic Tab key event to advance grid focus.
1542
+ *
1543
+ * Call this after committing a value and closing the overlay so the
1544
+ * grid moves focus to the next cell.
1545
+ *
1546
+ * @param backward - When `true`, dispatch Shift+Tab to move backwards.
1547
+ */
1548
+ protected advanceGridFocus(backward?: boolean): void;
1549
+ /**
1550
+ * Return the inline input element, if any.
1551
+ *
1552
+ * Used by overlay infrastructure to return focus after hiding.
1553
+ * Return `null` if there is no inline input.
1554
+ */
1555
+ protected abstract getInlineInput(): HTMLInputElement | null;
1556
+ /**
1557
+ * Called when a pointerdown event occurs outside the overlay panel
1558
+ * and outside the editor's host element.
1559
+ *
1560
+ * Typically, subclasses call `hideOverlay()` here.
1561
+ */
1562
+ protected abstract onOverlayOutsideClick(): void;
1563
+ /**
1564
+ * Called after the overlay is shown.
1565
+ *
1566
+ * Override to focus an element inside the panel, start animations, etc.
1567
+ * Default implementation is a no-op.
1568
+ */
1569
+ protected onOverlayOpened(): void;
1570
+ /** Find the parent cell element for this editor. */
1571
+ private _getCell;
1572
+ /**
1573
+ * JS fallback positioning for browsers without CSS Anchor Positioning.
1574
+ * Uses `getBoundingClientRect()` with viewport overflow detection.
1575
+ */
1576
+ private _positionWithJs;
1577
+ /**
1578
+ * Document pointerdown handler for click-outside detection.
1579
+ * Fires `onOverlayOutsideClick()` if the click is outside the panel
1580
+ * and outside the editor's host element.
1581
+ */
1582
+ private _onDocumentPointerDown;
1583
+ /**
1584
+ * Set up a MutationObserver on the parent cell to watch for
1585
+ * `cell-focus` class changes. This handles row-editing mode where
1586
+ * all editors exist simultaneously but only the focused cell's
1587
+ * editor should have its overlay visible.
1588
+ */
1589
+ private _setupFocusObserver;
1590
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<BaseOverlayEditor<any, any>, never>;
1591
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BaseOverlayEditor<any, any>, never, never, {}, {}, never, never, true, never>;
1592
+ }
1593
+
1163
1594
  /**
1164
1595
  * Context object passed to the cell editor template.
1165
1596
  * Contains the cell value, row data, column configuration, and commit/cancel functions.
@@ -1350,6 +1781,39 @@ declare class GridColumnView {
1350
1781
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<GridColumnView, "tbw-grid-column-view", never, {}, {}, ["template"], never, true, never>;
1351
1782
  }
1352
1783
 
1784
+ /**
1785
+ * Directive that registers `<tbw-grid-column>` as a known Angular element.
1786
+ *
1787
+ * This directive exists so that Angular's template compiler recognises
1788
+ * `<tbw-grid-column>` without requiring `CUSTOM_ELEMENTS_SCHEMA`.
1789
+ * The underlying web component reads its attributes (`field`, `header`,
1790
+ * `type`, `width`, etc.) directly from the DOM, so no `@Input()` forwarding
1791
+ * is needed — Angular's standard property/attribute binding handles it.
1792
+ *
1793
+ * ## Usage
1794
+ *
1795
+ * ```typescript
1796
+ * import { Component } from '@angular/core';
1797
+ * import { Grid, TbwGridColumn, TbwRenderer } from '@toolbox-web/grid-angular';
1798
+ *
1799
+ * @Component({
1800
+ * imports: [Grid, TbwGridColumn, TbwRenderer],
1801
+ * template: `
1802
+ * <tbw-grid [rows]="rows" [gridConfig]="config">
1803
+ * <tbw-grid-column field="status">
1804
+ * <app-status-badge *tbwRenderer="let value" [value]="value" />
1805
+ * </tbw-grid-column>
1806
+ * </tbw-grid>
1807
+ * `
1808
+ * })
1809
+ * export class MyComponent { }
1810
+ * ```
1811
+ */
1812
+ declare class TbwGridColumn {
1813
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TbwGridColumn, never>;
1814
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TbwGridColumn, "tbw-grid-column", never, {}, {}, never, never, true, never>;
1815
+ }
1816
+
1353
1817
  /**
1354
1818
  * Context object passed to the detail renderer template.
1355
1819
  * Contains the row data for the expanded detail view.
@@ -1571,6 +2035,36 @@ declare class GridFormArray implements OnInit, OnDestroy {
1571
2035
  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>;
1572
2036
  }
1573
2037
 
2038
+ /**
2039
+ * Directive that registers `<tbw-grid-header>` as a known Angular element.
2040
+ *
2041
+ * This directive exists so that Angular's template compiler recognises
2042
+ * `<tbw-grid-header>` without requiring `CUSTOM_ELEMENTS_SCHEMA`.
2043
+ * The grid's `config-manager` reads attributes like `title` directly
2044
+ * from the DOM element.
2045
+ *
2046
+ * ## Usage
2047
+ *
2048
+ * ```typescript
2049
+ * import { Component } from '@angular/core';
2050
+ * import { Grid, TbwGridHeader } from '@toolbox-web/grid-angular';
2051
+ *
2052
+ * @Component({
2053
+ * imports: [Grid, TbwGridHeader],
2054
+ * template: `
2055
+ * <tbw-grid [rows]="rows" [gridConfig]="config">
2056
+ * <tbw-grid-header title="My Grid Title"></tbw-grid-header>
2057
+ * </tbw-grid>
2058
+ * `
2059
+ * })
2060
+ * export class MyComponent { }
2061
+ * ```
2062
+ */
2063
+ declare class TbwGridHeader {
2064
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TbwGridHeader, never>;
2065
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TbwGridHeader, "tbw-grid-header", never, {}, {}, never, never, true, never>;
2066
+ }
2067
+
1574
2068
  /**
1575
2069
  * Gets the FormArrayContext from a grid element, if present.
1576
2070
  * @internal
@@ -1836,6 +2330,37 @@ declare class GridResponsiveCard<TRow = unknown> {
1836
2330
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<GridResponsiveCard<any>, "tbw-grid-responsive-card", never, {}, {}, ["template"], never, true, never>;
1837
2331
  }
1838
2332
 
2333
+ /**
2334
+ * Directive that registers `<tbw-grid-tool-buttons>` as a known Angular element.
2335
+ *
2336
+ * This directive exists so that Angular's template compiler recognises
2337
+ * `<tbw-grid-tool-buttons>` without requiring `CUSTOM_ELEMENTS_SCHEMA`.
2338
+ * The grid's shell reads toolbar buttons directly from the DOM.
2339
+ *
2340
+ * ## Usage
2341
+ *
2342
+ * ```typescript
2343
+ * import { Component } from '@angular/core';
2344
+ * import { Grid, TbwGridToolButtons } from '@toolbox-web/grid-angular';
2345
+ *
2346
+ * @Component({
2347
+ * imports: [Grid, TbwGridToolButtons],
2348
+ * template: `
2349
+ * <tbw-grid [rows]="rows" [gridConfig]="config">
2350
+ * <tbw-grid-tool-buttons>
2351
+ * <button (click)="doSomething()">Action</button>
2352
+ * </tbw-grid-tool-buttons>
2353
+ * </tbw-grid>
2354
+ * `
2355
+ * })
2356
+ * export class MyComponent { }
2357
+ * ```
2358
+ */
2359
+ declare class TbwGridToolButtons {
2360
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TbwGridToolButtons, never>;
2361
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TbwGridToolButtons, "tbw-grid-tool-buttons", never, {}, {}, never, never, true, never>;
2362
+ }
2363
+
1839
2364
  /**
1840
2365
  * Context object passed to the tool panel template.
1841
2366
  * Provides access to grid-related information for the panel content.
@@ -1962,13 +2487,12 @@ interface RowCommitEvent<TRow = unknown> {
1962
2487
  * ## Usage
1963
2488
  *
1964
2489
  * ```typescript
1965
- * import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
2490
+ * import { Component } from '@angular/core';
1966
2491
  * import { Grid } from '@toolbox-web/grid-angular';
1967
2492
  *
1968
2493
  * @Component({
1969
2494
  * selector: 'app-root',
1970
2495
  * imports: [Grid],
1971
- * schemas: [CUSTOM_ELEMENTS_SCHEMA],
1972
2496
  * template: `
1973
2497
  * <tbw-grid [rows]="rows" [gridConfig]="config" [customStyles]="myStyles">
1974
2498
  * <!-- column templates -->
@@ -2103,6 +2627,51 @@ declare class Grid implements OnInit, AfterContentInit, OnDestroy {
2103
2627
  * ```
2104
2628
  */
2105
2629
  loading: _angular_core.InputSignal<boolean | undefined>;
2630
+ /**
2631
+ * The data rows to display in the grid.
2632
+ *
2633
+ * Accepts an array of data objects. Each object represents one row.
2634
+ * The grid reads property values for each column's `field` from these objects.
2635
+ *
2636
+ * @example
2637
+ * ```html
2638
+ * <tbw-grid [rows]="employees()" [gridConfig]="config" />
2639
+ * ```
2640
+ */
2641
+ rows: _angular_core.InputSignal<any[] | undefined>;
2642
+ /**
2643
+ * Column configuration array.
2644
+ *
2645
+ * Shorthand for setting columns without wrapping them in a full `gridConfig`.
2646
+ * If both `columns` and `gridConfig.columns` are set, `columns` takes precedence
2647
+ * (see configuration precedence system).
2648
+ *
2649
+ * @example
2650
+ * ```html
2651
+ * <tbw-grid [rows]="data" [columns]="[
2652
+ * { field: 'id', header: 'ID', pinned: 'left', width: 80 },
2653
+ * { field: 'name', header: 'Name' },
2654
+ * { field: 'email', header: 'Email' }
2655
+ * ]" />
2656
+ * ```
2657
+ */
2658
+ columns: _angular_core.InputSignal<ColumnConfig<any>[] | undefined>;
2659
+ /**
2660
+ * Column sizing strategy.
2661
+ *
2662
+ * - `'stretch'` (default) — columns stretch to fill available width
2663
+ * - `'fixed'` — columns use their declared widths; enables horizontal scrolling
2664
+ * - `'auto-fit'` — columns auto-size to content, then stretch to fill
2665
+ *
2666
+ * @default 'stretch'
2667
+ *
2668
+ * @example
2669
+ * ```html
2670
+ * <tbw-grid [rows]="data" fitMode="fixed" />
2671
+ * <tbw-grid [rows]="data" [fitMode]="dynamicMode()" />
2672
+ * ```
2673
+ */
2674
+ fitMode: _angular_core.InputSignal<FitMode | undefined>;
2106
2675
  /**
2107
2676
  * Grid configuration object with optional Angular-specific extensions.
2108
2677
  *
@@ -2314,9 +2883,9 @@ declare class Grid implements OnInit, AfterContentInit, OnDestroy {
2314
2883
  * @example
2315
2884
  * ```html
2316
2885
  * <tbw-grid [pinnedColumns]="true" [columns]="[
2317
- * { field: 'id', sticky: 'left' },
2886
+ * { field: 'id', pinned: 'left' },
2318
2887
  * { field: 'name' },
2319
- * { field: 'actions', sticky: 'right' }
2888
+ * { field: 'actions', pinned: 'right' }
2320
2889
  * ]" />
2321
2890
  * ```
2322
2891
  */
@@ -2781,7 +3350,7 @@ declare class Grid implements OnInit, AfterContentInit, OnDestroy {
2781
3350
  private configureResponsiveCard;
2782
3351
  ngOnDestroy(): void;
2783
3352
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<Grid, never>;
2784
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<Grid, "tbw-grid", never, { "customStyles": { "alias": "customStyles"; "required": false; "isSignal": true; }; "sortable": { "alias": "sortable"; "required": false; "isSignal": true; }; "filterable": { "alias": "filterable"; "required": false; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "gridConfig": { "alias": "gridConfig"; "required": false; "isSignal": true; }; "angularConfig": { "alias": "angularConfig"; "required": false; "isSignal": true; }; "selection": { "alias": "selection"; "required": false; "isSignal": true; }; "editing": { "alias": "editing"; "required": false; "isSignal": true; }; "clipboard": { "alias": "clipboard"; "required": false; "isSignal": true; }; "contextMenu": { "alias": "contextMenu"; "required": false; "isSignal": true; }; "multiSort": { "alias": "multiSort"; "required": false; "isSignal": true; }; "sorting": { "alias": "sorting"; "required": false; "isSignal": true; }; "filtering": { "alias": "filtering"; "required": false; "isSignal": true; }; "reorder": { "alias": "reorder"; "required": false; "isSignal": true; }; "visibility": { "alias": "visibility"; "required": false; "isSignal": true; }; "pinnedColumns": { "alias": "pinnedColumns"; "required": false; "isSignal": true; }; "groupingColumns": { "alias": "groupingColumns"; "required": false; "isSignal": true; }; "columnVirtualization": { "alias": "columnVirtualization"; "required": false; "isSignal": true; }; "rowReorder": { "alias": "rowReorder"; "required": false; "isSignal": true; }; "groupingRows": { "alias": "groupingRows"; "required": false; "isSignal": true; }; "pinnedRows": { "alias": "pinnedRows"; "required": false; "isSignal": true; }; "tree": { "alias": "tree"; "required": false; "isSignal": true; }; "masterDetail": { "alias": "masterDetail"; "required": false; "isSignal": true; }; "responsive": { "alias": "responsive"; "required": false; "isSignal": true; }; "undoRedo": { "alias": "undoRedo"; "required": false; "isSignal": true; }; "exportFeature": { "alias": "export"; "required": false; "isSignal": true; }; "print": { "alias": "print"; "required": false; "isSignal": true; }; "pivot": { "alias": "pivot"; "required": false; "isSignal": true; }; "serverSide": { "alias": "serverSide"; "required": false; "isSignal": true; }; }, { "cellClick": "cellClick"; "rowClick": "rowClick"; "cellActivate": "cellActivate"; "cellChange": "cellChange"; "cellCommit": "cellCommit"; "rowCommit": "rowCommit"; "changedRowsReset": "changedRowsReset"; "sortChange": "sortChange"; "filterChange": "filterChange"; "columnResize": "columnResize"; "columnMove": "columnMove"; "columnVisibility": "columnVisibility"; "columnStateChange": "columnStateChange"; "selectionChange": "selectionChange"; "rowMove": "rowMove"; "groupToggle": "groupToggle"; "treeExpand": "treeExpand"; "detailExpand": "detailExpand"; "responsiveChange": "responsiveChange"; "copy": "copy"; "paste": "paste"; "undoRedoAction": "undoRedoAction"; "exportComplete": "exportComplete"; "printStart": "printStart"; "printComplete": "printComplete"; }, never, never, true, never>;
3353
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<Grid, "tbw-grid", never, { "customStyles": { "alias": "customStyles"; "required": false; "isSignal": true; }; "sortable": { "alias": "sortable"; "required": false; "isSignal": true; }; "filterable": { "alias": "filterable"; "required": false; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "fitMode": { "alias": "fitMode"; "required": false; "isSignal": true; }; "gridConfig": { "alias": "gridConfig"; "required": false; "isSignal": true; }; "angularConfig": { "alias": "angularConfig"; "required": false; "isSignal": true; }; "selection": { "alias": "selection"; "required": false; "isSignal": true; }; "editing": { "alias": "editing"; "required": false; "isSignal": true; }; "clipboard": { "alias": "clipboard"; "required": false; "isSignal": true; }; "contextMenu": { "alias": "contextMenu"; "required": false; "isSignal": true; }; "multiSort": { "alias": "multiSort"; "required": false; "isSignal": true; }; "sorting": { "alias": "sorting"; "required": false; "isSignal": true; }; "filtering": { "alias": "filtering"; "required": false; "isSignal": true; }; "reorder": { "alias": "reorder"; "required": false; "isSignal": true; }; "visibility": { "alias": "visibility"; "required": false; "isSignal": true; }; "pinnedColumns": { "alias": "pinnedColumns"; "required": false; "isSignal": true; }; "groupingColumns": { "alias": "groupingColumns"; "required": false; "isSignal": true; }; "columnVirtualization": { "alias": "columnVirtualization"; "required": false; "isSignal": true; }; "rowReorder": { "alias": "rowReorder"; "required": false; "isSignal": true; }; "groupingRows": { "alias": "groupingRows"; "required": false; "isSignal": true; }; "pinnedRows": { "alias": "pinnedRows"; "required": false; "isSignal": true; }; "tree": { "alias": "tree"; "required": false; "isSignal": true; }; "masterDetail": { "alias": "masterDetail"; "required": false; "isSignal": true; }; "responsive": { "alias": "responsive"; "required": false; "isSignal": true; }; "undoRedo": { "alias": "undoRedo"; "required": false; "isSignal": true; }; "exportFeature": { "alias": "export"; "required": false; "isSignal": true; }; "print": { "alias": "print"; "required": false; "isSignal": true; }; "pivot": { "alias": "pivot"; "required": false; "isSignal": true; }; "serverSide": { "alias": "serverSide"; "required": false; "isSignal": true; }; }, { "cellClick": "cellClick"; "rowClick": "rowClick"; "cellActivate": "cellActivate"; "cellChange": "cellChange"; "cellCommit": "cellCommit"; "rowCommit": "rowCommit"; "changedRowsReset": "changedRowsReset"; "sortChange": "sortChange"; "filterChange": "filterChange"; "columnResize": "columnResize"; "columnMove": "columnMove"; "columnVisibility": "columnVisibility"; "columnStateChange": "columnStateChange"; "selectionChange": "selectionChange"; "rowMove": "rowMove"; "groupToggle": "groupToggle"; "treeExpand": "treeExpand"; "detailExpand": "detailExpand"; "responsiveChange": "responsiveChange"; "copy": "copy"; "paste": "paste"; "undoRedoAction": "undoRedoAction"; "exportComplete": "exportComplete"; "printStart": "printStart"; "printComplete": "printComplete"; }, never, never, true, never>;
2785
3354
  }
2786
3355
 
2787
3356
  /**
@@ -2950,6 +3519,6 @@ declare class TbwEditor implements OnDestroy {
2950
3519
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TbwEditor, "[tbwEditor]", never, {}, {}, never, never, true, never>;
2951
3520
  }
2952
3521
 
2953
- export { AngularGridAdapter, BaseGridEditor, GRID_ICONS, GRID_TYPE_DEFAULTS, Grid, GridAdapter, GridColumnEditor, GridColumnView, GridDetailView, GridFormArray, GridIconRegistry, GridLazyForm, GridResponsiveCard, GridToolPanel, GridTypeRegistry, TbwEditor as TbwCellEditor, TbwRenderer as TbwCellView, TbwEditor, TbwRenderer, clearFeatureRegistry, createPluginFromFeature, getFeatureFactory, getFormArrayContext, getLazyFormContext, getRegisteredFeatures, injectGrid, isComponentClass, isFeatureRegistered, provideGridIcons, provideGridTypeDefaults, registerFeature };
2954
- export type { AngularCellEditor, AngularCellRenderer, AngularColumnConfig, AngularGridConfig, AngularTypeDefault, CellCommitEvent, CellEditor, CellRenderer, ColumnConfig, ExportMethods, FeatureName, FilterPanel, FormArrayContext, GridCellContext, GridConfig, GridDetailContext, GridEditorContext, GridResponsiveCardContext, GridToolPanelContext, InjectGridReturn, LazyFormFactory, PluginFactory, RowCommitEvent, RowFormChangeEvent, SelectionMethods, StructuralCellContext, StructuralEditorContext, TypeDefault, TypeDefaultRegistration };
3522
+ export { AngularGridAdapter, BaseFilterPanel, BaseGridEditor, BaseGridEditorCVA, BaseOverlayEditor, GRID_ICONS, GRID_TYPE_DEFAULTS, Grid, GridAdapter, GridColumnEditor, GridColumnView, GridDetailView, GridFormArray, GridIconRegistry, GridLazyForm, GridResponsiveCard, GridToolPanel, GridTypeRegistry, TbwEditor as TbwCellEditor, TbwRenderer as TbwCellView, TbwEditor, TbwGridColumn, TbwGridHeader, TbwGridToolButtons, TbwRenderer, clearFeatureRegistry, createPluginFromFeature, getFeatureFactory, getFormArrayContext, getLazyFormContext, getRegisteredFeatures, injectGrid, isComponentClass, isFeatureRegistered, provideGridIcons, provideGridTypeDefaults, registerFeature };
3523
+ export type { AngularCellEditor, AngularCellRenderer, AngularColumnConfig, AngularGridConfig, AngularTypeDefault, CellCommitEvent, CellEditor, CellRenderer, ColumnConfig, ExportMethods, FeatureName, FilterPanel, FormArrayContext, GridCellContext, GridConfig, GridDetailContext, GridEditorContext, GridResponsiveCardContext, GridToolPanelContext, InjectGridReturn, LazyFormFactory, OverlayPosition, PluginFactory, RowCommitEvent, RowFormChangeEvent, SelectionMethods, StructuralCellContext, StructuralEditorContext, TypeDefault, TypeDefaultRegistration };
2955
3524
  //# sourceMappingURL=toolbox-web-grid-angular.d.ts.map