@ngneers/controls 0.0.1-next.0 → 0.0.1-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ngneers-controls-api-ng.mjs +11 -18
- package/fesm2022/ngneers-controls-api-ng.mjs.map +1 -1
- package/fesm2022/ngneers-controls-api-resize.mjs +7 -0
- package/fesm2022/ngneers-controls-api-resize.mjs.map +1 -1
- package/fesm2022/ngneers-controls-badge.mjs +160 -0
- package/fesm2022/ngneers-controls-badge.mjs.map +1 -0
- package/fesm2022/ngneers-controls-base.mjs +85 -8
- package/fesm2022/ngneers-controls-base.mjs.map +1 -1
- package/fesm2022/{ngneers-controls-calendar-time-CJT5AFlA.mjs → ngneers-controls-calendar-time-paM6WVpV.mjs} +2 -2
- package/fesm2022/{ngneers-controls-calendar-time-CJT5AFlA.mjs.map → ngneers-controls-calendar-time-paM6WVpV.mjs.map} +1 -1
- package/fesm2022/ngneers-controls-calendar.mjs +13 -6
- package/fesm2022/ngneers-controls-calendar.mjs.map +1 -1
- package/fesm2022/ngneers-controls-checkbox.mjs +3 -3
- package/fesm2022/ngneers-controls-checkbox.mjs.map +1 -1
- package/fesm2022/ngneers-controls-color-picker.mjs +336 -0
- package/fesm2022/ngneers-controls-color-picker.mjs.map +1 -0
- package/fesm2022/ngneers-controls-default-icons.mjs +5 -0
- package/fesm2022/ngneers-controls-default-icons.mjs.map +1 -1
- package/fesm2022/ngneers-controls-directives.mjs +64 -7
- package/fesm2022/ngneers-controls-directives.mjs.map +1 -1
- package/fesm2022/ngneers-controls-edit-inplace.mjs +15 -5
- package/fesm2022/ngneers-controls-edit-inplace.mjs.map +1 -1
- package/fesm2022/ngneers-controls-errors.mjs +203 -148
- package/fesm2022/ngneers-controls-errors.mjs.map +1 -1
- package/fesm2022/ngneers-controls-filter.mjs +2 -2
- package/fesm2022/ngneers-controls-filter.mjs.map +1 -1
- package/fesm2022/ngneers-controls-hint.mjs +18 -1
- package/fesm2022/ngneers-controls-hint.mjs.map +1 -1
- package/fesm2022/ngneers-controls-i18n-translations-de.mjs +17 -0
- package/fesm2022/ngneers-controls-i18n-translations-de.mjs.map +1 -1
- package/fesm2022/ngneers-controls-i18n-translations-en.mjs +19 -0
- package/fesm2022/ngneers-controls-i18n-translations-en.mjs.map +1 -1
- package/fesm2022/ngneers-controls-icon.mjs +23 -6
- package/fesm2022/ngneers-controls-icon.mjs.map +1 -1
- package/fesm2022/ngneers-controls-input-field.mjs +18 -2
- package/fesm2022/ngneers-controls-input-field.mjs.map +1 -1
- package/fesm2022/ngneers-controls-input.mjs +49 -9
- package/fesm2022/ngneers-controls-input.mjs.map +1 -1
- package/fesm2022/ngneers-controls-list-box.mjs +2 -2
- package/fesm2022/ngneers-controls-list-box.mjs.map +1 -1
- package/fesm2022/ngneers-controls-mask-input.mjs +4 -1
- package/fesm2022/ngneers-controls-mask-input.mjs.map +1 -1
- package/fesm2022/ngneers-controls-number-input.mjs +4 -4
- package/fesm2022/ngneers-controls-number-input.mjs.map +1 -1
- package/fesm2022/ngneers-controls-otp.mjs +263 -0
- package/fesm2022/ngneers-controls-otp.mjs.map +1 -0
- package/fesm2022/ngneers-controls-paginator.mjs +36 -9
- package/fesm2022/ngneers-controls-paginator.mjs.map +1 -1
- package/fesm2022/ngneers-controls-radio.mjs +4 -4
- package/fesm2022/ngneers-controls-radio.mjs.map +1 -1
- package/fesm2022/ngneers-controls-rating.mjs +180 -0
- package/fesm2022/ngneers-controls-rating.mjs.map +1 -0
- package/fesm2022/ngneers-controls-scroll-shadow.mjs +33 -7
- package/fesm2022/ngneers-controls-scroll-shadow.mjs.map +1 -1
- package/fesm2022/ngneers-controls-scroller.mjs +4 -2
- package/fesm2022/ngneers-controls-scroller.mjs.map +1 -1
- package/fesm2022/ngneers-controls-select-button.mjs +2 -1
- package/fesm2022/ngneers-controls-select-button.mjs.map +1 -1
- package/fesm2022/ngneers-controls-select.mjs +24 -4
- package/fesm2022/ngneers-controls-select.mjs.map +1 -1
- package/fesm2022/ngneers-controls-slider.mjs +3 -3
- package/fesm2022/ngneers-controls-slider.mjs.map +1 -1
- package/fesm2022/ngneers-controls-splitter.mjs +43 -12
- package/fesm2022/ngneers-controls-splitter.mjs.map +1 -1
- package/fesm2022/ngneers-controls-stepper.mjs +142 -0
- package/fesm2022/ngneers-controls-stepper.mjs.map +1 -0
- package/fesm2022/ngneers-controls-switch.mjs +3 -3
- package/fesm2022/ngneers-controls-switch.mjs.map +1 -1
- package/fesm2022/ngneers-controls-table.mjs +282 -15
- package/fesm2022/ngneers-controls-table.mjs.map +1 -1
- package/fesm2022/ngneers-controls-tabs.mjs +2 -2
- package/fesm2022/ngneers-controls-tabs.mjs.map +1 -1
- package/fesm2022/ngneers-controls-toggle-button.mjs +3 -3
- package/fesm2022/ngneers-controls-toggle-button.mjs.map +1 -1
- package/fesm2022/ngneers-controls-tooltip.mjs +16 -28
- package/fesm2022/ngneers-controls-tooltip.mjs.map +1 -1
- package/fesm2022/ngneers-controls-tree.mjs +2 -2
- package/fesm2022/ngneers-controls-tree.mjs.map +1 -1
- package/fesm2022/ngneers-controls-utils.mjs +138 -1
- package/fesm2022/ngneers-controls-utils.mjs.map +1 -1
- package/package.json +22 -2
- package/types/ngneers-controls-api-ng.d.ts +12 -9
- package/types/ngneers-controls-badge.d.ts +67 -0
- package/types/ngneers-controls-base.d.ts +61 -4
- package/types/ngneers-controls-breadcrumb.d.ts +17 -0
- package/types/ngneers-controls-calendar.d.ts +24 -6
- package/types/ngneers-controls-chip.d.ts +17 -0
- package/types/ngneers-controls-color-picker.d.ts +119 -0
- package/types/ngneers-controls-dialog.d.ts +17 -0
- package/types/ngneers-controls-directives.d.ts +31 -2
- package/types/ngneers-controls-drawer.d.ts +17 -0
- package/types/ngneers-controls-edit-inplace.d.ts +23 -0
- package/types/ngneers-controls-errors.d.ts +105 -16
- package/types/ngneers-controls-filter.d.ts +30 -13
- package/types/ngneers-controls-hint.d.ts +8 -1
- package/types/ngneers-controls-i18n-translations-de.d.ts +17 -0
- package/types/ngneers-controls-i18n-translations-en.d.ts +17 -0
- package/types/ngneers-controls-i18n.d.ts +17 -0
- package/types/ngneers-controls-icon.d.ts +2 -2
- package/types/ngneers-controls-input-field.d.ts +28 -2
- package/types/ngneers-controls-input.d.ts +35 -3
- package/types/ngneers-controls-list-box.d.ts +17 -0
- package/types/ngneers-controls-mask-input.d.ts +17 -0
- package/types/ngneers-controls-otp.d.ts +262 -0
- package/types/ngneers-controls-paginator.d.ts +34 -3
- package/types/ngneers-controls-rating.d.ts +69 -0
- package/types/ngneers-controls-scroll-shadow.d.ts +11 -2
- package/types/ngneers-controls-scroller.d.ts +3 -1
- package/types/ngneers-controls-select.d.ts +30 -3
- package/types/ngneers-controls-snackbar.d.ts +17 -0
- package/types/ngneers-controls-splitter.d.ts +26 -2
- package/types/ngneers-controls-state.d.ts +2 -2
- package/types/ngneers-controls-stepper.d.ts +68 -0
- package/types/ngneers-controls-table.d.ts +276 -169
- package/types/ngneers-controls-toast.d.ts +17 -0
- package/types/ngneers-controls-tooltip.d.ts +0 -1
- package/types/ngneers-controls-tree.d.ts +17 -0
- package/types/ngneers-controls-upload.d.ts +17 -0
- package/types/ngneers-controls-utils.d.ts +27 -2
|
@@ -9,7 +9,7 @@ import { switchControlTemplate } from '@ngneers/controls-themes/templates/switch
|
|
|
9
9
|
class NgnSwitch extends ValueControlBase {
|
|
10
10
|
theme = this.injectThemeTemplate(switchControlTemplate, {
|
|
11
11
|
root: true,
|
|
12
|
-
invalid: () => this.
|
|
12
|
+
invalid: () => this.invalidState(),
|
|
13
13
|
});
|
|
14
14
|
changed(event) {
|
|
15
15
|
const target = event.target;
|
|
@@ -24,11 +24,11 @@ class NgnSwitch extends ValueControlBase {
|
|
|
24
24
|
super();
|
|
25
25
|
}
|
|
26
26
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnSwitch, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
27
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: NgnSwitch, isStandalone: true, selector: "ngn-switch", providers: [provideSelf(NgnSwitch)], usesInheritance: true, ngImport: i0, template: "<div [ptInt]=\"this\" [ptClass]=\"{ track: true, 'track-checked': !!value() }\">\n <div [ptInt]=\"this\" [ptClass]=\"'thumb'\"></div>\n</div>\n<input\n type=\"checkbox\"\n [checked]=\"value()\"\n (change)=\"changed($event)\"\n (click)=\"onClick($event)\"\n [ptInt]=\"this\"\n [ptClass]=\"'input'\"\n [attr.disabled]=\"disabled() ? '' : undefined\"\n [ariaReadOnly]=\"readonly() ? '' : undefined\"\n [ariaInvalid]=\"
|
|
27
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: NgnSwitch, isStandalone: true, selector: "ngn-switch", providers: [provideSelf(NgnSwitch)], usesInheritance: true, ngImport: i0, template: "<div [ptInt]=\"this\" [ptClass]=\"{ track: true, 'track-checked': !!value() }\">\n <div [ptInt]=\"this\" [ptClass]=\"'thumb'\"></div>\n</div>\n<input\n type=\"checkbox\"\n [checked]=\"value()\"\n (change)=\"changed($event)\"\n (click)=\"onClick($event)\"\n [ptInt]=\"this\"\n [ptClass]=\"'input'\"\n [attr.disabled]=\"disabled() ? '' : undefined\"\n [ariaReadOnly]=\"readonly() ? '' : undefined\"\n [ariaInvalid]=\"invalidState() ? 'true' : undefined\"\n [attr.aria-label]=\"label()\"\n [ariaLabelledByElements]=\"labelledBy()\"\n [id]=\"inputId()\"\n (blur)=\"markTouched()\"\n/>\n", dependencies: [{ kind: "directive", type: NgnPt, selector: "[ptInt]", inputs: ["ptInt", "ptClass", "ptDep"] }] });
|
|
28
28
|
}
|
|
29
29
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnSwitch, decorators: [{
|
|
30
30
|
type: Component,
|
|
31
|
-
args: [{ selector: 'ngn-switch', imports: [NgnPt], providers: [provideSelf(NgnSwitch)], template: "<div [ptInt]=\"this\" [ptClass]=\"{ track: true, 'track-checked': !!value() }\">\n <div [ptInt]=\"this\" [ptClass]=\"'thumb'\"></div>\n</div>\n<input\n type=\"checkbox\"\n [checked]=\"value()\"\n (change)=\"changed($event)\"\n (click)=\"onClick($event)\"\n [ptInt]=\"this\"\n [ptClass]=\"'input'\"\n [attr.disabled]=\"disabled() ? '' : undefined\"\n [ariaReadOnly]=\"readonly() ? '' : undefined\"\n [ariaInvalid]=\"
|
|
31
|
+
args: [{ selector: 'ngn-switch', imports: [NgnPt], providers: [provideSelf(NgnSwitch)], template: "<div [ptInt]=\"this\" [ptClass]=\"{ track: true, 'track-checked': !!value() }\">\n <div [ptInt]=\"this\" [ptClass]=\"'thumb'\"></div>\n</div>\n<input\n type=\"checkbox\"\n [checked]=\"value()\"\n (change)=\"changed($event)\"\n (click)=\"onClick($event)\"\n [ptInt]=\"this\"\n [ptClass]=\"'input'\"\n [attr.disabled]=\"disabled() ? '' : undefined\"\n [ariaReadOnly]=\"readonly() ? '' : undefined\"\n [ariaInvalid]=\"invalidState() ? 'true' : undefined\"\n [attr.aria-label]=\"label()\"\n [ariaLabelledByElements]=\"labelledBy()\"\n [id]=\"inputId()\"\n (blur)=\"markTouched()\"\n/>\n" }]
|
|
32
32
|
}], ctorParameters: () => [] });
|
|
33
33
|
|
|
34
34
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngneers-controls-switch.mjs","sources":["../../src/switch/switch.ts","../../src/switch/switch.html","../../src/switch/ngneers-controls-switch.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { NgnPt, provideSelf, ValueControlBase } from '@ngneers/controls/base';\nimport { switchControlTemplate } from '@ngneers/controls-themes/templates/switch';\n\n/**\n * @category control\n */\n@Component({\n selector: 'ngn-switch',\n templateUrl: './switch.html',\n imports: [NgnPt],\n providers: [provideSelf(NgnSwitch)],\n})\nexport class NgnSwitch extends ValueControlBase<'switch', boolean> {\n protected readonly theme = this.injectThemeTemplate(switchControlTemplate, {\n root: true,\n invalid: () => this.
|
|
1
|
+
{"version":3,"file":"ngneers-controls-switch.mjs","sources":["../../src/switch/switch.ts","../../src/switch/switch.html","../../src/switch/ngneers-controls-switch.ts"],"sourcesContent":["import { Component } from '@angular/core';\nimport { NgnPt, provideSelf, ValueControlBase } from '@ngneers/controls/base';\nimport { switchControlTemplate } from '@ngneers/controls-themes/templates/switch';\n\n/**\n * @category control\n */\n@Component({\n selector: 'ngn-switch',\n templateUrl: './switch.html',\n imports: [NgnPt],\n providers: [provideSelf(NgnSwitch)],\n})\nexport class NgnSwitch extends ValueControlBase<'switch', boolean> {\n protected readonly theme = this.injectThemeTemplate(switchControlTemplate, {\n root: true,\n invalid: () => this.invalidState(),\n });\n\n protected changed(event: Event) {\n const target = event.target as HTMLInputElement;\n this.value.set(target.checked);\n }\n\n protected onClick(event: Event) {\n if (this.readonly() || this.disabled()) {\n event.preventDefault();\n }\n }\n\n constructor() {\n super();\n }\n}\n","<div [ptInt]=\"this\" [ptClass]=\"{ track: true, 'track-checked': !!value() }\">\n <div [ptInt]=\"this\" [ptClass]=\"'thumb'\"></div>\n</div>\n<input\n type=\"checkbox\"\n [checked]=\"value()\"\n (change)=\"changed($event)\"\n (click)=\"onClick($event)\"\n [ptInt]=\"this\"\n [ptClass]=\"'input'\"\n [attr.disabled]=\"disabled() ? '' : undefined\"\n [ariaReadOnly]=\"readonly() ? '' : undefined\"\n [ariaInvalid]=\"invalidState() ? 'true' : undefined\"\n [attr.aria-label]=\"label()\"\n [ariaLabelledByElements]=\"labelledBy()\"\n [id]=\"inputId()\"\n (blur)=\"markTouched()\"\n/>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAIA;;AAEG;AAOG,MAAO,SAAU,SAAQ,gBAAmC,CAAA;AAC7C,IAAA,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,qBAAqB,EAAE;AACzE,QAAA,IAAI,EAAE,IAAI;AACV,QAAA,OAAO,EAAE,MAAM,IAAI,CAAC,YAAY,EAAE;AACnC,KAAA,CAAC;AAEQ,IAAA,OAAO,CAAC,KAAY,EAAA;AAC5B,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAA0B;QAC/C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;IAChC;AAEU,IAAA,OAAO,CAAC,KAAY,EAAA;QAC5B,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE;YACtC,KAAK,CAAC,cAAc,EAAE;QACxB;IACF;AAEA,IAAA,WAAA,GAAA;AACE,QAAA,KAAK,EAAE;IACT;uGAnBW,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAT,SAAS,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,YAAA,EAAA,SAAA,EAFT,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECXrC,slBAkBA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDRY,KAAK,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,SAAA,EAAA,OAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAGJ,SAAS,EAAA,UAAA,EAAA,CAAA;kBANrB,SAAS;+BACE,YAAY,EAAA,OAAA,EAEb,CAAC,KAAK,CAAC,aACL,CAAC,WAAW,WAAW,CAAC,EAAA,QAAA,EAAA,slBAAA,EAAA;;;AEXrC;;AAEG;;;;"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { signal, computed, afterRenderEffect, input, inject, ElementRef, effect, Directive, contentChild, Component, viewChild, model, booleanAttribute, afterNextRender, Renderer2, ViewContainerRef, viewChildren, EnvironmentInjector, ApplicationRef, createComponent, NgModule } from '@angular/core';
|
|
2
|
+
import { signal, computed, afterRenderEffect, input, inject, ElementRef, effect, Directive, contentChild, Component, viewChild, model, booleanAttribute, untracked, afterNextRender, Renderer2, ViewContainerRef, viewChildren, EnvironmentInjector, ApplicationRef, createComponent, NgModule } from '@angular/core';
|
|
3
3
|
import { NgTemplateOutlet } from '@angular/common';
|
|
4
4
|
import { elementSizeSignal, injectThemeTemplate, templateTypesFn, NgnTemplate, domEventHandler, setComponentInput } from '@ngneers/controls/api/ng';
|
|
5
5
|
import { NgnBase, NgnPt, provideSelf, getNearestNgnInstance, getNearestNgnInstanceSig } from '@ngneers/controls/base';
|
|
6
|
+
import { NgnButton, NgnActionButton } from '@ngneers/controls/button';
|
|
6
7
|
import { I18n } from '@ngneers/controls/i18n';
|
|
7
8
|
import { NgnIcon } from '@ngneers/controls/icon';
|
|
8
9
|
import { NgnPaginator } from '@ngneers/controls/paginator';
|
|
@@ -14,7 +15,6 @@ import { toggleClass, NgnError } from '@ngneers/controls/utils';
|
|
|
14
15
|
import { setInputSignalValue } from '@ngneers/controls/utils-ng';
|
|
15
16
|
import { executeMultiFilter } from '@ngneers/controls/api';
|
|
16
17
|
import { openMenuAt } from '@ngneers/controls/menu';
|
|
17
|
-
import { NgnActionButton } from '@ngneers/controls/button';
|
|
18
18
|
import { NgnCheckbox } from '@ngneers/controls/checkbox';
|
|
19
19
|
import { NgnFilter } from '@ngneers/controls/filter';
|
|
20
20
|
|
|
@@ -514,6 +514,144 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
514
514
|
}]
|
|
515
515
|
}], ctorParameters: () => [], propDecorators: { ngnTableGroupHeaderTr: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngnTableGroupHeaderTr", required: true }] }], ngnScrollerItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngnScrollerItem", required: false }] }] } });
|
|
516
516
|
|
|
517
|
+
/**
|
|
518
|
+
* Owns lazy-loading state for {@link NgnTable}: the loaded row window,
|
|
519
|
+
* request status, per-page cache, and an epoch that invalidates on
|
|
520
|
+
* sort/filter/pageSize/dataSource change. Plain signal class (no DI), mirroring
|
|
521
|
+
* `TableSelectionModel`.
|
|
522
|
+
*/
|
|
523
|
+
class TableLazyModel {
|
|
524
|
+
_deps;
|
|
525
|
+
loaded = signal([], /* @ts-ignore */
|
|
526
|
+
...(ngDevMode ? [{ debugName: "loaded" }] : /* istanbul ignore next */ []));
|
|
527
|
+
status = signal('idle', /* @ts-ignore */
|
|
528
|
+
...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
|
|
529
|
+
error = signal(null, /* @ts-ignore */
|
|
530
|
+
...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
|
|
531
|
+
total = signal(undefined, /* @ts-ignore */
|
|
532
|
+
...(ngDevMode ? [{ debugName: "total" }] : /* istanbul ignore next */ []));
|
|
533
|
+
hasMore = signal(true, /* @ts-ignore */
|
|
534
|
+
...(ngDevMode ? [{ debugName: "hasMore" }] : /* istanbul ignore next */ []));
|
|
535
|
+
/** page index -> result, valid within the current epoch. */
|
|
536
|
+
_cache = new Map();
|
|
537
|
+
_epoch = 0;
|
|
538
|
+
_controller = null;
|
|
539
|
+
_lastState = null;
|
|
540
|
+
_nextWindow = 0;
|
|
541
|
+
/** The most recent load attempt, replayed by {@link retry}. */
|
|
542
|
+
_lastLoad = null;
|
|
543
|
+
constructor(_deps) {
|
|
544
|
+
this._deps = _deps;
|
|
545
|
+
}
|
|
546
|
+
/** Load (or serve from cache) the page described by `state`. */
|
|
547
|
+
async setPage(state) {
|
|
548
|
+
this._lastState = state;
|
|
549
|
+
const cached = this._cache.get(state.page.current);
|
|
550
|
+
if (cached) {
|
|
551
|
+
// Supersede any in-flight load so it can't resolve over the cached page.
|
|
552
|
+
this._controller?.abort();
|
|
553
|
+
this._controller = null;
|
|
554
|
+
this.loaded.set(cached.rows);
|
|
555
|
+
this.total.set(cached.total);
|
|
556
|
+
this.hasMore.set(cached.hasMore);
|
|
557
|
+
this.status.set('idle');
|
|
558
|
+
this.error.set(null);
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
await this._load(state, 'replace');
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Invalidate everything and refetch the current page/window from scratch.
|
|
565
|
+
* No-op if {@link setPage} has never been called (nothing to refetch yet).
|
|
566
|
+
*/
|
|
567
|
+
async reload() {
|
|
568
|
+
const state = this._lastState;
|
|
569
|
+
// Capture the cursor before _bumpEpoch clears the cache it's read from.
|
|
570
|
+
const cursor = state ? this.cursorFor(state.page.current) : undefined;
|
|
571
|
+
this._bumpEpoch();
|
|
572
|
+
if (state)
|
|
573
|
+
await this._load(state, 'replace', cursor);
|
|
574
|
+
}
|
|
575
|
+
/** Called by the component when sort/filter/pageSize/dataSource change. */
|
|
576
|
+
invalidate() {
|
|
577
|
+
this._bumpEpoch();
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Infinite scroll: load and append the next window of `pageSize` rows.
|
|
581
|
+
* No-op while a load is in flight or when `hasMore` is false.
|
|
582
|
+
*/
|
|
583
|
+
async loadNext(pageSize) {
|
|
584
|
+
if (this.status() === 'loading' || !this.hasMore())
|
|
585
|
+
return;
|
|
586
|
+
const current = this._nextWindow;
|
|
587
|
+
const state = {
|
|
588
|
+
page: { current, size: pageSize },
|
|
589
|
+
slice: { skip: current * pageSize, take: pageSize },
|
|
590
|
+
};
|
|
591
|
+
await this._load(state, 'append');
|
|
592
|
+
}
|
|
593
|
+
/** Re-issue the last load attempt after a rejection; keeps loaded rows in infinite scroll. */
|
|
594
|
+
async retry() {
|
|
595
|
+
const last = this._lastLoad;
|
|
596
|
+
if (last)
|
|
597
|
+
await this._load(last.state, last.apply, last.cursor);
|
|
598
|
+
}
|
|
599
|
+
cursorFor(pageIndex) {
|
|
600
|
+
return this._cache.get(pageIndex - 1)?.cursor;
|
|
601
|
+
}
|
|
602
|
+
_bumpEpoch() {
|
|
603
|
+
this._epoch++;
|
|
604
|
+
this._cache.clear();
|
|
605
|
+
this._controller?.abort();
|
|
606
|
+
this._controller = null;
|
|
607
|
+
this.loaded.set([]);
|
|
608
|
+
this.total.set(undefined);
|
|
609
|
+
this.hasMore.set(true);
|
|
610
|
+
this.status.set('idle');
|
|
611
|
+
this.error.set(null);
|
|
612
|
+
this._nextWindow = 0;
|
|
613
|
+
this._lastLoad = null;
|
|
614
|
+
}
|
|
615
|
+
async _load(state, apply, cursorOverride) {
|
|
616
|
+
const loader = this._deps.dataSource();
|
|
617
|
+
if (!loader)
|
|
618
|
+
return;
|
|
619
|
+
const cursor = cursorOverride ?? this.cursorFor(state.page.current);
|
|
620
|
+
this._lastLoad = { state, apply, cursor };
|
|
621
|
+
const epoch = this._epoch;
|
|
622
|
+
this._controller?.abort();
|
|
623
|
+
const controller = new AbortController();
|
|
624
|
+
this._controller = controller;
|
|
625
|
+
this.status.set('loading');
|
|
626
|
+
this.error.set(null);
|
|
627
|
+
try {
|
|
628
|
+
const result = await loader({
|
|
629
|
+
pagination: state,
|
|
630
|
+
sort: this._deps.sort(),
|
|
631
|
+
filters: this._deps.filters(),
|
|
632
|
+
cursor,
|
|
633
|
+
signal: controller.signal,
|
|
634
|
+
});
|
|
635
|
+
if (epoch !== this._epoch || controller !== this._controller)
|
|
636
|
+
return; // superseded
|
|
637
|
+
this._cache.set(state.page.current, result);
|
|
638
|
+
this.total.set(result.total);
|
|
639
|
+
this.hasMore.set(result.hasMore);
|
|
640
|
+
this.loaded.set(apply === 'append' ? [...this.loaded(), ...result.rows] : result.rows);
|
|
641
|
+
// Advance only on success, so a failed append retries the same window.
|
|
642
|
+
if (apply === 'append')
|
|
643
|
+
this._nextWindow = state.page.current + 1;
|
|
644
|
+
this.status.set('idle');
|
|
645
|
+
}
|
|
646
|
+
catch (err) {
|
|
647
|
+
if (epoch !== this._epoch || controller !== this._controller || controller.signal.aborted)
|
|
648
|
+
return;
|
|
649
|
+
this.error.set(err);
|
|
650
|
+
this.status.set('error');
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
517
655
|
/** Applies the active multi-column filter set. Returns the input untouched when no filters are set. */
|
|
518
656
|
function filterRows(rows, filters) {
|
|
519
657
|
if (!filters) {
|
|
@@ -935,23 +1073,32 @@ class NgnTableTemplates extends NgnBase {
|
|
|
935
1073
|
...(ngDevMode ? [{ debugName: "_bodyTemplate" }] : /* istanbul ignore next */ []));
|
|
936
1074
|
_groupHeaderTemplate = contentChild('groupHeader', /* @ts-ignore */
|
|
937
1075
|
...(ngDevMode ? [{ debugName: "_groupHeaderTemplate" }] : /* istanbul ignore next */ []));
|
|
1076
|
+
_loadingTemplate = contentChild('loading', /* @ts-ignore */
|
|
1077
|
+
...(ngDevMode ? [{ debugName: "_loadingTemplate" }] : /* istanbul ignore next */ []));
|
|
1078
|
+
_errorTemplate = contentChild('error', /* @ts-ignore */
|
|
1079
|
+
...(ngDevMode ? [{ debugName: "_errorTemplate" }] : /* istanbul ignore next */ []));
|
|
938
1080
|
headerTemplate = this._headerTemplate;
|
|
939
1081
|
bodyTemplate = this._bodyTemplate;
|
|
940
1082
|
groupHeaderTemplate = this._groupHeaderTemplate;
|
|
1083
|
+
/** Custom rows shown while a lazy load is in flight, via `<ng-template #loading>`. */
|
|
1084
|
+
loadingTemplate = this._loadingTemplate;
|
|
1085
|
+
/** Custom error row via `<ng-template #error>`; receives `{ error, retry }`, where `retry` re-issues the failed load. */
|
|
1086
|
+
errorTemplate = this._errorTemplate;
|
|
941
1087
|
/**
|
|
942
1088
|
* Types for the table templates.
|
|
943
1089
|
*/
|
|
944
1090
|
templateTypes = templateTypesFn();
|
|
945
1091
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnTableTemplates, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
946
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.5", type: NgnTableTemplates, isStandalone: true, selector: "ng-component", queries: [{ propertyName: "_headerTemplate", first: true, predicate: ["header"], descendants: true, isSignal: true }, { propertyName: "_bodyTemplate", first: true, predicate: ["body"], descendants: true, isSignal: true }, { propertyName: "_groupHeaderTemplate", first: true, predicate: ["groupHeader"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: '', isInline: true });
|
|
1092
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.5", type: NgnTableTemplates, isStandalone: true, selector: "ng-component", queries: [{ propertyName: "_headerTemplate", first: true, predicate: ["header"], descendants: true, isSignal: true }, { propertyName: "_bodyTemplate", first: true, predicate: ["body"], descendants: true, isSignal: true }, { propertyName: "_groupHeaderTemplate", first: true, predicate: ["groupHeader"], descendants: true, isSignal: true }, { propertyName: "_loadingTemplate", first: true, predicate: ["loading"], descendants: true, isSignal: true }, { propertyName: "_errorTemplate", first: true, predicate: ["error"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: '', isInline: true });
|
|
947
1093
|
}
|
|
948
1094
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnTableTemplates, decorators: [{
|
|
949
1095
|
type: Component,
|
|
950
1096
|
args: [{
|
|
951
1097
|
template: '',
|
|
952
1098
|
}]
|
|
953
|
-
}], propDecorators: { _headerTemplate: [{ type: i0.ContentChild, args: ['header', { isSignal: true }] }], _bodyTemplate: [{ type: i0.ContentChild, args: ['body', { isSignal: true }] }], _groupHeaderTemplate: [{ type: i0.ContentChild, args: ['groupHeader', { isSignal: true }] }] } });
|
|
1099
|
+
}], propDecorators: { _headerTemplate: [{ type: i0.ContentChild, args: ['header', { isSignal: true }] }], _bodyTemplate: [{ type: i0.ContentChild, args: ['body', { isSignal: true }] }], _groupHeaderTemplate: [{ type: i0.ContentChild, args: ['groupHeader', { isSignal: true }] }], _loadingTemplate: [{ type: i0.ContentChild, args: ['loading', { isSignal: true }] }], _errorTemplate: [{ type: i0.ContentChild, args: ['error', { isSignal: true }] }] } });
|
|
954
1100
|
|
|
1101
|
+
const DEFAULT_LAZY_PAGE_SIZE = 25;
|
|
955
1102
|
/**
|
|
956
1103
|
* @category control
|
|
957
1104
|
*/
|
|
@@ -963,10 +1110,11 @@ class NgnTable extends NgnTableTemplates {
|
|
|
963
1110
|
selectable: () => !!this.selectionMode(),
|
|
964
1111
|
reorderable: () => this.reorderable(),
|
|
965
1112
|
reordering: () => this._columns?.isReordering() ?? false,
|
|
1113
|
+
loading: () => this.loadStatus() === 'loading',
|
|
966
1114
|
});
|
|
967
1115
|
_scroller = viewChild.required(NgnScroller);
|
|
968
|
-
/** The data rows to render. */
|
|
969
|
-
rows = input
|
|
1116
|
+
/** The data rows to render in client-side mode. Ignored when {@link dataSource} is set. */
|
|
1117
|
+
rows = input([], /* @ts-ignore */
|
|
970
1118
|
...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
971
1119
|
/**
|
|
972
1120
|
* When {@link virtual} is enabled, this defines the height of each row in pixels.
|
|
@@ -1000,6 +1148,27 @@ class NgnTable extends NgnTableTemplates {
|
|
|
1000
1148
|
*/
|
|
1001
1149
|
paginator = input(false, /* @ts-ignore */
|
|
1002
1150
|
...(ngDevMode ? [{ debugName: "paginator" }] : /* istanbul ignore next */ []));
|
|
1151
|
+
/**
|
|
1152
|
+
* A loader callback for server-driven lazy loading. When set, the table fetches
|
|
1153
|
+
* rows on demand instead of reading {@link rows}, and client-side sort/filter are
|
|
1154
|
+
* delegated to the loader. With {@link paginator} it pages lazily; without, it
|
|
1155
|
+
* infinite-scrolls. Incompatible with {@link groupBy} (throws).
|
|
1156
|
+
*
|
|
1157
|
+
* @remarks Bind to a stable reference (a class field/method), not an inline
|
|
1158
|
+
* arrow — a new function identity each change-detection cycle invalidates the
|
|
1159
|
+
* page cache and refetches every cycle.
|
|
1160
|
+
* @default null
|
|
1161
|
+
*/
|
|
1162
|
+
dataSource = input(null, /* @ts-ignore */
|
|
1163
|
+
...(ngDevMode ? [{ debugName: "dataSource" }] : /* istanbul ignore next */ []));
|
|
1164
|
+
/**
|
|
1165
|
+
* Infinite scroll only: set by the header select-all checkbox to request a
|
|
1166
|
+
* "select everything matching the current filters" bulk operation, since the
|
|
1167
|
+
* full set is not loaded. Two-way bindable.
|
|
1168
|
+
* @default false
|
|
1169
|
+
*/
|
|
1170
|
+
selectAllMatching = model(false, /* @ts-ignore */
|
|
1171
|
+
...(ngDevMode ? [{ debugName: "selectAllMatching" }] : /* istanbul ignore next */ []));
|
|
1003
1172
|
/**
|
|
1004
1173
|
* The selection mode for the table.
|
|
1005
1174
|
* - `'single'`: Only one row can be selected at a time.
|
|
@@ -1091,6 +1260,21 @@ class NgnTable extends NgnTableTemplates {
|
|
|
1091
1260
|
...(ngDevMode ? [{ debugName: "filters" }] : /* istanbul ignore next */ []));
|
|
1092
1261
|
pageState = signal(null, /* @ts-ignore */
|
|
1093
1262
|
...(ngDevMode ? [{ debugName: "pageState" }] : /* istanbul ignore next */ []));
|
|
1263
|
+
// --- Lazy (server-driven) loading ---
|
|
1264
|
+
lazy = computed(() => !!this.dataSource(), /* @ts-ignore */
|
|
1265
|
+
...(ngDevMode ? [{ debugName: "lazy" }] : /* istanbul ignore next */ []));
|
|
1266
|
+
lazyMode = computed(() => this.paginator() ? 'paginate' : 'infinite', /* @ts-ignore */
|
|
1267
|
+
...(ngDevMode ? [{ debugName: "lazyMode" }] : /* istanbul ignore next */ []));
|
|
1268
|
+
_lazyModel = new TableLazyModel({
|
|
1269
|
+
dataSource: this.dataSource,
|
|
1270
|
+
sort: this.sort,
|
|
1271
|
+
filters: computed(() => this.filters()),
|
|
1272
|
+
mode: this.lazyMode,
|
|
1273
|
+
});
|
|
1274
|
+
loadStatus = this._lazyModel.status;
|
|
1275
|
+
loadError = this._lazyModel.error;
|
|
1276
|
+
loadTotal = this._lazyModel.total;
|
|
1277
|
+
lazyHasMore = this._lazyModel.hasMore;
|
|
1094
1278
|
i18n = inject(I18n).translations;
|
|
1095
1279
|
/**
|
|
1096
1280
|
* Polite live-region text announcing sort / filter / pagination / selection
|
|
@@ -1144,6 +1328,15 @@ class NgnTable extends NgnTableTemplates {
|
|
|
1144
1328
|
*/
|
|
1145
1329
|
totalColumnCount = computed(() => this._columns.columnCount() + (this._columns.hasSelectionColumn() ? 1 : 0), /* @ts-ignore */
|
|
1146
1330
|
...(ngDevMode ? [{ debugName: "totalColumnCount" }] : /* istanbul ignore next */ []));
|
|
1331
|
+
/** Number of placeholder rows to show while a lazy load is in flight. */
|
|
1332
|
+
skeletonRows = computed(() => {
|
|
1333
|
+
if (this.loadStatus() !== 'loading')
|
|
1334
|
+
return 0;
|
|
1335
|
+
return this.paginator()
|
|
1336
|
+
? (this.pageState()?.page.size ?? DEFAULT_LAZY_PAGE_SIZE)
|
|
1337
|
+
: this.virtualPadding() * 2 + 1;
|
|
1338
|
+
}, /* @ts-ignore */
|
|
1339
|
+
...(ngDevMode ? [{ debugName: "skeletonRows" }] : /* istanbul ignore next */ []));
|
|
1147
1340
|
formattedRows = computed(() => {
|
|
1148
1341
|
const groupBy = this.groupBy();
|
|
1149
1342
|
if (groupBy) {
|
|
@@ -1166,15 +1359,27 @@ class NgnTable extends NgnTableTemplates {
|
|
|
1166
1359
|
}, /* @ts-ignore */
|
|
1167
1360
|
...(ngDevMode ? [{ debugName: "_groupedRows" }] : /* istanbul ignore next */ []));
|
|
1168
1361
|
pagedRows = computed(() => {
|
|
1169
|
-
|
|
1362
|
+
// Lazy pagination clears rows while fetching so skeletons replace the page.
|
|
1363
|
+
if (this.lazy() && this.lazyMode() === 'paginate' && this.loadStatus() === 'loading') {
|
|
1364
|
+
return [];
|
|
1365
|
+
}
|
|
1366
|
+
// Lazy loaders return exactly one page — never re-slice client-side.
|
|
1367
|
+
if (!this.paginator() || this.lazy()) {
|
|
1170
1368
|
return this.formattedRows();
|
|
1171
1369
|
}
|
|
1172
1370
|
return [...paginateRows(this.formattedRows(), this.pageState())];
|
|
1173
1371
|
}, /* @ts-ignore */
|
|
1174
1372
|
...(ngDevMode ? [{ debugName: "pagedRows" }] : /* istanbul ignore next */ []));
|
|
1175
|
-
|
|
1373
|
+
_baseRows = computed(() => this.lazy() ? this._lazyModel.loaded() : this.rows(), /* @ts-ignore */
|
|
1374
|
+
...(ngDevMode ? [{ debugName: "_baseRows" }] : /* istanbul ignore next */ []));
|
|
1375
|
+
_filteredRows = computed(() => this.lazy() ? this._baseRows() : filterRows(this._baseRows(), this.filters()), /* @ts-ignore */
|
|
1176
1376
|
...(ngDevMode ? [{ debugName: "_filteredRows" }] : /* istanbul ignore next */ []));
|
|
1177
|
-
|
|
1377
|
+
/** Page size only — page navigation must not invalidate the per-page cache. */
|
|
1378
|
+
_lazyPageSize = computed(() => this.pageState()?.page.size, /* @ts-ignore */
|
|
1379
|
+
...(ngDevMode ? [{ debugName: "_lazyPageSize" }] : /* istanbul ignore next */ []));
|
|
1380
|
+
_sortedRows = computed(() => this.lazy()
|
|
1381
|
+
? this._baseRows()
|
|
1382
|
+
: sortRows(this._filteredRows(), this.sort(), this.sortComparator()), /* @ts-ignore */
|
|
1178
1383
|
...(ngDevMode ? [{ debugName: "_sortedRows" }] : /* istanbul ignore next */ []));
|
|
1179
1384
|
constructor() {
|
|
1180
1385
|
super();
|
|
@@ -1197,7 +1402,9 @@ class NgnTable extends NgnTableTemplates {
|
|
|
1197
1402
|
openMenu: index => this.getRowActions(index)?.openMenuFromKeyboard() ?? false,
|
|
1198
1403
|
focusHost: () => this.element.nativeElement.focus(),
|
|
1199
1404
|
});
|
|
1200
|
-
this.headerCheckboxValue = computed(() => this.
|
|
1405
|
+
this.headerCheckboxValue = computed(() => this.lazy() && this.lazyMode() === 'infinite'
|
|
1406
|
+
? this.selectAllMatching()
|
|
1407
|
+
: this._selection.headerCheckboxValue(), /* @ts-ignore */
|
|
1201
1408
|
...(ngDevMode ? [{ debugName: "headerCheckboxValue" }] : /* istanbul ignore next */ []));
|
|
1202
1409
|
// Minor #3: clear the current-row highlight whenever the underlying row
|
|
1203
1410
|
// set changes identity (sort/filter/rows replaced), so it never lingers
|
|
@@ -1221,9 +1428,13 @@ class NgnTable extends NgnTableTemplates {
|
|
|
1221
1428
|
let prevSelCount = 0;
|
|
1222
1429
|
effect(() => {
|
|
1223
1430
|
const sort = this.sort();
|
|
1224
|
-
|
|
1431
|
+
// Lazy: announce the server total; fall back to the loaded window count.
|
|
1432
|
+
const filterCount = this.lazy()
|
|
1433
|
+
? (this.loadTotal() ?? this._filteredRows().length)
|
|
1434
|
+
: this._filteredRows().length;
|
|
1225
1435
|
const page = this.pageState();
|
|
1226
1436
|
const selCount = this.selection().length;
|
|
1437
|
+
const selTotal = this.lazy() ? (this.loadTotal() ?? this.rows().length) : this.rows().length;
|
|
1227
1438
|
const sortKey = sort ? `${sort.column}:${sort.direction}` : '';
|
|
1228
1439
|
const pageKey = page ? `${page.page.current}/${page.page.size}` : '';
|
|
1229
1440
|
if (!seeded) {
|
|
@@ -1254,7 +1465,7 @@ class NgnTable extends NgnTableTemplates {
|
|
|
1254
1465
|
message = this.i18n['table_page']({ page: (page?.page.current ?? 0) + 1, pages });
|
|
1255
1466
|
}
|
|
1256
1467
|
else if (selCount !== prevSelCount) {
|
|
1257
|
-
message = this.i18n['table_selectedCount']({ count: selCount, total:
|
|
1468
|
+
message = this.i18n['table_selectedCount']({ count: selCount, total: selTotal });
|
|
1258
1469
|
}
|
|
1259
1470
|
[prevSort, prevFilterCount, prevPageKey, prevSelCount] = [
|
|
1260
1471
|
sortKey,
|
|
@@ -1266,6 +1477,57 @@ class NgnTable extends NgnTableTemplates {
|
|
|
1266
1477
|
this.liveAnnouncement.set(message);
|
|
1267
1478
|
}
|
|
1268
1479
|
});
|
|
1480
|
+
// Lazy grouping needs the full row set, which lazy mode never has.
|
|
1481
|
+
effect(() => {
|
|
1482
|
+
if (this.lazy() && this.groupBy()) {
|
|
1483
|
+
throw new NgnError('table', 'groupBy is not supported with a lazy dataSource (v1)');
|
|
1484
|
+
}
|
|
1485
|
+
});
|
|
1486
|
+
// Reset the lazy cache when sort, filter, page size or dataSource change.
|
|
1487
|
+
effect(() => {
|
|
1488
|
+
this.sort();
|
|
1489
|
+
this.filters();
|
|
1490
|
+
this._lazyPageSize();
|
|
1491
|
+
this.dataSource();
|
|
1492
|
+
if (!this.lazy())
|
|
1493
|
+
return;
|
|
1494
|
+
untracked(() => this._lazyModel.invalidate());
|
|
1495
|
+
});
|
|
1496
|
+
// Lazy pagination: load the current page when it, sort, filters or dataSource change.
|
|
1497
|
+
effect(() => {
|
|
1498
|
+
const state = this.pageState();
|
|
1499
|
+
this.sort();
|
|
1500
|
+
this.filters();
|
|
1501
|
+
this.dataSource();
|
|
1502
|
+
if (!this.lazy() || this.lazyMode() !== 'paginate' || !state)
|
|
1503
|
+
return;
|
|
1504
|
+
untracked(() => void this._lazyModel.setPage(state));
|
|
1505
|
+
});
|
|
1506
|
+
// Infinite scroll: load the next window when the viewport nears the end.
|
|
1507
|
+
effect(() => {
|
|
1508
|
+
if (!this.lazy() || this.lazyMode() !== 'infinite')
|
|
1509
|
+
return;
|
|
1510
|
+
const distance = this._scroller().distanceFromEnd();
|
|
1511
|
+
const threshold = (this.rowHeight() ?? 40) * this.virtualPadding();
|
|
1512
|
+
const pageSize = this.pageState()?.page.size ?? DEFAULT_LAZY_PAGE_SIZE;
|
|
1513
|
+
if (distance <= threshold) {
|
|
1514
|
+
untracked(() => void this._lazyModel.loadNext(pageSize));
|
|
1515
|
+
}
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
/** Force a lazy refetch, clearing the page cache. No-op in client-side mode. */
|
|
1519
|
+
reload() {
|
|
1520
|
+
// Infinite scroll has no current page — restart from the first window.
|
|
1521
|
+
if (this.lazy() && this.lazyMode() === 'infinite') {
|
|
1522
|
+
this._lazyModel.invalidate();
|
|
1523
|
+
void this._lazyModel.loadNext(this.pageState()?.page.size ?? DEFAULT_LAZY_PAGE_SIZE);
|
|
1524
|
+
return;
|
|
1525
|
+
}
|
|
1526
|
+
void this._lazyModel.reload();
|
|
1527
|
+
}
|
|
1528
|
+
/** Retry the failed load, keeping already-loaded rows in infinite scroll. */
|
|
1529
|
+
retryLoad() {
|
|
1530
|
+
void this._lazyModel.retry();
|
|
1269
1531
|
}
|
|
1270
1532
|
pageChanged(event) {
|
|
1271
1533
|
this.pageState.set(event);
|
|
@@ -1341,6 +1603,10 @@ class NgnTable extends NgnTableTemplates {
|
|
|
1341
1603
|
this._selection.handleCheckboxChange(row);
|
|
1342
1604
|
}
|
|
1343
1605
|
toggleSelectAll() {
|
|
1606
|
+
if (this.lazy() && this.lazyMode() === 'infinite') {
|
|
1607
|
+
this.selectAllMatching.update(v => !v);
|
|
1608
|
+
return;
|
|
1609
|
+
}
|
|
1344
1610
|
this._selection.toggleSelectAll();
|
|
1345
1611
|
}
|
|
1346
1612
|
// --- Row actions registry ---
|
|
@@ -1405,7 +1671,7 @@ class NgnTable extends NgnTableTemplates {
|
|
|
1405
1671
|
this.toggleGroup(row.groupKey);
|
|
1406
1672
|
}
|
|
1407
1673
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnTable, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1408
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: NgnTable, isStandalone: true, selector: "ngn-table", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired:
|
|
1674
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: NgnTable, isStandalone: true, selector: "ngn-table", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: false, transformFunction: null }, fieldId: { classPropertyName: "fieldId", publicName: "fieldId", isSignal: true, isRequired: true, transformFunction: null }, virtual: { classPropertyName: "virtual", publicName: "virtual", isSignal: true, isRequired: false, transformFunction: null }, virtualPadding: { classPropertyName: "virtualPadding", publicName: "virtualPadding", isSignal: true, isRequired: false, transformFunction: null }, striped: { classPropertyName: "striped", publicName: "striped", isSignal: true, isRequired: false, transformFunction: null }, paginator: { classPropertyName: "paginator", publicName: "paginator", isSignal: true, isRequired: false, transformFunction: null }, dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null }, selectAllMatching: { classPropertyName: "selectAllMatching", publicName: "selectAllMatching", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, groupBy: { classPropertyName: "groupBy", publicName: "groupBy", isSignal: true, isRequired: false, transformFunction: null }, expandedGroups: { classPropertyName: "expandedGroups", publicName: "expandedGroups", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, resizeMode: { classPropertyName: "resizeMode", publicName: "resizeMode", isSignal: true, isRequired: false, transformFunction: null }, lockSizes: { classPropertyName: "lockSizes", publicName: "lockSizes", isSignal: true, isRequired: false, transformFunction: null }, reorderable: { classPropertyName: "reorderable", publicName: "reorderable", isSignal: true, isRequired: false, transformFunction: null }, columnOrder: { classPropertyName: "columnOrder", publicName: "columnOrder", isSignal: true, isRequired: false, transformFunction: null }, sort: { classPropertyName: "sort", publicName: "sort", isSignal: true, isRequired: false, transformFunction: null }, sortComparator: { classPropertyName: "sortComparator", publicName: "sortComparator", isSignal: true, isRequired: false, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectAllMatching: "selectAllMatchingChange", selection: "selectionChange", expandedGroups: "expandedGroupsChange", columnOrder: "columnOrderChange", sort: "sortChange", filters: "filtersChange" }, host: { attributes: { "tabindex": "0" }, listeners: { "keydown": "onKeyDown($event)" } }, providers: [provideSelf(NgnTable)], viewQueries: [{ propertyName: "_scroller", first: true, predicate: NgnScroller, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<span\n aria-live=\"polite\"\n aria-atomic=\"true\"\n style=\"\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0 0 0 0);\n white-space: nowrap;\n border: 0;\n \"\n >{{ liveAnnouncement() }}</span\n>\n<table\n #scrollContainer\n role=\"grid\"\n ngnScrollShadow=\"horizontal\"\n ngnScrollShadowUnstyled\n [ptInt]=\"this\"\n [ptClass]=\"{ table: true, striped: striped() }\"\n [attr.aria-multiselectable]=\"selectionMode() === 'multi' ? true : null\"\n [attr.aria-rowcount]=\"formattedRows().length\"\n [style.--ngn-table-column-count]=\"totalColumnCount()\"\n [style.--ngn-table-selection-offset]=\"showCheckboxes() ? 1 : 0\"\n [style.grid-template-columns]=\"gridTemplateColumns()\"\n [style.--ngn-table-row-height.px]=\"rowHeight()\"\n>\n <thead role=\"rowgroup\" [ptInt]=\"this\" [ptClass]=\"'head'\">\n <ng-container [ngTemplateOutlet]=\"headerTemplate()\"></ng-container>\n </thead>\n @if (dropIndicatorState()) {\n <div\n [ptInt]=\"this\"\n [ptClass]=\"'drop-indicator'\"\n [style.left.px]=\"dropIndicatorState()!.leftPx\"\n [style.top.px]=\"dropIndicatorState()!.topPx\"\n [style.height.px]=\"dropIndicatorState()!.heightPx\"\n ></div>\n }\n\n <tbody\n role=\"rowgroup\"\n [ptInt]=\"this\"\n [ptClass]=\"'body'\"\n [ptDep]=\"'scroller'\"\n ngn-scroller\n #scroller\n [scrollContainer]=\"scrollContainer\"\n [virtual]=\"virtual()\"\n [items]=\"pagedRows()\"\n [fieldId]=\"'id'\"\n [itemHeight]=\"rowHeight() || 0\"\n [virtualPadding]=\"virtualPadding()\"\n [style.--ngn-table-item-start-index]=\"scroller.itemStartIndex()\"\n >\n <ng-template #item [ngnTemplate]=\"scroller.templateTypes.item\" let-item let-index=\"index\">\n @if (item.kind === 'group-header') {\n @if (groupHeaderTemplate(); as customGroupHeader) {\n <ng-container\n [ngTemplateOutlet]=\"customGroupHeader\"\n [ngTemplateOutletContext]=\"{\n $implicit: {\n groupKey: item.groupKey,\n groupValue: item.groupValue,\n count: item.count,\n expanded: item.expanded,\n },\n }\"\n ></ng-container>\n } @else {\n <tr\n [ngnTableGroupHeaderTr]=\"item\"\n [class]=\"theme.classes({ 'group-expanded': item.expanded })\"\n [attr.aria-expanded]=\"item.expanded\"\n role=\"row\"\n (click)=\"toggleGroupFromRow(item)\"\n >\n <td [class]=\"theme.class('group-header-cell')\" role=\"gridcell\">\n <ngn-icon\n [ptInt]=\"this\"\n [ptClass]=\"'group-toggle'\"\n [ptDep]=\"'group-toggle-icon'\"\n [defaultIcon]=\"'table-group-toggle'\"\n />\n <span>{{ item.groupValue }}</span>\n <span>({{ item.count }})</span>\n </td>\n </tr>\n }\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"bodyTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n ></ng-container>\n }\n </ng-template>\n @if (skeletonRows() > 0) {\n @if (loadingTemplate(); as customLoading) {\n <ng-container [ngTemplateOutlet]=\"customLoading\"></ng-container>\n } @else {\n @for (i of [].constructor(skeletonRows()); track $index) {\n <tr [class]=\"theme.class('skeleton-row')\" role=\"row\" aria-hidden=\"true\">\n <td [class]=\"theme.class('skeleton-cell')\" role=\"gridcell\"></td>\n </tr>\n }\n }\n }\n @if (loadStatus() === 'error') {\n @if (errorTemplate(); as customError) {\n <ng-container\n [ngTemplateOutlet]=\"customError\"\n [ngTemplateOutletContext]=\"{\n $implicit: { error: loadError(), retry: retryLoad.bind(this) },\n }\"\n ></ng-container>\n } @else {\n <tr [class]=\"theme.class('error-row')\" role=\"row\">\n <td [attr.colspan]=\"totalColumnCount()\" role=\"gridcell\">\n <span>{{ i18n['table_loadError']() }}</span>\n <button ngnButton [kind]=\"'text'\" (click)=\"retryLoad()\">\n {{ i18n['table_retry']() }}\n </button>\n </td>\n </tr>\n }\n }\n </tbody>\n</table>\n@if (paginator()) {\n <ngn-paginator\n [ptInt]=\"this\"\n [ptDep]=\"'paginator'\"\n [mode]=\"lazy() && loadTotal() === undefined ? 'compact' : 'pages'\"\n [totalItems]=\"lazy() ? (loadTotal() ?? 0) : rows().length\"\n [hasNext]=\"lazyHasMore()\"\n (value)=\"pageChanged($event)\"\n />\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NgnScroller, selector: "ngn-scroller, [ngn-scroller]", inputs: ["items", "fieldId", "virtual", "itemHeight", "virtualPadding", "focusable", "fieldSticky"] }, { kind: "component", type: NgnPaginator, selector: "ngn-paginator", inputs: ["totalItems", "pageSize", "mode", "hasNext", "possiblePageSizes", "fixedPageSize", "page"], outputs: ["pageSizeChange", "value", "pageChange"] }, { kind: "directive", type: NgnTemplate, selector: "ng-template[ngnTemplate]", inputs: ["ngnTemplate"] }, { kind: "directive", type: NgnPt, selector: "[ptInt]", inputs: ["ptInt", "ptClass", "ptDep"] }, { kind: "component", type: NgnIcon, selector: "ngn-icon", inputs: ["defaultIcon", "icon"] }, { kind: "directive", type: NgnTableGroupHeaderTr, selector: "[ngnTableGroupHeaderTr]", inputs: ["ngnTableGroupHeaderTr", "ngnScrollerItem"] }, { kind: "directive", type: NgnScrollShadow, selector: "[ngnScrollShadow]", inputs: ["ngnScrollShadow", "scrollShadowTarget", "ngnScrollShadowUnstyled"] }, { kind: "directive", type: NgnButton, selector: "button[ngnButton], a[ngnButton]", inputs: ["ngnButtonInline"], exportAs: ["ngnButton"] }] });
|
|
1409
1675
|
}
|
|
1410
1676
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NgnTable, decorators: [{
|
|
1411
1677
|
type: Component,
|
|
@@ -1418,11 +1684,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
1418
1684
|
NgnIcon,
|
|
1419
1685
|
NgnTableGroupHeaderTr,
|
|
1420
1686
|
NgnScrollShadow,
|
|
1687
|
+
NgnButton,
|
|
1421
1688
|
], providers: [provideSelf(NgnTable)], host: {
|
|
1422
1689
|
tabindex: '0',
|
|
1423
1690
|
'(keydown)': 'onKeyDown($event)',
|
|
1424
|
-
}, template: "<span\n aria-live=\"polite\"\n aria-atomic=\"true\"\n style=\"\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0 0 0 0);\n white-space: nowrap;\n border: 0;\n \"\n >{{ liveAnnouncement() }}</span\n>\n<table\n #scrollContainer\n role=\"grid\"\n ngnScrollShadow=\"horizontal\"\n [ptInt]=\"this\"\n [ptClass]=\"{ table: true, striped: striped() }\"\n [attr.aria-multiselectable]=\"selectionMode() === 'multi' ? true : null\"\n [attr.aria-rowcount]=\"formattedRows().length\"\n [style.--ngn-table-column-count]=\"totalColumnCount()\"\n [style.--ngn-table-selection-offset]=\"showCheckboxes() ? 1 : 0\"\n [style.grid-template-columns]=\"gridTemplateColumns()\"\n [style.--ngn-table-row-height.px]=\"rowHeight()\"\n>\n <thead role=\"rowgroup\" [ptInt]=\"this\" [ptClass]=\"'head'\">\n <ng-container [ngTemplateOutlet]=\"headerTemplate()\"></ng-container>\n </thead>\n @if (dropIndicatorState()) {\n <div\n [ptInt]=\"this\"\n [ptClass]=\"'drop-indicator'\"\n [style.left.px]=\"dropIndicatorState()!.leftPx\"\n [style.top.px]=\"dropIndicatorState()!.topPx\"\n [style.height.px]=\"dropIndicatorState()!.heightPx\"\n ></div>\n }\n\n <tbody\n role=\"rowgroup\"\n [ptInt]=\"this\"\n [ptClass]=\"'body'\"\n [ptDep]=\"'scroller'\"\n ngn-scroller\n #scroller\n [scrollContainer]=\"scrollContainer\"\n [virtual]=\"virtual()\"\n [items]=\"pagedRows()\"\n [fieldId]=\"'id'\"\n [itemHeight]=\"rowHeight() || 0\"\n [virtualPadding]=\"virtualPadding()\"\n [style.--ngn-table-item-start-index]=\"scroller.itemStartIndex()\"\n >\n <ng-template #item [ngnTemplate]=\"scroller.templateTypes.item\" let-item let-index=\"index\">\n @if (item.kind === 'group-header') {\n @if (groupHeaderTemplate(); as customGroupHeader) {\n <ng-container\n [ngTemplateOutlet]=\"customGroupHeader\"\n [ngTemplateOutletContext]=\"{\n $implicit: {\n groupKey: item.groupKey,\n groupValue: item.groupValue,\n count: item.count,\n expanded: item.expanded,\n },\n }\"\n ></ng-container>\n } @else {\n <tr\n [ngnTableGroupHeaderTr]=\"item\"\n [class]=\"theme.classes({ 'group-expanded': item.expanded })\"\n [attr.aria-expanded]=\"item.expanded\"\n role=\"row\"\n (click)=\"toggleGroupFromRow(item)\"\n >\n <td [class]=\"theme.class('group-header-cell')\" role=\"gridcell\">\n <ngn-icon\n [ptInt]=\"this\"\n [ptClass]=\"'group-toggle'\"\n [ptDep]=\"'group-toggle-icon'\"\n [defaultIcon]=\"'table-group-toggle'\"\n />\n <span>{{ item.groupValue }}</span>\n <span>({{ item.count }})</span>\n </td>\n </tr>\n }\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"bodyTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n ></ng-container>\n }\n </ng-template>\n </tbody>\n</table>\n@if (paginator()) {\n <ngn-paginator\n [ptInt]=\"this\"\n [ptDep]=\"'paginator'\"\n [totalItems]=\"rows().length\"\n (value)=\"pageChanged($event)\"\n />\n}\n" }]
|
|
1425
|
-
}], ctorParameters: () => [], propDecorators: { _scroller: [{ type: i0.ViewChild, args: [i0.forwardRef(() => NgnScroller), { isSignal: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required:
|
|
1691
|
+
}, template: "<span\n aria-live=\"polite\"\n aria-atomic=\"true\"\n style=\"\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0 0 0 0);\n white-space: nowrap;\n border: 0;\n \"\n >{{ liveAnnouncement() }}</span\n>\n<table\n #scrollContainer\n role=\"grid\"\n ngnScrollShadow=\"horizontal\"\n ngnScrollShadowUnstyled\n [ptInt]=\"this\"\n [ptClass]=\"{ table: true, striped: striped() }\"\n [attr.aria-multiselectable]=\"selectionMode() === 'multi' ? true : null\"\n [attr.aria-rowcount]=\"formattedRows().length\"\n [style.--ngn-table-column-count]=\"totalColumnCount()\"\n [style.--ngn-table-selection-offset]=\"showCheckboxes() ? 1 : 0\"\n [style.grid-template-columns]=\"gridTemplateColumns()\"\n [style.--ngn-table-row-height.px]=\"rowHeight()\"\n>\n <thead role=\"rowgroup\" [ptInt]=\"this\" [ptClass]=\"'head'\">\n <ng-container [ngTemplateOutlet]=\"headerTemplate()\"></ng-container>\n </thead>\n @if (dropIndicatorState()) {\n <div\n [ptInt]=\"this\"\n [ptClass]=\"'drop-indicator'\"\n [style.left.px]=\"dropIndicatorState()!.leftPx\"\n [style.top.px]=\"dropIndicatorState()!.topPx\"\n [style.height.px]=\"dropIndicatorState()!.heightPx\"\n ></div>\n }\n\n <tbody\n role=\"rowgroup\"\n [ptInt]=\"this\"\n [ptClass]=\"'body'\"\n [ptDep]=\"'scroller'\"\n ngn-scroller\n #scroller\n [scrollContainer]=\"scrollContainer\"\n [virtual]=\"virtual()\"\n [items]=\"pagedRows()\"\n [fieldId]=\"'id'\"\n [itemHeight]=\"rowHeight() || 0\"\n [virtualPadding]=\"virtualPadding()\"\n [style.--ngn-table-item-start-index]=\"scroller.itemStartIndex()\"\n >\n <ng-template #item [ngnTemplate]=\"scroller.templateTypes.item\" let-item let-index=\"index\">\n @if (item.kind === 'group-header') {\n @if (groupHeaderTemplate(); as customGroupHeader) {\n <ng-container\n [ngTemplateOutlet]=\"customGroupHeader\"\n [ngTemplateOutletContext]=\"{\n $implicit: {\n groupKey: item.groupKey,\n groupValue: item.groupValue,\n count: item.count,\n expanded: item.expanded,\n },\n }\"\n ></ng-container>\n } @else {\n <tr\n [ngnTableGroupHeaderTr]=\"item\"\n [class]=\"theme.classes({ 'group-expanded': item.expanded })\"\n [attr.aria-expanded]=\"item.expanded\"\n role=\"row\"\n (click)=\"toggleGroupFromRow(item)\"\n >\n <td [class]=\"theme.class('group-header-cell')\" role=\"gridcell\">\n <ngn-icon\n [ptInt]=\"this\"\n [ptClass]=\"'group-toggle'\"\n [ptDep]=\"'group-toggle-icon'\"\n [defaultIcon]=\"'table-group-toggle'\"\n />\n <span>{{ item.groupValue }}</span>\n <span>({{ item.count }})</span>\n </td>\n </tr>\n }\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"bodyTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: item }\"\n ></ng-container>\n }\n </ng-template>\n @if (skeletonRows() > 0) {\n @if (loadingTemplate(); as customLoading) {\n <ng-container [ngTemplateOutlet]=\"customLoading\"></ng-container>\n } @else {\n @for (i of [].constructor(skeletonRows()); track $index) {\n <tr [class]=\"theme.class('skeleton-row')\" role=\"row\" aria-hidden=\"true\">\n <td [class]=\"theme.class('skeleton-cell')\" role=\"gridcell\"></td>\n </tr>\n }\n }\n }\n @if (loadStatus() === 'error') {\n @if (errorTemplate(); as customError) {\n <ng-container\n [ngTemplateOutlet]=\"customError\"\n [ngTemplateOutletContext]=\"{\n $implicit: { error: loadError(), retry: retryLoad.bind(this) },\n }\"\n ></ng-container>\n } @else {\n <tr [class]=\"theme.class('error-row')\" role=\"row\">\n <td [attr.colspan]=\"totalColumnCount()\" role=\"gridcell\">\n <span>{{ i18n['table_loadError']() }}</span>\n <button ngnButton [kind]=\"'text'\" (click)=\"retryLoad()\">\n {{ i18n['table_retry']() }}\n </button>\n </td>\n </tr>\n }\n }\n </tbody>\n</table>\n@if (paginator()) {\n <ngn-paginator\n [ptInt]=\"this\"\n [ptDep]=\"'paginator'\"\n [mode]=\"lazy() && loadTotal() === undefined ? 'compact' : 'pages'\"\n [totalItems]=\"lazy() ? (loadTotal() ?? 0) : rows().length\"\n [hasNext]=\"lazyHasMore()\"\n (value)=\"pageChanged($event)\"\n />\n}\n" }]
|
|
1692
|
+
}], ctorParameters: () => [], propDecorators: { _scroller: [{ type: i0.ViewChild, args: [i0.forwardRef(() => NgnScroller), { isSignal: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: false }] }], fieldId: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldId", required: true }] }], virtual: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtual", required: false }] }], virtualPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualPadding", required: false }] }], striped: [{ type: i0.Input, args: [{ isSignal: true, alias: "striped", required: false }] }], paginator: [{ type: i0.Input, args: [{ isSignal: true, alias: "paginator", required: false }] }], dataSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataSource", required: false }] }], selectAllMatching: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAllMatching", required: false }] }, { type: i0.Output, args: ["selectAllMatchingChange"] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }, { type: i0.Output, args: ["selectionChange"] }], groupBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupBy", required: false }] }], expandedGroups: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedGroups", required: false }] }, { type: i0.Output, args: ["expandedGroupsChange"] }], resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }], resizeMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizeMode", required: false }] }], lockSizes: [{ type: i0.Input, args: [{ isSignal: true, alias: "lockSizes", required: false }] }], reorderable: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderable", required: false }] }], columnOrder: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnOrder", required: false }] }, { type: i0.Output, args: ["columnOrderChange"] }], sort: [{ type: i0.Input, args: [{ isSignal: true, alias: "sort", required: false }] }, { type: i0.Output, args: ["sortChange"] }], sortComparator: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortComparator", required: false }] }], filters: [{ type: i0.Input, args: [{ isSignal: true, alias: "filters", required: false }] }, { type: i0.Output, args: ["filtersChange"] }] } });
|
|
1426
1693
|
|
|
1427
1694
|
/**
|
|
1428
1695
|
* Lightweight body-cell directive. Deliberately does **not** extend `NgnBase`:
|