@toolbox-web/grid-angular 0.12.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -0
- package/fesm2022/toolbox-web-grid-angular-features-export.mjs +16 -1
- package/fesm2022/toolbox-web-grid-angular-features-export.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-filtering.mjs +16 -1
- package/fesm2022/toolbox-web-grid-angular-features-filtering.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-pinned-columns.mjs +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-pinned-columns.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-print.mjs +16 -1
- package/fesm2022/toolbox-web-grid-angular-features-print.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-selection.mjs +35 -1
- package/fesm2022/toolbox-web-grid-angular-features-selection.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular-features-undo-redo.mjs +63 -5
- package/fesm2022/toolbox-web-grid-angular-features-undo-redo.mjs.map +1 -1
- package/fesm2022/toolbox-web-grid-angular.mjs +899 -7
- package/fesm2022/toolbox-web-grid-angular.mjs.map +1 -1
- package/package.json +1 -1
- package/types/toolbox-web-grid-angular-features-undo-redo.d.ts +24 -4
- package/types/toolbox-web-grid-angular-features-undo-redo.d.ts.map +1 -1
- package/types/toolbox-web-grid-angular.d.ts +563 -9
- package/types/toolbox-web-grid-angular.d.ts.map +1 -1
|
@@ -2429,6 +2429,94 @@ function clearFeatureRegistry() {
|
|
|
2429
2429
|
warnedFeatures.clear();
|
|
2430
2430
|
}
|
|
2431
2431
|
|
|
2432
|
+
/**
|
|
2433
|
+
* Base class for Angular filter panel components.
|
|
2434
|
+
*
|
|
2435
|
+
* Provides a ready-made `params` input and common lifecycle helpers
|
|
2436
|
+
* (`applyAndClose`, `clearAndClose`) so consumers only need to implement
|
|
2437
|
+
* their filter logic in `applyFilter()`.
|
|
2438
|
+
*
|
|
2439
|
+
* ## Usage
|
|
2440
|
+
*
|
|
2441
|
+
* ```typescript
|
|
2442
|
+
* import { Component } from '@angular/core';
|
|
2443
|
+
* import { BaseFilterPanel } from '@toolbox-web/grid-angular';
|
|
2444
|
+
*
|
|
2445
|
+
* @Component({
|
|
2446
|
+
* selector: 'app-text-filter',
|
|
2447
|
+
* template: `
|
|
2448
|
+
* <input #input (keydown.enter)="applyAndClose()" />
|
|
2449
|
+
* <button (click)="applyAndClose()">Apply</button>
|
|
2450
|
+
* <button (click)="clearAndClose()">Clear</button>
|
|
2451
|
+
* `
|
|
2452
|
+
* })
|
|
2453
|
+
* export class TextFilterComponent extends BaseFilterPanel {
|
|
2454
|
+
* @ViewChild('input') input!: ElementRef<HTMLInputElement>;
|
|
2455
|
+
*
|
|
2456
|
+
* applyFilter(): void {
|
|
2457
|
+
* this.params().applyTextFilter('contains', this.input.nativeElement.value);
|
|
2458
|
+
* }
|
|
2459
|
+
* }
|
|
2460
|
+
* ```
|
|
2461
|
+
*
|
|
2462
|
+
* ## Template Syntax
|
|
2463
|
+
*
|
|
2464
|
+
* The grid's filtering plugin will mount this component and provide `params`
|
|
2465
|
+
* automatically. No manual wiring is required:
|
|
2466
|
+
*
|
|
2467
|
+
* ```typescript
|
|
2468
|
+
* gridConfig = {
|
|
2469
|
+
* columns: [
|
|
2470
|
+
* { field: 'name', filterable: true, filterPanel: TextFilterComponent },
|
|
2471
|
+
* ],
|
|
2472
|
+
* };
|
|
2473
|
+
* ```
|
|
2474
|
+
*
|
|
2475
|
+
* @typeParam TRow - The row data type (available via `params().column`)
|
|
2476
|
+
*/
|
|
2477
|
+
class BaseFilterPanel {
|
|
2478
|
+
/**
|
|
2479
|
+
* Filter panel parameters injected by the grid's filtering plugin.
|
|
2480
|
+
*
|
|
2481
|
+
* Provides access to:
|
|
2482
|
+
* - `field` — the column field name
|
|
2483
|
+
* - `column` — full column configuration
|
|
2484
|
+
* - `uniqueValues` — distinct values in the column
|
|
2485
|
+
* - `excludedValues` — currently excluded values (set filter)
|
|
2486
|
+
* - `searchText` — current search text
|
|
2487
|
+
* - `applySetFilter(excluded)` — apply a set-based (include/exclude) filter
|
|
2488
|
+
* - `applyTextFilter(operator, value, valueTo?)` — apply a text/number filter
|
|
2489
|
+
* - `clearFilter()` — clear the filter for this column
|
|
2490
|
+
* - `closePanel()` — close the filter panel
|
|
2491
|
+
*/
|
|
2492
|
+
params = input.required(...(ngDevMode ? [{ debugName: "params" }] : []));
|
|
2493
|
+
/**
|
|
2494
|
+
* Apply the filter then close the panel.
|
|
2495
|
+
*
|
|
2496
|
+
* Calls {@link applyFilter} followed by `params().closePanel()`.
|
|
2497
|
+
* Bind this to your "Apply" button or Enter key handler.
|
|
2498
|
+
*/
|
|
2499
|
+
applyAndClose() {
|
|
2500
|
+
this.applyFilter();
|
|
2501
|
+
this.params().closePanel();
|
|
2502
|
+
}
|
|
2503
|
+
/**
|
|
2504
|
+
* Clear the filter then close the panel.
|
|
2505
|
+
*
|
|
2506
|
+
* Calls `params().clearFilter()` followed by `params().closePanel()`.
|
|
2507
|
+
* Bind this to your "Clear" / "Reset" button.
|
|
2508
|
+
*/
|
|
2509
|
+
clearAndClose() {
|
|
2510
|
+
this.params().clearFilter();
|
|
2511
|
+
this.params().closePanel();
|
|
2512
|
+
}
|
|
2513
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: BaseFilterPanel, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2514
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: BaseFilterPanel, isStandalone: true, inputs: { params: { classPropertyName: "params", publicName: "params", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
|
|
2515
|
+
}
|
|
2516
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: BaseFilterPanel, decorators: [{
|
|
2517
|
+
type: Directive
|
|
2518
|
+
}], propDecorators: { params: [{ type: i0.Input, args: [{ isSignal: true, alias: "params", required: true }] }] } });
|
|
2519
|
+
|
|
2432
2520
|
/**
|
|
2433
2521
|
* Base class for grid cell editors.
|
|
2434
2522
|
*
|
|
@@ -2699,6 +2787,703 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
|
|
|
2699
2787
|
type: Directive
|
|
2700
2788
|
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: false }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: false }] }], control: [{ type: i0.Input, args: [{ isSignal: true, alias: "control", required: false }] }], commit: [{ type: i0.Output, args: ["commit"] }], cancel: [{ type: i0.Output, args: ["cancel"] }] } });
|
|
2701
2789
|
|
|
2790
|
+
/**
|
|
2791
|
+
* Base class for grid editors that also work as Angular form controls.
|
|
2792
|
+
*
|
|
2793
|
+
* Combines `BaseGridEditor` with `ControlValueAccessor` so the same component
|
|
2794
|
+
* can be used inside a `<tbw-grid>` **and** in a standalone `<form>`.
|
|
2795
|
+
*
|
|
2796
|
+
* ## What it provides
|
|
2797
|
+
*
|
|
2798
|
+
* | Member | Purpose |
|
|
2799
|
+
* |--------|---------|
|
|
2800
|
+
* | `cvaValue` | Signal holding the value written by the form control |
|
|
2801
|
+
* | `disabledState` | Signal tracking `setDisabledState` calls |
|
|
2802
|
+
* | `displayValue` | Computed that prefers grid value (`currentValue`) and falls back to `cvaValue` |
|
|
2803
|
+
* | `commitBoth(v)` | Commits via both CVA `onChange` and grid `commitValue` |
|
|
2804
|
+
* | `writeValue` / `registerOn*` / `setDisabledState` | Full CVA implementation |
|
|
2805
|
+
*
|
|
2806
|
+
* ## Usage
|
|
2807
|
+
*
|
|
2808
|
+
* ```typescript
|
|
2809
|
+
* import { Component, forwardRef } from '@angular/core';
|
|
2810
|
+
* import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
2811
|
+
* import { BaseGridEditorCVA } from '@toolbox-web/grid-angular';
|
|
2812
|
+
*
|
|
2813
|
+
* @Component({
|
|
2814
|
+
* selector: 'app-date-picker',
|
|
2815
|
+
* providers: [{
|
|
2816
|
+
* provide: NG_VALUE_ACCESSOR,
|
|
2817
|
+
* useExisting: forwardRef(() => DatePickerComponent),
|
|
2818
|
+
* multi: true,
|
|
2819
|
+
* }],
|
|
2820
|
+
* template: `
|
|
2821
|
+
* <input
|
|
2822
|
+
* type="date"
|
|
2823
|
+
* [value]="displayValue()"
|
|
2824
|
+
* [disabled]="disabledState()"
|
|
2825
|
+
* (change)="commitBoth($event.target.value)"
|
|
2826
|
+
* (keydown.escape)="cancelEdit()"
|
|
2827
|
+
* />
|
|
2828
|
+
* `
|
|
2829
|
+
* })
|
|
2830
|
+
* export class DatePickerComponent extends BaseGridEditorCVA<MyRow, string> {}
|
|
2831
|
+
* ```
|
|
2832
|
+
*
|
|
2833
|
+
* > **Note:** Subclasses must still provide `NG_VALUE_ACCESSOR` themselves
|
|
2834
|
+
* > because `forwardRef(() => ConcreteClass)` must reference the concrete
|
|
2835
|
+
* > component — this is an Angular limitation.
|
|
2836
|
+
*
|
|
2837
|
+
* @typeParam TRow - The row data type
|
|
2838
|
+
* @typeParam TValue - The cell/control value type
|
|
2839
|
+
*/
|
|
2840
|
+
class BaseGridEditorCVA extends BaseGridEditor {
|
|
2841
|
+
// ============================================================================
|
|
2842
|
+
// CVA State
|
|
2843
|
+
// ============================================================================
|
|
2844
|
+
/** Internal onChange callback registered by the form control. */
|
|
2845
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
2846
|
+
_onChange = () => { };
|
|
2847
|
+
/** Internal onTouched callback registered by the form control. */
|
|
2848
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
2849
|
+
_onTouched = () => { };
|
|
2850
|
+
/**
|
|
2851
|
+
* Signal holding the value written by the form control via `writeValue()`.
|
|
2852
|
+
* Updated when the form control pushes a new value (e.g. `patchValue`, `setValue`).
|
|
2853
|
+
*/
|
|
2854
|
+
cvaValue = signal(null, ...(ngDevMode ? [{ debugName: "cvaValue" }] : []));
|
|
2855
|
+
/**
|
|
2856
|
+
* Signal tracking the disabled state set by the form control.
|
|
2857
|
+
* Updated when `setDisabledState()` is called by Angular's forms module.
|
|
2858
|
+
*/
|
|
2859
|
+
disabledState = signal(false, ...(ngDevMode ? [{ debugName: "disabledState" }] : []));
|
|
2860
|
+
/**
|
|
2861
|
+
* Resolved display value.
|
|
2862
|
+
*
|
|
2863
|
+
* Prefers `currentValue()` (grid context — from `control.value` or `value` input)
|
|
2864
|
+
* and falls back to `cvaValue()` (standalone form context — from `writeValue`).
|
|
2865
|
+
*
|
|
2866
|
+
* Use this in your template instead of reading `currentValue()` directly
|
|
2867
|
+
* so the component works in both grid and standalone form contexts.
|
|
2868
|
+
*/
|
|
2869
|
+
displayValue = computed(() => {
|
|
2870
|
+
return this.currentValue() ?? this.cvaValue();
|
|
2871
|
+
}, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
|
|
2872
|
+
// ============================================================================
|
|
2873
|
+
// ControlValueAccessor Implementation
|
|
2874
|
+
// ============================================================================
|
|
2875
|
+
/**
|
|
2876
|
+
* Called by Angular forms when the form control value changes programmatically.
|
|
2877
|
+
*/
|
|
2878
|
+
writeValue(value) {
|
|
2879
|
+
this.cvaValue.set(value);
|
|
2880
|
+
}
|
|
2881
|
+
/**
|
|
2882
|
+
* Called by Angular forms to register a change callback.
|
|
2883
|
+
*/
|
|
2884
|
+
registerOnChange(fn) {
|
|
2885
|
+
this._onChange = fn;
|
|
2886
|
+
}
|
|
2887
|
+
/**
|
|
2888
|
+
* Called by Angular forms to register a touched callback.
|
|
2889
|
+
*/
|
|
2890
|
+
registerOnTouched(fn) {
|
|
2891
|
+
this._onTouched = fn;
|
|
2892
|
+
}
|
|
2893
|
+
/**
|
|
2894
|
+
* Called by Angular forms to set the disabled state.
|
|
2895
|
+
*/
|
|
2896
|
+
setDisabledState(isDisabled) {
|
|
2897
|
+
this.disabledState.set(isDisabled);
|
|
2898
|
+
}
|
|
2899
|
+
// ============================================================================
|
|
2900
|
+
// Dual-Commit Helpers
|
|
2901
|
+
// ============================================================================
|
|
2902
|
+
/**
|
|
2903
|
+
* Commit a value through both the CVA (form control) and the grid.
|
|
2904
|
+
*
|
|
2905
|
+
* - Calls the CVA `onChange` callback (updates the form control)
|
|
2906
|
+
* - Marks the control as touched
|
|
2907
|
+
* - Calls `commitValue()` (emits grid commit event + DOM `CustomEvent`)
|
|
2908
|
+
*
|
|
2909
|
+
* Use this instead of `commitValue()` when your editor doubles as a form control.
|
|
2910
|
+
*
|
|
2911
|
+
* @param value - The new value to commit
|
|
2912
|
+
*/
|
|
2913
|
+
commitBoth(value) {
|
|
2914
|
+
// Update CVA
|
|
2915
|
+
this.cvaValue.set(value);
|
|
2916
|
+
this._onChange(value);
|
|
2917
|
+
this._onTouched();
|
|
2918
|
+
// Update grid
|
|
2919
|
+
if (value != null) {
|
|
2920
|
+
this.commitValue(value);
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: BaseGridEditorCVA, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
2924
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: BaseGridEditorCVA, isStandalone: true, usesInheritance: true, ngImport: i0 });
|
|
2925
|
+
}
|
|
2926
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: BaseGridEditorCVA, decorators: [{
|
|
2927
|
+
type: Directive
|
|
2928
|
+
}] });
|
|
2929
|
+
|
|
2930
|
+
// #endregion
|
|
2931
|
+
// #region Global Styles
|
|
2932
|
+
/** Tracks whether the global overlay stylesheet has been injected. */
|
|
2933
|
+
let overlayStylesInjected = false;
|
|
2934
|
+
/**
|
|
2935
|
+
* CSS for the overlay panel base layer.
|
|
2936
|
+
* Injected once into `<head>` on first `BaseOverlayEditor` use.
|
|
2937
|
+
*
|
|
2938
|
+
* Uses CSS Anchor Positioning as primary strategy with a JS fallback
|
|
2939
|
+
* for browsers that don't support it (Firefox, Safari as of late 2025).
|
|
2940
|
+
*/
|
|
2941
|
+
const OVERLAY_STYLES = /* css */ `
|
|
2942
|
+
.tbw-overlay-panel {
|
|
2943
|
+
position: fixed;
|
|
2944
|
+
z-index: 10000;
|
|
2945
|
+
background: var(--tbw-overlay-bg, #fff);
|
|
2946
|
+
border: 1px solid var(--tbw-overlay-border, #ccc);
|
|
2947
|
+
border-radius: var(--tbw-overlay-radius, 4px);
|
|
2948
|
+
box-shadow: var(--tbw-overlay-shadow, 0 4px 12px rgba(0, 0, 0, 0.15));
|
|
2949
|
+
box-sizing: border-box;
|
|
2950
|
+
overflow: auto;
|
|
2951
|
+
}
|
|
2952
|
+
|
|
2953
|
+
.tbw-overlay-panel:popover-open {
|
|
2954
|
+
display: block;
|
|
2955
|
+
}
|
|
2956
|
+
|
|
2957
|
+
@supports (anchor-name: --a) {
|
|
2958
|
+
.tbw-overlay-panel[data-anchor-id] {
|
|
2959
|
+
position: fixed;
|
|
2960
|
+
position-anchor: var(--tbw-overlay-anchor);
|
|
2961
|
+
inset: unset;
|
|
2962
|
+
}
|
|
2963
|
+
.tbw-overlay-panel[data-pos="below"] {
|
|
2964
|
+
top: anchor(bottom);
|
|
2965
|
+
left: anchor(left);
|
|
2966
|
+
position-try-fallbacks: flip-block;
|
|
2967
|
+
}
|
|
2968
|
+
.tbw-overlay-panel[data-pos="above"] {
|
|
2969
|
+
bottom: anchor(top);
|
|
2970
|
+
left: anchor(left);
|
|
2971
|
+
position-try-fallbacks: flip-block;
|
|
2972
|
+
}
|
|
2973
|
+
.tbw-overlay-panel[data-pos="below-right"] {
|
|
2974
|
+
top: anchor(bottom);
|
|
2975
|
+
right: anchor(right);
|
|
2976
|
+
position-try-fallbacks: flip-block;
|
|
2977
|
+
}
|
|
2978
|
+
.tbw-overlay-panel[data-pos="over-left"] {
|
|
2979
|
+
top: anchor(top);
|
|
2980
|
+
left: anchor(left);
|
|
2981
|
+
}
|
|
2982
|
+
}
|
|
2983
|
+
`;
|
|
2984
|
+
function ensureOverlayStyles() {
|
|
2985
|
+
if (overlayStylesInjected)
|
|
2986
|
+
return;
|
|
2987
|
+
overlayStylesInjected = true;
|
|
2988
|
+
const style = document.createElement('style');
|
|
2989
|
+
style.setAttribute('data-tbw-overlay', '');
|
|
2990
|
+
style.textContent = OVERLAY_STYLES;
|
|
2991
|
+
document.head.appendChild(style);
|
|
2992
|
+
}
|
|
2993
|
+
// #endregion
|
|
2994
|
+
// #region Anchor ID Counter
|
|
2995
|
+
let anchorCounter = 0;
|
|
2996
|
+
// #endregion
|
|
2997
|
+
/**
|
|
2998
|
+
* Base class for grid editors that display a floating overlay panel.
|
|
2999
|
+
*
|
|
3000
|
+
* Provides infrastructure for:
|
|
3001
|
+
* - **Overlay positioning** — CSS Anchor Positioning with JS fallback
|
|
3002
|
+
* - **Focus gating** — in row editing mode, the panel only opens for the focused cell
|
|
3003
|
+
* - **Click-outside detection** — closes the panel when clicking outside
|
|
3004
|
+
* - **MutationObserver** — detects cell focus changes (row editing mode)
|
|
3005
|
+
* - **Escape handling** — closes the panel and returns focus to the inline input
|
|
3006
|
+
* - **Synthetic Tab dispatch** — advances grid focus after overlay close
|
|
3007
|
+
* - **Automatic teardown** — removes the panel from `<body>` and cleans up listeners
|
|
3008
|
+
*
|
|
3009
|
+
* ## Usage
|
|
3010
|
+
*
|
|
3011
|
+
* ```typescript
|
|
3012
|
+
* import { Component, ViewChild, ElementRef } from '@angular/core';
|
|
3013
|
+
* import { BaseOverlayEditor } from '@toolbox-web/grid-angular';
|
|
3014
|
+
*
|
|
3015
|
+
* @Component({
|
|
3016
|
+
* selector: 'app-date-editor',
|
|
3017
|
+
* template: `
|
|
3018
|
+
* <input
|
|
3019
|
+
* #inlineInput
|
|
3020
|
+
* readonly
|
|
3021
|
+
* [value]="currentValue()"
|
|
3022
|
+
* (click)="onInlineClick()"
|
|
3023
|
+
* (keydown)="onInlineKeydown($event)"
|
|
3024
|
+
* />
|
|
3025
|
+
* <div #panel class="tbw-overlay-panel" style="width: 280px;">
|
|
3026
|
+
* <!-- your date picker UI here -->
|
|
3027
|
+
* <div class="actions">
|
|
3028
|
+
* <button (click)="selectAndClose(selectedDate)">OK</button>
|
|
3029
|
+
* <button (click)="hideOverlay()">Cancel</button>
|
|
3030
|
+
* </div>
|
|
3031
|
+
* </div>
|
|
3032
|
+
* `
|
|
3033
|
+
* })
|
|
3034
|
+
* export class DateEditorComponent extends BaseOverlayEditor<MyRow, string> {
|
|
3035
|
+
* @ViewChild('panel') panelRef!: ElementRef<HTMLElement>;
|
|
3036
|
+
* @ViewChild('inlineInput') inputRef!: ElementRef<HTMLInputElement>;
|
|
3037
|
+
*
|
|
3038
|
+
* protected override overlayPosition = 'below' as const;
|
|
3039
|
+
*
|
|
3040
|
+
* ngAfterViewInit(): void {
|
|
3041
|
+
* this.initOverlay(this.panelRef.nativeElement);
|
|
3042
|
+
* if (this.isCellFocused()) this.showOverlay();
|
|
3043
|
+
* }
|
|
3044
|
+
*
|
|
3045
|
+
* protected getInlineInput(): HTMLInputElement | null {
|
|
3046
|
+
* return this.inputRef?.nativeElement ?? null;
|
|
3047
|
+
* }
|
|
3048
|
+
*
|
|
3049
|
+
* protected onOverlayOutsideClick(): void {
|
|
3050
|
+
* this.hideOverlay();
|
|
3051
|
+
* }
|
|
3052
|
+
*
|
|
3053
|
+
* selectAndClose(date: string): void {
|
|
3054
|
+
* this.commitValue(date);
|
|
3055
|
+
* this.hideOverlay();
|
|
3056
|
+
* }
|
|
3057
|
+
* }
|
|
3058
|
+
* ```
|
|
3059
|
+
*
|
|
3060
|
+
* @typeParam TRow - The row data type
|
|
3061
|
+
* @typeParam TValue - The cell value type
|
|
3062
|
+
*/
|
|
3063
|
+
class BaseOverlayEditor extends BaseGridEditor {
|
|
3064
|
+
_elementRef = inject(ElementRef);
|
|
3065
|
+
_overlayDestroyRef = inject(DestroyRef);
|
|
3066
|
+
// ============================================================================
|
|
3067
|
+
// Configuration
|
|
3068
|
+
// ============================================================================
|
|
3069
|
+
/**
|
|
3070
|
+
* Position of the overlay panel relative to the anchor cell.
|
|
3071
|
+
* Override in subclasses to change the default position.
|
|
3072
|
+
*
|
|
3073
|
+
* @default 'below'
|
|
3074
|
+
*/
|
|
3075
|
+
overlayPosition = 'below';
|
|
3076
|
+
// ============================================================================
|
|
3077
|
+
// Internal State
|
|
3078
|
+
// ============================================================================
|
|
3079
|
+
/** The overlay panel element (set via `initOverlay()`). */
|
|
3080
|
+
_panel = null;
|
|
3081
|
+
/** Whether the overlay is currently visible. */
|
|
3082
|
+
_isOpen = false;
|
|
3083
|
+
/** Unique anchor ID for CSS Anchor Positioning. */
|
|
3084
|
+
_anchorId = '';
|
|
3085
|
+
/** Whether the browser supports CSS Anchor Positioning. */
|
|
3086
|
+
_supportsAnchor = false;
|
|
3087
|
+
/** AbortController for all overlay-related listeners. */
|
|
3088
|
+
_abortCtrl = null;
|
|
3089
|
+
/** MutationObserver watching cell focus class changes. */
|
|
3090
|
+
_focusObserver = null;
|
|
3091
|
+
// ============================================================================
|
|
3092
|
+
// Lifecycle
|
|
3093
|
+
// ============================================================================
|
|
3094
|
+
constructor() {
|
|
3095
|
+
super();
|
|
3096
|
+
this._supportsAnchor = typeof CSS !== 'undefined' && CSS.supports('anchor-name', '--a');
|
|
3097
|
+
ensureOverlayStyles();
|
|
3098
|
+
afterNextRender(() => this._setupFocusObserver());
|
|
3099
|
+
this._overlayDestroyRef.onDestroy(() => this.teardownOverlay());
|
|
3100
|
+
}
|
|
3101
|
+
// ============================================================================
|
|
3102
|
+
// Public API — Subclass Interface
|
|
3103
|
+
// ============================================================================
|
|
3104
|
+
/**
|
|
3105
|
+
* Initialise the overlay with the panel element.
|
|
3106
|
+
*
|
|
3107
|
+
* Call this in `ngAfterViewInit` with your `@ViewChild` panel reference.
|
|
3108
|
+
* The panel is moved to `<body>` and hidden until {@link showOverlay} is called.
|
|
3109
|
+
*
|
|
3110
|
+
* @param panel - The overlay panel DOM element
|
|
3111
|
+
*/
|
|
3112
|
+
initOverlay(panel) {
|
|
3113
|
+
this._panel = panel;
|
|
3114
|
+
// Assign a unique anchor ID
|
|
3115
|
+
this._anchorId = `tbw-anchor-${++anchorCounter}`;
|
|
3116
|
+
panel.classList.add('tbw-overlay-panel');
|
|
3117
|
+
panel.setAttribute('data-pos', this.overlayPosition);
|
|
3118
|
+
panel.setAttribute('data-anchor-id', this._anchorId);
|
|
3119
|
+
panel.style.display = 'none';
|
|
3120
|
+
// Set up CSS Anchor Positioning on the cell
|
|
3121
|
+
if (this._supportsAnchor) {
|
|
3122
|
+
const cell = this._getCell();
|
|
3123
|
+
if (cell) {
|
|
3124
|
+
cell.style.setProperty('anchor-name', `--${this._anchorId}`);
|
|
3125
|
+
panel.style.setProperty('--tbw-overlay-anchor', `--${this._anchorId}`);
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
3128
|
+
// Move panel to body so it escapes grid overflow clipping
|
|
3129
|
+
document.body.appendChild(panel);
|
|
3130
|
+
// Set up click-outside detection
|
|
3131
|
+
this._abortCtrl = new AbortController();
|
|
3132
|
+
document.addEventListener('pointerdown', (e) => this._onDocumentPointerDown(e), {
|
|
3133
|
+
signal: this._abortCtrl.signal,
|
|
3134
|
+
});
|
|
3135
|
+
}
|
|
3136
|
+
/**
|
|
3137
|
+
* Show the overlay panel.
|
|
3138
|
+
*
|
|
3139
|
+
* If CSS Anchor Positioning is not supported, falls back to JS-based
|
|
3140
|
+
* positioning using `getBoundingClientRect()`.
|
|
3141
|
+
*/
|
|
3142
|
+
showOverlay() {
|
|
3143
|
+
if (!this._panel || this._isOpen)
|
|
3144
|
+
return;
|
|
3145
|
+
this._isOpen = true;
|
|
3146
|
+
this._panel.style.display = '';
|
|
3147
|
+
// JS fallback positioning for browsers without CSS Anchor Positioning
|
|
3148
|
+
if (!this._supportsAnchor) {
|
|
3149
|
+
this._positionWithJs();
|
|
3150
|
+
}
|
|
3151
|
+
}
|
|
3152
|
+
/**
|
|
3153
|
+
* Hide the overlay panel.
|
|
3154
|
+
*
|
|
3155
|
+
* @param suppressTabAdvance - When `true`, skip synthetic Tab dispatch
|
|
3156
|
+
* (useful when hiding is triggered by an external focus change).
|
|
3157
|
+
*/
|
|
3158
|
+
hideOverlay(suppressTabAdvance) {
|
|
3159
|
+
if (!this._panel || !this._isOpen)
|
|
3160
|
+
return;
|
|
3161
|
+
this._isOpen = false;
|
|
3162
|
+
this._panel.style.display = 'none';
|
|
3163
|
+
if (!suppressTabAdvance) {
|
|
3164
|
+
this.getInlineInput()?.focus();
|
|
3165
|
+
}
|
|
3166
|
+
}
|
|
3167
|
+
/**
|
|
3168
|
+
* Close and immediately re-open the overlay.
|
|
3169
|
+
* Useful after the panel content changes size and needs repositioning.
|
|
3170
|
+
*/
|
|
3171
|
+
reopenOverlay() {
|
|
3172
|
+
if (!this._panel)
|
|
3173
|
+
return;
|
|
3174
|
+
this._isOpen = false;
|
|
3175
|
+
this._panel.style.display = 'none';
|
|
3176
|
+
this.showOverlay();
|
|
3177
|
+
}
|
|
3178
|
+
/**
|
|
3179
|
+
* Remove the overlay from the DOM and clean up all listeners.
|
|
3180
|
+
*
|
|
3181
|
+
* Called automatically on `DestroyRef.onDestroy`. Can also be called
|
|
3182
|
+
* manually if the editor needs early cleanup.
|
|
3183
|
+
*/
|
|
3184
|
+
teardownOverlay() {
|
|
3185
|
+
this._abortCtrl?.abort();
|
|
3186
|
+
this._abortCtrl = null;
|
|
3187
|
+
this._focusObserver?.disconnect();
|
|
3188
|
+
this._focusObserver = null;
|
|
3189
|
+
if (this._panel?.parentNode) {
|
|
3190
|
+
this._panel.parentNode.removeChild(this._panel);
|
|
3191
|
+
}
|
|
3192
|
+
this._panel = null;
|
|
3193
|
+
this._isOpen = false;
|
|
3194
|
+
// Clean up anchor-name on the cell
|
|
3195
|
+
if (this._supportsAnchor) {
|
|
3196
|
+
const cell = this._getCell();
|
|
3197
|
+
if (cell) {
|
|
3198
|
+
cell.style.removeProperty('anchor-name');
|
|
3199
|
+
}
|
|
3200
|
+
}
|
|
3201
|
+
}
|
|
3202
|
+
/**
|
|
3203
|
+
* Override in `edit-close` handler to also hide the overlay.
|
|
3204
|
+
* This is called automatically by `BaseGridEditor` when the grid
|
|
3205
|
+
* ends the editing session.
|
|
3206
|
+
*/
|
|
3207
|
+
onEditClose() {
|
|
3208
|
+
this.hideOverlay(true);
|
|
3209
|
+
}
|
|
3210
|
+
// ============================================================================
|
|
3211
|
+
// Keyboard & Click Helpers
|
|
3212
|
+
// ============================================================================
|
|
3213
|
+
/**
|
|
3214
|
+
* Keydown handler for the inline readonly input.
|
|
3215
|
+
*
|
|
3216
|
+
* - **Enter / Space / ArrowDown / F2** → open overlay
|
|
3217
|
+
* - **Escape** → calls {@link handleEscape}
|
|
3218
|
+
*
|
|
3219
|
+
* Bind this to `(keydown)` on your inline input element.
|
|
3220
|
+
*/
|
|
3221
|
+
onInlineKeydown(event) {
|
|
3222
|
+
switch (event.key) {
|
|
3223
|
+
case 'Enter':
|
|
3224
|
+
case ' ':
|
|
3225
|
+
case 'ArrowDown':
|
|
3226
|
+
case 'F2':
|
|
3227
|
+
event.preventDefault();
|
|
3228
|
+
this.showOverlay();
|
|
3229
|
+
this.onOverlayOpened();
|
|
3230
|
+
break;
|
|
3231
|
+
case 'Escape':
|
|
3232
|
+
this.handleEscape(event);
|
|
3233
|
+
break;
|
|
3234
|
+
}
|
|
3235
|
+
}
|
|
3236
|
+
/**
|
|
3237
|
+
* Click handler for the inline input.
|
|
3238
|
+
* Opens the overlay and calls {@link onOverlayOpened}.
|
|
3239
|
+
*
|
|
3240
|
+
* Bind this to `(click)` on your inline input element.
|
|
3241
|
+
*/
|
|
3242
|
+
onInlineClick() {
|
|
3243
|
+
if (this._isOpen) {
|
|
3244
|
+
this.hideOverlay();
|
|
3245
|
+
}
|
|
3246
|
+
else {
|
|
3247
|
+
this.showOverlay();
|
|
3248
|
+
this.onOverlayOpened();
|
|
3249
|
+
}
|
|
3250
|
+
}
|
|
3251
|
+
/**
|
|
3252
|
+
* Handle Escape key press.
|
|
3253
|
+
*
|
|
3254
|
+
* If the overlay is open, closes it and returns focus to the inline input.
|
|
3255
|
+
* If the overlay is already closed, cancels the edit entirely.
|
|
3256
|
+
*/
|
|
3257
|
+
handleEscape(event) {
|
|
3258
|
+
if (this._isOpen) {
|
|
3259
|
+
event.stopPropagation();
|
|
3260
|
+
this.hideOverlay();
|
|
3261
|
+
}
|
|
3262
|
+
else {
|
|
3263
|
+
this.cancelEdit();
|
|
3264
|
+
}
|
|
3265
|
+
}
|
|
3266
|
+
/**
|
|
3267
|
+
* Dispatch a synthetic Tab key event to advance grid focus.
|
|
3268
|
+
*
|
|
3269
|
+
* Call this after committing a value and closing the overlay so the
|
|
3270
|
+
* grid moves focus to the next cell.
|
|
3271
|
+
*
|
|
3272
|
+
* @param backward - When `true`, dispatch Shift+Tab to move backwards.
|
|
3273
|
+
*/
|
|
3274
|
+
advanceGridFocus(backward = false) {
|
|
3275
|
+
const cell = this._getCell();
|
|
3276
|
+
if (!cell)
|
|
3277
|
+
return;
|
|
3278
|
+
cell.dispatchEvent(new KeyboardEvent('keydown', {
|
|
3279
|
+
key: 'Tab',
|
|
3280
|
+
shiftKey: backward,
|
|
3281
|
+
bubbles: true,
|
|
3282
|
+
cancelable: true,
|
|
3283
|
+
}));
|
|
3284
|
+
}
|
|
3285
|
+
/**
|
|
3286
|
+
* Called after the overlay is shown.
|
|
3287
|
+
*
|
|
3288
|
+
* Override to focus an element inside the panel, start animations, etc.
|
|
3289
|
+
* Default implementation is a no-op.
|
|
3290
|
+
*/
|
|
3291
|
+
onOverlayOpened() {
|
|
3292
|
+
// Default: no-op. Subclasses override.
|
|
3293
|
+
}
|
|
3294
|
+
// ============================================================================
|
|
3295
|
+
// Private Helpers
|
|
3296
|
+
// ============================================================================
|
|
3297
|
+
/** Find the parent cell element for this editor. */
|
|
3298
|
+
_getCell() {
|
|
3299
|
+
return this._elementRef.nativeElement.closest('[part="cell"]') ?? null;
|
|
3300
|
+
}
|
|
3301
|
+
/**
|
|
3302
|
+
* JS fallback positioning for browsers without CSS Anchor Positioning.
|
|
3303
|
+
* Uses `getBoundingClientRect()` with viewport overflow detection.
|
|
3304
|
+
*/
|
|
3305
|
+
_positionWithJs() {
|
|
3306
|
+
const cell = this._getCell();
|
|
3307
|
+
const panel = this._panel;
|
|
3308
|
+
if (!cell || !panel)
|
|
3309
|
+
return;
|
|
3310
|
+
const cellRect = cell.getBoundingClientRect();
|
|
3311
|
+
// Temporarily make visible to measure
|
|
3312
|
+
panel.style.visibility = 'hidden';
|
|
3313
|
+
panel.style.display = '';
|
|
3314
|
+
const panelRect = panel.getBoundingClientRect();
|
|
3315
|
+
panel.style.visibility = '';
|
|
3316
|
+
const viewportH = window.innerHeight;
|
|
3317
|
+
const viewportW = window.innerWidth;
|
|
3318
|
+
let top;
|
|
3319
|
+
let left;
|
|
3320
|
+
switch (this.overlayPosition) {
|
|
3321
|
+
case 'above': {
|
|
3322
|
+
top = cellRect.top - panelRect.height;
|
|
3323
|
+
left = cellRect.left;
|
|
3324
|
+
// Flip to below if off-screen
|
|
3325
|
+
if (top < 0)
|
|
3326
|
+
top = cellRect.bottom;
|
|
3327
|
+
break;
|
|
3328
|
+
}
|
|
3329
|
+
case 'below-right': {
|
|
3330
|
+
top = cellRect.bottom;
|
|
3331
|
+
left = cellRect.right - panelRect.width;
|
|
3332
|
+
// Flip to above if off-screen
|
|
3333
|
+
if (top + panelRect.height > viewportH)
|
|
3334
|
+
top = cellRect.top - panelRect.height;
|
|
3335
|
+
break;
|
|
3336
|
+
}
|
|
3337
|
+
case 'over-left': {
|
|
3338
|
+
top = cellRect.top;
|
|
3339
|
+
left = cellRect.left;
|
|
3340
|
+
break;
|
|
3341
|
+
}
|
|
3342
|
+
case 'below':
|
|
3343
|
+
default: {
|
|
3344
|
+
top = cellRect.bottom;
|
|
3345
|
+
left = cellRect.left;
|
|
3346
|
+
// Flip to above if off-screen
|
|
3347
|
+
if (top + panelRect.height > viewportH)
|
|
3348
|
+
top = cellRect.top - panelRect.height;
|
|
3349
|
+
break;
|
|
3350
|
+
}
|
|
3351
|
+
}
|
|
3352
|
+
// Clamp to viewport
|
|
3353
|
+
if (left + panelRect.width > viewportW)
|
|
3354
|
+
left = viewportW - panelRect.width - 4;
|
|
3355
|
+
if (left < 0)
|
|
3356
|
+
left = 4;
|
|
3357
|
+
if (top < 0)
|
|
3358
|
+
top = 4;
|
|
3359
|
+
panel.style.top = `${top}px`;
|
|
3360
|
+
panel.style.left = `${left}px`;
|
|
3361
|
+
}
|
|
3362
|
+
/**
|
|
3363
|
+
* Document pointerdown handler for click-outside detection.
|
|
3364
|
+
* Fires `onOverlayOutsideClick()` if the click is outside the panel
|
|
3365
|
+
* and outside the editor's host element.
|
|
3366
|
+
*/
|
|
3367
|
+
_onDocumentPointerDown(event) {
|
|
3368
|
+
if (!this._isOpen || !this._panel)
|
|
3369
|
+
return;
|
|
3370
|
+
const target = event.target;
|
|
3371
|
+
const hostEl = this._elementRef.nativeElement;
|
|
3372
|
+
// Click inside panel or host — ignore
|
|
3373
|
+
if (this._panel.contains(target) || hostEl.contains(target))
|
|
3374
|
+
return;
|
|
3375
|
+
this.onOverlayOutsideClick();
|
|
3376
|
+
}
|
|
3377
|
+
/**
|
|
3378
|
+
* Set up a MutationObserver on the parent cell to watch for
|
|
3379
|
+
* `cell-focus` class changes. This handles row-editing mode where
|
|
3380
|
+
* all editors exist simultaneously but only the focused cell's
|
|
3381
|
+
* editor should have its overlay visible.
|
|
3382
|
+
*/
|
|
3383
|
+
_setupFocusObserver() {
|
|
3384
|
+
const cell = this._getCell();
|
|
3385
|
+
if (!cell)
|
|
3386
|
+
return;
|
|
3387
|
+
this._focusObserver = new MutationObserver((mutations) => {
|
|
3388
|
+
for (const mutation of mutations) {
|
|
3389
|
+
if (mutation.type !== 'attributes' || mutation.attributeName !== 'class')
|
|
3390
|
+
continue;
|
|
3391
|
+
const isFocused = cell.classList.contains('cell-focus');
|
|
3392
|
+
if (isFocused && !this._isOpen) {
|
|
3393
|
+
// Cell just gained focus — open overlay if appropriate
|
|
3394
|
+
this.showOverlay();
|
|
3395
|
+
this.onOverlayOpened();
|
|
3396
|
+
}
|
|
3397
|
+
else if (!isFocused && this._isOpen) {
|
|
3398
|
+
// Cell lost focus — hide overlay silently
|
|
3399
|
+
this.hideOverlay(true);
|
|
3400
|
+
}
|
|
3401
|
+
}
|
|
3402
|
+
});
|
|
3403
|
+
this._focusObserver.observe(cell, { attributes: true, attributeFilter: ['class'] });
|
|
3404
|
+
}
|
|
3405
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: BaseOverlayEditor, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3406
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: BaseOverlayEditor, isStandalone: true, usesInheritance: true, ngImport: i0 });
|
|
3407
|
+
}
|
|
3408
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: BaseOverlayEditor, decorators: [{
|
|
3409
|
+
type: Directive
|
|
3410
|
+
}], ctorParameters: () => [] });
|
|
3411
|
+
|
|
3412
|
+
/**
|
|
3413
|
+
* Directive that registers `<tbw-grid-column>` as a known Angular element.
|
|
3414
|
+
*
|
|
3415
|
+
* This directive exists so that Angular's template compiler recognises
|
|
3416
|
+
* `<tbw-grid-column>` without requiring `CUSTOM_ELEMENTS_SCHEMA`.
|
|
3417
|
+
* The underlying web component reads its attributes (`field`, `header`,
|
|
3418
|
+
* `type`, `width`, etc.) directly from the DOM, so no `@Input()` forwarding
|
|
3419
|
+
* is needed — Angular's standard property/attribute binding handles it.
|
|
3420
|
+
*
|
|
3421
|
+
* ## Usage
|
|
3422
|
+
*
|
|
3423
|
+
* ```typescript
|
|
3424
|
+
* import { Component } from '@angular/core';
|
|
3425
|
+
* import { Grid, TbwGridColumn, TbwRenderer } from '@toolbox-web/grid-angular';
|
|
3426
|
+
*
|
|
3427
|
+
* @Component({
|
|
3428
|
+
* imports: [Grid, TbwGridColumn, TbwRenderer],
|
|
3429
|
+
* template: `
|
|
3430
|
+
* <tbw-grid [rows]="rows" [gridConfig]="config">
|
|
3431
|
+
* <tbw-grid-column field="status">
|
|
3432
|
+
* <app-status-badge *tbwRenderer="let value" [value]="value" />
|
|
3433
|
+
* </tbw-grid-column>
|
|
3434
|
+
* </tbw-grid>
|
|
3435
|
+
* `
|
|
3436
|
+
* })
|
|
3437
|
+
* export class MyComponent { }
|
|
3438
|
+
* ```
|
|
3439
|
+
*/
|
|
3440
|
+
class TbwGridColumn {
|
|
3441
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TbwGridColumn, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3442
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: TbwGridColumn, isStandalone: true, selector: "tbw-grid-column", ngImport: i0 });
|
|
3443
|
+
}
|
|
3444
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TbwGridColumn, decorators: [{
|
|
3445
|
+
type: Directive,
|
|
3446
|
+
args: [{
|
|
3447
|
+
selector: 'tbw-grid-column',
|
|
3448
|
+
}]
|
|
3449
|
+
}] });
|
|
3450
|
+
|
|
3451
|
+
/**
|
|
3452
|
+
* Directive that registers `<tbw-grid-header>` as a known Angular element.
|
|
3453
|
+
*
|
|
3454
|
+
* This directive exists so that Angular's template compiler recognises
|
|
3455
|
+
* `<tbw-grid-header>` without requiring `CUSTOM_ELEMENTS_SCHEMA`.
|
|
3456
|
+
* The grid's `config-manager` reads attributes like `title` directly
|
|
3457
|
+
* from the DOM element.
|
|
3458
|
+
*
|
|
3459
|
+
* ## Usage
|
|
3460
|
+
*
|
|
3461
|
+
* ```typescript
|
|
3462
|
+
* import { Component } from '@angular/core';
|
|
3463
|
+
* import { Grid, TbwGridHeader } from '@toolbox-web/grid-angular';
|
|
3464
|
+
*
|
|
3465
|
+
* @Component({
|
|
3466
|
+
* imports: [Grid, TbwGridHeader],
|
|
3467
|
+
* template: `
|
|
3468
|
+
* <tbw-grid [rows]="rows" [gridConfig]="config">
|
|
3469
|
+
* <tbw-grid-header title="My Grid Title"></tbw-grid-header>
|
|
3470
|
+
* </tbw-grid>
|
|
3471
|
+
* `
|
|
3472
|
+
* })
|
|
3473
|
+
* export class MyComponent { }
|
|
3474
|
+
* ```
|
|
3475
|
+
*/
|
|
3476
|
+
class TbwGridHeader {
|
|
3477
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TbwGridHeader, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3478
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: TbwGridHeader, isStandalone: true, selector: "tbw-grid-header", ngImport: i0 });
|
|
3479
|
+
}
|
|
3480
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TbwGridHeader, decorators: [{
|
|
3481
|
+
type: Directive,
|
|
3482
|
+
args: [{
|
|
3483
|
+
selector: 'tbw-grid-header',
|
|
3484
|
+
}]
|
|
3485
|
+
}] });
|
|
3486
|
+
|
|
2702
3487
|
// Symbol for storing form context on the grid element (shared with GridFormArray)
|
|
2703
3488
|
const FORM_ARRAY_CONTEXT = Symbol('formArrayContext');
|
|
2704
3489
|
/**
|
|
@@ -3183,6 +3968,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
|
|
|
3183
3968
|
}]
|
|
3184
3969
|
}], propDecorators: { lazyForm: [{ type: i0.Input, args: [{ isSignal: true, alias: "lazyForm", required: true }] }], syncValidation: [{ type: i0.Input, args: [{ isSignal: true, alias: "syncValidation", required: false }] }], keepFormGroups: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepFormGroups", required: false }] }], rowFormChange: [{ type: i0.Output, args: ["rowFormChange"] }] } });
|
|
3185
3970
|
|
|
3971
|
+
/**
|
|
3972
|
+
* Directive that registers `<tbw-grid-tool-buttons>` as a known Angular element.
|
|
3973
|
+
*
|
|
3974
|
+
* This directive exists so that Angular's template compiler recognises
|
|
3975
|
+
* `<tbw-grid-tool-buttons>` without requiring `CUSTOM_ELEMENTS_SCHEMA`.
|
|
3976
|
+
* The grid's shell reads toolbar buttons directly from the DOM.
|
|
3977
|
+
*
|
|
3978
|
+
* ## Usage
|
|
3979
|
+
*
|
|
3980
|
+
* ```typescript
|
|
3981
|
+
* import { Component } from '@angular/core';
|
|
3982
|
+
* import { Grid, TbwGridToolButtons } from '@toolbox-web/grid-angular';
|
|
3983
|
+
*
|
|
3984
|
+
* @Component({
|
|
3985
|
+
* imports: [Grid, TbwGridToolButtons],
|
|
3986
|
+
* template: `
|
|
3987
|
+
* <tbw-grid [rows]="rows" [gridConfig]="config">
|
|
3988
|
+
* <tbw-grid-tool-buttons>
|
|
3989
|
+
* <button (click)="doSomething()">Action</button>
|
|
3990
|
+
* </tbw-grid-tool-buttons>
|
|
3991
|
+
* </tbw-grid>
|
|
3992
|
+
* `
|
|
3993
|
+
* })
|
|
3994
|
+
* export class MyComponent { }
|
|
3995
|
+
* ```
|
|
3996
|
+
*/
|
|
3997
|
+
class TbwGridToolButtons {
|
|
3998
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TbwGridToolButtons, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3999
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: TbwGridToolButtons, isStandalone: true, selector: "tbw-grid-tool-buttons", ngImport: i0 });
|
|
4000
|
+
}
|
|
4001
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TbwGridToolButtons, decorators: [{
|
|
4002
|
+
type: Directive,
|
|
4003
|
+
args: [{
|
|
4004
|
+
selector: 'tbw-grid-tool-buttons',
|
|
4005
|
+
}]
|
|
4006
|
+
}] });
|
|
4007
|
+
|
|
3186
4008
|
/**
|
|
3187
4009
|
* Directive that automatically registers the Angular adapter with tbw-grid elements.
|
|
3188
4010
|
*
|
|
@@ -3192,13 +4014,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
|
|
|
3192
4014
|
* ## Usage
|
|
3193
4015
|
*
|
|
3194
4016
|
* ```typescript
|
|
3195
|
-
* import { Component
|
|
4017
|
+
* import { Component } from '@angular/core';
|
|
3196
4018
|
* import { Grid } from '@toolbox-web/grid-angular';
|
|
3197
4019
|
*
|
|
3198
4020
|
* @Component({
|
|
3199
4021
|
* selector: 'app-root',
|
|
3200
4022
|
* imports: [Grid],
|
|
3201
|
-
* schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
3202
4023
|
* template: `
|
|
3203
4024
|
* <tbw-grid [rows]="rows" [gridConfig]="config" [customStyles]="myStyles">
|
|
3204
4025
|
* <!-- column templates -->
|
|
@@ -3292,6 +4113,30 @@ class Grid {
|
|
|
3292
4113
|
const grid = this.elementRef.nativeElement;
|
|
3293
4114
|
grid.loading = loadingValue;
|
|
3294
4115
|
});
|
|
4116
|
+
// Effect to sync rows to the grid element
|
|
4117
|
+
effect(() => {
|
|
4118
|
+
const rowsValue = this.rows();
|
|
4119
|
+
if (rowsValue === undefined)
|
|
4120
|
+
return;
|
|
4121
|
+
const grid = this.elementRef.nativeElement;
|
|
4122
|
+
grid.rows = rowsValue;
|
|
4123
|
+
});
|
|
4124
|
+
// Effect to sync columns to the grid element
|
|
4125
|
+
effect(() => {
|
|
4126
|
+
const columnsValue = this.columns();
|
|
4127
|
+
if (columnsValue === undefined)
|
|
4128
|
+
return;
|
|
4129
|
+
const grid = this.elementRef.nativeElement;
|
|
4130
|
+
grid.columns = columnsValue;
|
|
4131
|
+
});
|
|
4132
|
+
// Effect to sync fitMode to the grid element
|
|
4133
|
+
effect(() => {
|
|
4134
|
+
const fitModeValue = this.fitMode();
|
|
4135
|
+
if (fitModeValue === undefined)
|
|
4136
|
+
return;
|
|
4137
|
+
const grid = this.elementRef.nativeElement;
|
|
4138
|
+
grid.fitMode = fitModeValue;
|
|
4139
|
+
});
|
|
3295
4140
|
}
|
|
3296
4141
|
/**
|
|
3297
4142
|
* Custom CSS styles to inject into the grid.
|
|
@@ -3400,6 +4245,53 @@ class Grid {
|
|
|
3400
4245
|
* ```
|
|
3401
4246
|
*/
|
|
3402
4247
|
loading = input(...(ngDevMode ? [undefined, { debugName: "loading" }] : []));
|
|
4248
|
+
/**
|
|
4249
|
+
* The data rows to display in the grid.
|
|
4250
|
+
*
|
|
4251
|
+
* Accepts an array of data objects. Each object represents one row.
|
|
4252
|
+
* The grid reads property values for each column's `field` from these objects.
|
|
4253
|
+
*
|
|
4254
|
+
* @example
|
|
4255
|
+
* ```html
|
|
4256
|
+
* <tbw-grid [rows]="employees()" [gridConfig]="config" />
|
|
4257
|
+
* ```
|
|
4258
|
+
*/
|
|
4259
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4260
|
+
rows = input(...(ngDevMode ? [undefined, { debugName: "rows" }] : []));
|
|
4261
|
+
/**
|
|
4262
|
+
* Column configuration array.
|
|
4263
|
+
*
|
|
4264
|
+
* Shorthand for setting columns without wrapping them in a full `gridConfig`.
|
|
4265
|
+
* If both `columns` and `gridConfig.columns` are set, `columns` takes precedence
|
|
4266
|
+
* (see configuration precedence system).
|
|
4267
|
+
*
|
|
4268
|
+
* @example
|
|
4269
|
+
* ```html
|
|
4270
|
+
* <tbw-grid [rows]="data" [columns]="[
|
|
4271
|
+
* { field: 'id', header: 'ID', pinned: 'left', width: 80 },
|
|
4272
|
+
* { field: 'name', header: 'Name' },
|
|
4273
|
+
* { field: 'email', header: 'Email' }
|
|
4274
|
+
* ]" />
|
|
4275
|
+
* ```
|
|
4276
|
+
*/
|
|
4277
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4278
|
+
columns = input(...(ngDevMode ? [undefined, { debugName: "columns" }] : []));
|
|
4279
|
+
/**
|
|
4280
|
+
* Column sizing strategy.
|
|
4281
|
+
*
|
|
4282
|
+
* - `'stretch'` (default) — columns stretch to fill available width
|
|
4283
|
+
* - `'fixed'` — columns use their declared widths; enables horizontal scrolling
|
|
4284
|
+
* - `'auto-fit'` — columns auto-size to content, then stretch to fill
|
|
4285
|
+
*
|
|
4286
|
+
* @default 'stretch'
|
|
4287
|
+
*
|
|
4288
|
+
* @example
|
|
4289
|
+
* ```html
|
|
4290
|
+
* <tbw-grid [rows]="data" fitMode="fixed" />
|
|
4291
|
+
* <tbw-grid [rows]="data" [fitMode]="dynamicMode()" />
|
|
4292
|
+
* ```
|
|
4293
|
+
*/
|
|
4294
|
+
fitMode = input(...(ngDevMode ? [undefined, { debugName: "fitMode" }] : []));
|
|
3403
4295
|
/**
|
|
3404
4296
|
* Grid configuration object with optional Angular-specific extensions.
|
|
3405
4297
|
*
|
|
@@ -3618,9 +4510,9 @@ class Grid {
|
|
|
3618
4510
|
* @example
|
|
3619
4511
|
* ```html
|
|
3620
4512
|
* <tbw-grid [pinnedColumns]="true" [columns]="[
|
|
3621
|
-
* { field: 'id',
|
|
4513
|
+
* { field: 'id', pinned: 'left' },
|
|
3622
4514
|
* { field: 'name' },
|
|
3623
|
-
* { field: 'actions',
|
|
4515
|
+
* { field: 'actions', pinned: 'right' }
|
|
3624
4516
|
* ]" />
|
|
3625
4517
|
* ```
|
|
3626
4518
|
*/
|
|
@@ -4330,12 +5222,12 @@ class Grid {
|
|
|
4330
5222
|
}
|
|
4331
5223
|
}
|
|
4332
5224
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: Grid, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
4333
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: Grid, isStandalone: true, selector: "tbw-grid", inputs: { customStyles: { classPropertyName: "customStyles", publicName: "customStyles", isSignal: true, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, gridConfig: { classPropertyName: "gridConfig", publicName: "gridConfig", isSignal: true, isRequired: false, transformFunction: null }, angularConfig: { classPropertyName: "angularConfig", publicName: "angularConfig", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, editing: { classPropertyName: "editing", publicName: "editing", isSignal: true, isRequired: false, transformFunction: null }, clipboard: { classPropertyName: "clipboard", publicName: "clipboard", isSignal: true, isRequired: false, transformFunction: null }, contextMenu: { classPropertyName: "contextMenu", publicName: "contextMenu", isSignal: true, isRequired: false, transformFunction: null }, multiSort: { classPropertyName: "multiSort", publicName: "multiSort", isSignal: true, isRequired: false, transformFunction: null }, sorting: { classPropertyName: "sorting", publicName: "sorting", isSignal: true, isRequired: false, transformFunction: null }, filtering: { classPropertyName: "filtering", publicName: "filtering", isSignal: true, isRequired: false, transformFunction: null }, reorder: { classPropertyName: "reorder", publicName: "reorder", isSignal: true, isRequired: false, transformFunction: null }, visibility: { classPropertyName: "visibility", publicName: "visibility", isSignal: true, isRequired: false, transformFunction: null }, pinnedColumns: { classPropertyName: "pinnedColumns", publicName: "pinnedColumns", isSignal: true, isRequired: false, transformFunction: null }, groupingColumns: { classPropertyName: "groupingColumns", publicName: "groupingColumns", isSignal: true, isRequired: false, transformFunction: null }, columnVirtualization: { classPropertyName: "columnVirtualization", publicName: "columnVirtualization", isSignal: true, isRequired: false, transformFunction: null }, rowReorder: { classPropertyName: "rowReorder", publicName: "rowReorder", isSignal: true, isRequired: false, transformFunction: null }, groupingRows: { classPropertyName: "groupingRows", publicName: "groupingRows", isSignal: true, isRequired: false, transformFunction: null }, pinnedRows: { classPropertyName: "pinnedRows", publicName: "pinnedRows", isSignal: true, isRequired: false, transformFunction: null }, tree: { classPropertyName: "tree", publicName: "tree", isSignal: true, isRequired: false, transformFunction: null }, masterDetail: { classPropertyName: "masterDetail", publicName: "masterDetail", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, undoRedo: { classPropertyName: "undoRedo", publicName: "undoRedo", isSignal: true, isRequired: false, transformFunction: null }, exportFeature: { classPropertyName: "exportFeature", publicName: "export", isSignal: true, isRequired: false, transformFunction: null }, print: { classPropertyName: "print", publicName: "print", isSignal: true, isRequired: false, transformFunction: null }, pivot: { classPropertyName: "pivot", publicName: "pivot", isSignal: true, isRequired: false, transformFunction: null }, serverSide: { classPropertyName: "serverSide", publicName: "serverSide", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { 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" }, ngImport: i0 });
|
|
5225
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: Grid, isStandalone: true, selector: "tbw-grid", inputs: { customStyles: { classPropertyName: "customStyles", publicName: "customStyles", isSignal: true, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, fitMode: { classPropertyName: "fitMode", publicName: "fitMode", isSignal: true, isRequired: false, transformFunction: null }, gridConfig: { classPropertyName: "gridConfig", publicName: "gridConfig", isSignal: true, isRequired: false, transformFunction: null }, angularConfig: { classPropertyName: "angularConfig", publicName: "angularConfig", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, editing: { classPropertyName: "editing", publicName: "editing", isSignal: true, isRequired: false, transformFunction: null }, clipboard: { classPropertyName: "clipboard", publicName: "clipboard", isSignal: true, isRequired: false, transformFunction: null }, contextMenu: { classPropertyName: "contextMenu", publicName: "contextMenu", isSignal: true, isRequired: false, transformFunction: null }, multiSort: { classPropertyName: "multiSort", publicName: "multiSort", isSignal: true, isRequired: false, transformFunction: null }, sorting: { classPropertyName: "sorting", publicName: "sorting", isSignal: true, isRequired: false, transformFunction: null }, filtering: { classPropertyName: "filtering", publicName: "filtering", isSignal: true, isRequired: false, transformFunction: null }, reorder: { classPropertyName: "reorder", publicName: "reorder", isSignal: true, isRequired: false, transformFunction: null }, visibility: { classPropertyName: "visibility", publicName: "visibility", isSignal: true, isRequired: false, transformFunction: null }, pinnedColumns: { classPropertyName: "pinnedColumns", publicName: "pinnedColumns", isSignal: true, isRequired: false, transformFunction: null }, groupingColumns: { classPropertyName: "groupingColumns", publicName: "groupingColumns", isSignal: true, isRequired: false, transformFunction: null }, columnVirtualization: { classPropertyName: "columnVirtualization", publicName: "columnVirtualization", isSignal: true, isRequired: false, transformFunction: null }, rowReorder: { classPropertyName: "rowReorder", publicName: "rowReorder", isSignal: true, isRequired: false, transformFunction: null }, groupingRows: { classPropertyName: "groupingRows", publicName: "groupingRows", isSignal: true, isRequired: false, transformFunction: null }, pinnedRows: { classPropertyName: "pinnedRows", publicName: "pinnedRows", isSignal: true, isRequired: false, transformFunction: null }, tree: { classPropertyName: "tree", publicName: "tree", isSignal: true, isRequired: false, transformFunction: null }, masterDetail: { classPropertyName: "masterDetail", publicName: "masterDetail", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, undoRedo: { classPropertyName: "undoRedo", publicName: "undoRedo", isSignal: true, isRequired: false, transformFunction: null }, exportFeature: { classPropertyName: "exportFeature", publicName: "export", isSignal: true, isRequired: false, transformFunction: null }, print: { classPropertyName: "print", publicName: "print", isSignal: true, isRequired: false, transformFunction: null }, pivot: { classPropertyName: "pivot", publicName: "pivot", isSignal: true, isRequired: false, transformFunction: null }, serverSide: { classPropertyName: "serverSide", publicName: "serverSide", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { 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" }, ngImport: i0 });
|
|
4334
5226
|
}
|
|
4335
5227
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: Grid, decorators: [{
|
|
4336
5228
|
type: Directive,
|
|
4337
5229
|
args: [{ selector: 'tbw-grid' }]
|
|
4338
|
-
}], ctorParameters: () => [], propDecorators: { customStyles: [{ type: i0.Input, args: [{ isSignal: true, alias: "customStyles", required: false }] }], sortable: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortable", required: false }] }], filterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterable", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], gridConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "gridConfig", required: false }] }], angularConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "angularConfig", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }], editing: [{ type: i0.Input, args: [{ isSignal: true, alias: "editing", required: false }] }], clipboard: [{ type: i0.Input, args: [{ isSignal: true, alias: "clipboard", required: false }] }], contextMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextMenu", required: false }] }], multiSort: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiSort", required: false }] }], sorting: [{ type: i0.Input, args: [{ isSignal: true, alias: "sorting", required: false }] }], filtering: [{ type: i0.Input, args: [{ isSignal: true, alias: "filtering", required: false }] }], reorder: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorder", required: false }] }], visibility: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibility", required: false }] }], pinnedColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedColumns", required: false }] }], groupingColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupingColumns", required: false }] }], columnVirtualization: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnVirtualization", required: false }] }], rowReorder: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowReorder", required: false }] }], groupingRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupingRows", required: false }] }], pinnedRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedRows", required: false }] }], tree: [{ type: i0.Input, args: [{ isSignal: true, alias: "tree", required: false }] }], masterDetail: [{ type: i0.Input, args: [{ isSignal: true, alias: "masterDetail", required: false }] }], responsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "responsive", required: false }] }], undoRedo: [{ type: i0.Input, args: [{ isSignal: true, alias: "undoRedo", required: false }] }], exportFeature: [{ type: i0.Input, args: [{ isSignal: true, alias: "export", required: false }] }], print: [{ type: i0.Input, args: [{ isSignal: true, alias: "print", required: false }] }], pivot: [{ type: i0.Input, args: [{ isSignal: true, alias: "pivot", required: false }] }], serverSide: [{ type: i0.Input, args: [{ isSignal: true, alias: "serverSide", required: false }] }], cellClick: [{ type: i0.Output, args: ["cellClick"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], cellActivate: [{ type: i0.Output, args: ["cellActivate"] }], cellChange: [{ type: i0.Output, args: ["cellChange"] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], rowCommit: [{ type: i0.Output, args: ["rowCommit"] }], changedRowsReset: [{ type: i0.Output, args: ["changedRowsReset"] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }], columnResize: [{ type: i0.Output, args: ["columnResize"] }], columnMove: [{ type: i0.Output, args: ["columnMove"] }], columnVisibility: [{ type: i0.Output, args: ["columnVisibility"] }], columnStateChange: [{ type: i0.Output, args: ["columnStateChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], rowMove: [{ type: i0.Output, args: ["rowMove"] }], groupToggle: [{ type: i0.Output, args: ["groupToggle"] }], treeExpand: [{ type: i0.Output, args: ["treeExpand"] }], detailExpand: [{ type: i0.Output, args: ["detailExpand"] }], responsiveChange: [{ type: i0.Output, args: ["responsiveChange"] }], copy: [{ type: i0.Output, args: ["copy"] }], paste: [{ type: i0.Output, args: ["paste"] }], undoRedoAction: [{ type: i0.Output, args: ["undoRedoAction"] }], exportComplete: [{ type: i0.Output, args: ["exportComplete"] }], printStart: [{ type: i0.Output, args: ["printStart"] }], printComplete: [{ type: i0.Output, args: ["printComplete"] }] } });
|
|
5230
|
+
}], ctorParameters: () => [], propDecorators: { customStyles: [{ type: i0.Input, args: [{ isSignal: true, alias: "customStyles", required: false }] }], sortable: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortable", required: false }] }], filterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterable", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], fitMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "fitMode", required: false }] }], gridConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "gridConfig", required: false }] }], angularConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "angularConfig", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }], editing: [{ type: i0.Input, args: [{ isSignal: true, alias: "editing", required: false }] }], clipboard: [{ type: i0.Input, args: [{ isSignal: true, alias: "clipboard", required: false }] }], contextMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextMenu", required: false }] }], multiSort: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiSort", required: false }] }], sorting: [{ type: i0.Input, args: [{ isSignal: true, alias: "sorting", required: false }] }], filtering: [{ type: i0.Input, args: [{ isSignal: true, alias: "filtering", required: false }] }], reorder: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorder", required: false }] }], visibility: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibility", required: false }] }], pinnedColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedColumns", required: false }] }], groupingColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupingColumns", required: false }] }], columnVirtualization: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnVirtualization", required: false }] }], rowReorder: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowReorder", required: false }] }], groupingRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupingRows", required: false }] }], pinnedRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedRows", required: false }] }], tree: [{ type: i0.Input, args: [{ isSignal: true, alias: "tree", required: false }] }], masterDetail: [{ type: i0.Input, args: [{ isSignal: true, alias: "masterDetail", required: false }] }], responsive: [{ type: i0.Input, args: [{ isSignal: true, alias: "responsive", required: false }] }], undoRedo: [{ type: i0.Input, args: [{ isSignal: true, alias: "undoRedo", required: false }] }], exportFeature: [{ type: i0.Input, args: [{ isSignal: true, alias: "export", required: false }] }], print: [{ type: i0.Input, args: [{ isSignal: true, alias: "print", required: false }] }], pivot: [{ type: i0.Input, args: [{ isSignal: true, alias: "pivot", required: false }] }], serverSide: [{ type: i0.Input, args: [{ isSignal: true, alias: "serverSide", required: false }] }], cellClick: [{ type: i0.Output, args: ["cellClick"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], cellActivate: [{ type: i0.Output, args: ["cellActivate"] }], cellChange: [{ type: i0.Output, args: ["cellChange"] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], rowCommit: [{ type: i0.Output, args: ["rowCommit"] }], changedRowsReset: [{ type: i0.Output, args: ["changedRowsReset"] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], filterChange: [{ type: i0.Output, args: ["filterChange"] }], columnResize: [{ type: i0.Output, args: ["columnResize"] }], columnMove: [{ type: i0.Output, args: ["columnMove"] }], columnVisibility: [{ type: i0.Output, args: ["columnVisibility"] }], columnStateChange: [{ type: i0.Output, args: ["columnStateChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], rowMove: [{ type: i0.Output, args: ["rowMove"] }], groupToggle: [{ type: i0.Output, args: ["groupToggle"] }], treeExpand: [{ type: i0.Output, args: ["treeExpand"] }], detailExpand: [{ type: i0.Output, args: ["detailExpand"] }], responsiveChange: [{ type: i0.Output, args: ["responsiveChange"] }], copy: [{ type: i0.Output, args: ["copy"] }], paste: [{ type: i0.Output, args: ["paste"] }], undoRedoAction: [{ type: i0.Output, args: ["undoRedoAction"] }], exportComplete: [{ type: i0.Output, args: ["exportComplete"] }], printStart: [{ type: i0.Output, args: ["printStart"] }], printComplete: [{ type: i0.Output, args: ["printComplete"] }] } });
|
|
4339
5231
|
|
|
4340
5232
|
/**
|
|
4341
5233
|
* @packageDocumentation
|
|
@@ -4349,5 +5241,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
|
|
|
4349
5241
|
* Generated bundle index. Do not edit.
|
|
4350
5242
|
*/
|
|
4351
5243
|
|
|
4352
|
-
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 };
|
|
5244
|
+
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 };
|
|
4353
5245
|
//# sourceMappingURL=toolbox-web-grid-angular.mjs.map
|