@akcelik/strct 4.9.0 → 4.11.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.
@@ -1941,6 +1941,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
1941
1941
  }, styles: [".strct-badge{display:inline-flex;align-items:center;gap:4px;font-size:12px;font-weight:600;line-height:1;letter-spacing:.2px;padding-block:3px;padding-inline:9px 7px;border-radius:var(--radius-sm);white-space:nowrap;color:var(--t2);background:transparent;border:1px solid var(--b3);border-inline-start-width:3px}.strct-badge--accent{color:var(--acc);border-color:var(--acc30)}.strct-badge--success{color:var(--success);border-color:var(--success)}.strct-badge--warning{color:var(--warning);border-color:var(--warning)}.strct-badge--critical{color:var(--critical);border-color:var(--critical)}.strct-badge--solid{color:var(--t1);background:var(--bg-a);border-color:transparent;border-inline-start-width:1px;padding-inline-start:7px}.strct-badge--solid.strct-badge--accent{background:var(--acc);color:var(--inv)}.strct-badge--solid.strct-badge--success{background:var(--success);color:var(--inv)}.strct-badge--solid.strct-badge--warning{background:var(--warning);color:var(--inv)}.strct-badge--solid.strct-badge--critical{background:var(--critical);color:var(--inv)}\n"] }]
1942
1942
  }], propDecorators: { status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], solid: [{ type: i0.Input, args: [{ isSignal: true, alias: "solid", required: false }] }] } });
1943
1943
 
1944
+ /** Content rendered before the tag's text — a status dot, an icon. */
1945
+ class StrctTagLeading {
1946
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctTagLeading, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1947
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.4", type: StrctTagLeading, isStandalone: true, selector: "[strctTagLeading]", ngImport: i0 });
1948
+ }
1949
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctTagLeading, decorators: [{
1950
+ type: Directive,
1951
+ args: [{ selector: '[strctTagLeading]' }]
1952
+ }] });
1944
1953
  /**
1945
1954
  * Compact, optionally removable chip.
1946
1955
  * <strct-tag status="accent" removable (removed)="drop()">Frontend</strct-tag>
@@ -1956,11 +1965,40 @@ class StrctTag {
1956
1965
  /** Accessible label for the remove button. */
1957
1966
  removeLabel = input('Remove', /* @ts-ignore */
1958
1967
  ...(ngDevMode ? [{ debugName: "removeLabel" }] : /* istanbul ignore next */ []));
1968
+ /**
1969
+ * The body becomes a control: pointer, hover, focus ring, and `activated` on
1970
+ * click / Enter / Space. The × stays a separate tab stop, so "open it" and
1971
+ * "remove it" are two targets.
1972
+ */
1973
+ interactive = input(false, { ...(ngDevMode ? { debugName: "interactive" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1974
+ /** `'pill'` rounds the tag fully — a chip for a thing, not a label on one. */
1975
+ shape = input('default', /* @ts-ignore */
1976
+ ...(ngDevMode ? [{ debugName: "shape" }] : /* istanbul ignore next */ []));
1977
+ /** Monospace text, for names that are identifiers. */
1978
+ mono = input(false, { ...(ngDevMode ? { debugName: "mono" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1959
1979
  /** Emitted when the user clicks the remove button. */
1960
1980
  removed = output();
1981
+ /** Emitted when an `interactive` tag's body is activated. */
1982
+ activated = output();
1983
+ onActivate() {
1984
+ if (this.interactive() && !this.disabled())
1985
+ this.activated.emit();
1986
+ }
1961
1987
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctTag, deps: [], target: i0.ɵɵFactoryTarget.Component });
1962
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctTag, isStandalone: true, selector: "strct-tag", inputs: { status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removed: "removed" }, host: { properties: { "class.strct-tag--accent": "status() === 'accent'", "class.strct-tag--success": "status() === 'success'", "class.strct-tag--warning": "status() === 'warning'", "class.strct-tag--critical": "status() === 'critical'" }, classAttribute: "strct-tag" }, ngImport: i0, template: `
1963
- <span class="strct-tag__text"><ng-content /></span>
1988
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctTag, isStandalone: true, selector: "strct-tag", inputs: { status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, mono: { classPropertyName: "mono", publicName: "mono", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removed: "removed", activated: "activated" }, host: { properties: { "class.strct-tag--interactive": "interactive() && !disabled()", "class.strct-tag--pill": "shape() === 'pill'", "class.strct-tag--mono": "mono()", "class.strct-tag--accent": "status() === 'accent'", "class.strct-tag--success": "status() === 'success'", "class.strct-tag--warning": "status() === 'warning'", "class.strct-tag--critical": "status() === 'critical'" }, classAttribute: "strct-tag" }, ngImport: i0, template: `
1989
+ <span
1990
+ class="strct-tag__text"
1991
+ [attr.role]="interactive() ? 'button' : null"
1992
+ [attr.tabindex]="interactive() && !disabled() ? 0 : null"
1993
+ (click)="onActivate()"
1994
+ (keydown.enter)="onActivate()"
1995
+ (keydown.space)="$event.preventDefault(); onActivate()"
1996
+ >
1997
+ <!-- Declared before the catch-all so the selector wins; it renders first
1998
+ either way. -->
1999
+ <ng-content select="[strctTagLeading]" />
2000
+ <ng-content />
2001
+ </span>
1964
2002
  @if (removable() && !disabled()) {
1965
2003
  <button
1966
2004
  type="button"
@@ -1971,12 +2009,24 @@ class StrctTag {
1971
2009
  <strct-icon name="close" [size]="11" [strokeWidth]="1.6" />
1972
2010
  </button>
1973
2011
  }
1974
- `, isInline: true, styles: [".strct-tag{display:inline-flex;align-items:center;gap:5px;padding-block:3px;padding-inline:9px 4px;border-radius:4px;font-size:12px;font-weight:500;color:var(--t1);background:var(--bg-3);border:1px solid var(--b2)}.strct-tag:not(:has(.strct-tag__remove)){padding-inline-end:9px}.strct-tag--accent{color:var(--acc);border-color:var(--acc30);background:var(--acc-s)}.strct-tag--success{color:var(--success);border-color:var(--success);background:transparent}.strct-tag--warning{color:var(--warning);border-color:var(--warning);background:transparent}.strct-tag--critical{color:var(--critical);border-color:var(--critical);background:transparent}.strct-tag__remove{display:inline-flex;padding:2px;border:0;border-radius:3px;background:transparent;color:currentColor;opacity:.65;cursor:pointer}.strct-tag__remove:hover,.strct-tag__remove:focus-visible{opacity:1;background:var(--dn)}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
2012
+ `, isInline: true, styles: [".strct-tag{display:inline-flex;align-items:center;gap:5px;padding-block:3px;padding-inline:9px 4px;border-radius:4px;font-size:12px;font-weight:500;color:var(--t1);background:var(--bg-3);border:1px solid var(--b2)}.strct-tag:not(:has(.strct-tag__remove)){padding-inline-end:9px}.strct-tag--accent{color:var(--acc);border-color:var(--acc30);background:var(--acc-s)}.strct-tag--success{color:var(--success);border-color:var(--success);background:transparent}.strct-tag--warning{color:var(--warning);border-color:var(--warning);background:transparent}.strct-tag--critical{color:var(--critical);border-color:var(--critical);background:transparent}.strct-tag__text{display:inline-flex;align-items:center;gap:5px}.strct-tag--interactive .strct-tag__text{cursor:pointer;border-radius:3px}.strct-tag--interactive:hover{border-color:var(--b3);background:var(--bg-2)}.strct-tag--interactive.strct-tag--accent:hover{border-color:var(--acc)}.strct-tag__text:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}.strct-tag--pill{border-radius:var(--radius-full, 999px);padding-inline:10px 5px}.strct-tag--pill:not(:has(.strct-tag__remove)){padding-inline-end:10px}.strct-tag--pill .strct-tag__remove{border-radius:999px}.strct-tag--mono{font-family:var(--mono)}.strct-tag__remove{display:inline-flex;padding:2px;border:0;border-radius:3px;background:transparent;color:currentColor;opacity:.65;cursor:pointer}.strct-tag__remove:hover,.strct-tag__remove:focus-visible{opacity:1;background:var(--dn)}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1975
2013
  }
1976
2014
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctTag, decorators: [{
1977
2015
  type: Component,
1978
2016
  args: [{ selector: 'strct-tag', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctIcon], template: `
1979
- <span class="strct-tag__text"><ng-content /></span>
2017
+ <span
2018
+ class="strct-tag__text"
2019
+ [attr.role]="interactive() ? 'button' : null"
2020
+ [attr.tabindex]="interactive() && !disabled() ? 0 : null"
2021
+ (click)="onActivate()"
2022
+ (keydown.enter)="onActivate()"
2023
+ (keydown.space)="$event.preventDefault(); onActivate()"
2024
+ >
2025
+ <!-- Declared before the catch-all so the selector wins; it renders first
2026
+ either way. -->
2027
+ <ng-content select="[strctTagLeading]" />
2028
+ <ng-content />
2029
+ </span>
1980
2030
  @if (removable() && !disabled()) {
1981
2031
  <button
1982
2032
  type="button"
@@ -1989,12 +2039,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
1989
2039
  }
1990
2040
  `, host: {
1991
2041
  class: 'strct-tag',
2042
+ '[class.strct-tag--interactive]': 'interactive() && !disabled()',
2043
+ '[class.strct-tag--pill]': "shape() === 'pill'",
2044
+ '[class.strct-tag--mono]': 'mono()',
1992
2045
  '[class.strct-tag--accent]': "status() === 'accent'",
1993
2046
  '[class.strct-tag--success]': "status() === 'success'",
1994
2047
  '[class.strct-tag--warning]': "status() === 'warning'",
1995
2048
  '[class.strct-tag--critical]': "status() === 'critical'",
1996
- }, styles: [".strct-tag{display:inline-flex;align-items:center;gap:5px;padding-block:3px;padding-inline:9px 4px;border-radius:4px;font-size:12px;font-weight:500;color:var(--t1);background:var(--bg-3);border:1px solid var(--b2)}.strct-tag:not(:has(.strct-tag__remove)){padding-inline-end:9px}.strct-tag--accent{color:var(--acc);border-color:var(--acc30);background:var(--acc-s)}.strct-tag--success{color:var(--success);border-color:var(--success);background:transparent}.strct-tag--warning{color:var(--warning);border-color:var(--warning);background:transparent}.strct-tag--critical{color:var(--critical);border-color:var(--critical);background:transparent}.strct-tag__remove{display:inline-flex;padding:2px;border:0;border-radius:3px;background:transparent;color:currentColor;opacity:.65;cursor:pointer}.strct-tag__remove:hover,.strct-tag__remove:focus-visible{opacity:1;background:var(--dn)}\n"] }]
1997
- }], propDecorators: { status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], removable: [{ type: i0.Input, args: [{ isSignal: true, alias: "removable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], removeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeLabel", required: false }] }], removed: [{ type: i0.Output, args: ["removed"] }] } });
2049
+ }, styles: [".strct-tag{display:inline-flex;align-items:center;gap:5px;padding-block:3px;padding-inline:9px 4px;border-radius:4px;font-size:12px;font-weight:500;color:var(--t1);background:var(--bg-3);border:1px solid var(--b2)}.strct-tag:not(:has(.strct-tag__remove)){padding-inline-end:9px}.strct-tag--accent{color:var(--acc);border-color:var(--acc30);background:var(--acc-s)}.strct-tag--success{color:var(--success);border-color:var(--success);background:transparent}.strct-tag--warning{color:var(--warning);border-color:var(--warning);background:transparent}.strct-tag--critical{color:var(--critical);border-color:var(--critical);background:transparent}.strct-tag__text{display:inline-flex;align-items:center;gap:5px}.strct-tag--interactive .strct-tag__text{cursor:pointer;border-radius:3px}.strct-tag--interactive:hover{border-color:var(--b3);background:var(--bg-2)}.strct-tag--interactive.strct-tag--accent:hover{border-color:var(--acc)}.strct-tag__text:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}.strct-tag--pill{border-radius:var(--radius-full, 999px);padding-inline:10px 5px}.strct-tag--pill:not(:has(.strct-tag__remove)){padding-inline-end:10px}.strct-tag--pill .strct-tag__remove{border-radius:999px}.strct-tag--mono{font-family:var(--mono)}.strct-tag__remove{display:inline-flex;padding:2px;border:0;border-radius:3px;background:transparent;color:currentColor;opacity:.65;cursor:pointer}.strct-tag__remove:hover,.strct-tag__remove:focus-visible{opacity:1;background:var(--dn)}\n"] }]
2050
+ }], propDecorators: { status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], removable: [{ type: i0.Input, args: [{ isSignal: true, alias: "removable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], removeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeLabel", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], mono: [{ type: i0.Input, args: [{ isSignal: true, alias: "mono", required: false }] }], removed: [{ type: i0.Output, args: ["removed"] }], activated: [{ type: i0.Output, args: ["activated"] }] } });
1998
2051
 
1999
2052
  /**
2000
2053
  * Circular avatar: an image when `src` is set, otherwise initials from `name`.
@@ -7750,6 +7803,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
7750
7803
  }]
7751
7804
  }] });
7752
7805
 
7806
+ /**
7807
+ * A description with markup in it, projected into `strct-checkbox`,
7808
+ * `strct-toggle` or `strct-radio` — where the string `description` renders, and
7809
+ * linked to the control the same way.
7810
+ *
7811
+ * <strct-checkbox [(checked)]="net">
7812
+ * Network
7813
+ * <span strctControlDescription>The cluster networks and <strong>Windows Firewall</strong>.</span>
7814
+ * </strct-checkbox>
7815
+ */
7816
+ class StrctControlDescription {
7817
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctControlDescription, deps: [], target: i0.ɵɵFactoryTarget.Directive });
7818
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.4", type: StrctControlDescription, isStandalone: true, selector: "[strctControlDescription]", ngImport: i0 });
7819
+ }
7820
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctControlDescription, decorators: [{
7821
+ type: Directive,
7822
+ args: [{ selector: '[strctControlDescription]' }]
7823
+ }] });
7824
+
7825
+ let checkboxCounter = 0;
7753
7826
  /** Checkbox with custom box. Works with `[(ngModel)]` / reactive forms. */
7754
7827
  class StrctCheckbox {
7755
7828
  checked = model(false, /* @ts-ignore */
@@ -7766,6 +7839,31 @@ class StrctCheckbox {
7766
7839
  /** Accessible label for the checkbox (used when no text label is present). */
7767
7840
  ariaLabel = input(null, /* @ts-ignore */
7768
7841
  ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
7842
+ /**
7843
+ * A sentence under the label explaining the option's consequence. It renders
7844
+ * inside the component's own `<label>` — so clicking it still toggles the
7845
+ * option — and is linked with `aria-describedby` rather than becoming part of
7846
+ * the name. `[strctControlDescription]` projects one with markup in it.
7847
+ */
7848
+ description = input('', /* @ts-ignore */
7849
+ ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
7850
+ n = ++checkboxCounter;
7851
+ descId = `strct-cb-desc-${this.n}`;
7852
+ labelId = `strct-cb-label-${this.n}`;
7853
+ projDescId = `strct-cb-pdesc-${this.n}`;
7854
+ projected = contentChild(StrctControlDescription, /* @ts-ignore */
7855
+ ...(ngDevMode ? [{ debugName: "projected" }] : /* istanbul ignore next */ []));
7856
+ described = computed(() => !!this.description() || !!this.projected(), /* @ts-ignore */
7857
+ ...(ngDevMode ? [{ debugName: "described" }] : /* istanbul ignore next */ []));
7858
+ describedBy = computed(() => this.description() ? this.descId : this.projected() ? this.projDescId : null, /* @ts-ignore */
7859
+ ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
7860
+ /**
7861
+ * The description sits inside the `<label>` so clicking it still toggles the
7862
+ * option — which would otherwise make it part of the name as well as the
7863
+ * description. Naming the label span keeps the name to the label alone.
7864
+ */
7865
+ labelledBy = computed(() => this.described() && !this.ariaLabel() ? this.labelId : null, /* @ts-ignore */
7866
+ ...(ngDevMode ? [{ debugName: "labelledBy" }] : /* istanbul ignore next */ []));
7769
7867
  onChange = () => { };
7770
7868
  onTouched = () => { };
7771
7869
  onToggle(event) {
@@ -7786,10 +7884,14 @@ class StrctCheckbox {
7786
7884
  this.cvaDisabled.set(isDisabled);
7787
7885
  }
7788
7886
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctCheckbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
7789
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: StrctCheckbox, isStandalone: true, selector: "strct-checkbox", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange" }, providers: [
7887
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctCheckbox, isStandalone: true, selector: "strct-checkbox", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange" }, providers: [
7790
7888
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => StrctCheckbox), multi: true },
7791
- ], ngImport: i0, template: `
7792
- <label class="strct-cb" [class.strct-cb--disabled]="isDisabled()">
7889
+ ], queries: [{ propertyName: "projected", first: true, predicate: StrctControlDescription, descendants: true, isSignal: true }], ngImport: i0, template: `
7890
+ <label
7891
+ class="strct-cb"
7892
+ [class.strct-cb--disabled]="isDisabled()"
7893
+ [class.strct-cb--described]="described()"
7894
+ >
7793
7895
  <input
7794
7896
  type="checkbox"
7795
7897
  class="strct-cb__native"
@@ -7797,22 +7899,40 @@ class StrctCheckbox {
7797
7899
  [disabled]="isDisabled()"
7798
7900
  [indeterminate]="indeterminate()"
7799
7901
  [attr.aria-label]="ariaLabel()"
7902
+ [attr.aria-labelledby]="labelledBy()"
7903
+ [attr.aria-describedby]="describedBy()"
7800
7904
  (change)="onToggle($event)"
7801
7905
  (blur)="onTouched()"
7802
7906
  />
7803
7907
  <span class="strct-cb__box">
7804
7908
  <strct-icon name="check" [size]="11" [strokeWidth]="2" />
7805
7909
  </span>
7806
- <span class="strct-cb__label"><ng-content /></span>
7910
+ <span class="strct-cb__text">
7911
+ <!-- The projected slot is declared first so its selector wins over the
7912
+ catch-all below; CSS order puts it under the label. -->
7913
+ @if (projected()) {
7914
+ <span class="strct-cb__desc strct-cb__desc--projected" [id]="projDescId">
7915
+ <ng-content select="[strctControlDescription]" />
7916
+ </span>
7917
+ }
7918
+ <span class="strct-cb__label" [id]="labelId"><ng-content /></span>
7919
+ @if (description()) {
7920
+ <span class="strct-cb__desc" [id]="descId">{{ description() }}</span>
7921
+ }
7922
+ </span>
7807
7923
  </label>
7808
- `, isInline: true, styles: [".strct-cb{display:inline-flex;align-items:center;gap:8px;cursor:pointer;font-size:13px;color:var(--t1);-webkit-user-select:none;user-select:none}.strct-cb--disabled{opacity:.5;cursor:not-allowed}.strct-cb__native{position:absolute;opacity:0;width:0;height:0}.strct-cb__box{display:inline-flex;align-items:center;justify-content:center;width:17px;height:17px;border-radius:4px;flex-shrink:0;background:var(--bg-2);border:1px solid var(--b3);color:transparent;transition:background .14s ease,border-color .14s ease}.strct-cb__native:checked+.strct-cb__box{background:var(--acc);border-color:transparent;color:var(--inv)}.strct-cb__native:indeterminate+.strct-cb__box{background:var(--acc);border-color:transparent}.strct-cb__native:indeterminate+.strct-cb__box strct-icon{visibility:hidden}.strct-cb__native:indeterminate+.strct-cb__box:after{content:\"\";width:9px;height:2px;border-radius:1px;background:var(--inv)}.strct-cb__native:focus-visible+.strct-cb__box{box-shadow:0 0 0 3px var(--acc18)}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7924
+ `, isInline: true, styles: [".strct-cb{display:inline-flex;align-items:center;gap:8px;cursor:pointer;font-size:13px;color:var(--t1);-webkit-user-select:none;user-select:none}.strct-cb--disabled{opacity:.5;cursor:not-allowed}.strct-cb__native{position:absolute;opacity:0;width:0;height:0}.strct-cb__box{display:inline-flex;align-items:center;justify-content:center;width:17px;height:17px;border-radius:4px;flex-shrink:0;background:var(--bg-2);border:1px solid var(--b3);color:transparent;transition:background .14s ease,border-color .14s ease}.strct-cb__native:checked+.strct-cb__box{background:var(--acc);border-color:transparent;color:var(--inv)}.strct-cb__native:indeterminate+.strct-cb__box{background:var(--acc);border-color:transparent}.strct-cb__native:indeterminate+.strct-cb__box strct-icon{visibility:hidden}.strct-cb__native:indeterminate+.strct-cb__box:after{content:\"\";width:9px;height:2px;border-radius:1px;background:var(--inv)}.strct-cb__native:focus-visible+.strct-cb__box{box-shadow:0 0 0 3px var(--acc18)}.strct-cb__text{display:flex;flex-direction:column;gap:1px;min-width:0}.strct-cb__desc{font-size:var(--text-sm);line-height:1.4;color:var(--t3)}.strct-cb__desc--projected{order:1}.strct-cb--described{align-items:flex-start}.strct-cb--described .strct-cb__box{margin-block-start:1px}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7809
7925
  }
7810
7926
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctCheckbox, decorators: [{
7811
7927
  type: Component,
7812
7928
  args: [{ selector: 'strct-checkbox', changeDetection: ChangeDetectionStrategy.OnPush, imports: [StrctIcon], providers: [
7813
7929
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => StrctCheckbox), multi: true },
7814
7930
  ], template: `
7815
- <label class="strct-cb" [class.strct-cb--disabled]="isDisabled()">
7931
+ <label
7932
+ class="strct-cb"
7933
+ [class.strct-cb--disabled]="isDisabled()"
7934
+ [class.strct-cb--described]="described()"
7935
+ >
7816
7936
  <input
7817
7937
  type="checkbox"
7818
7938
  class="strct-cb__native"
@@ -7820,17 +7940,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
7820
7940
  [disabled]="isDisabled()"
7821
7941
  [indeterminate]="indeterminate()"
7822
7942
  [attr.aria-label]="ariaLabel()"
7943
+ [attr.aria-labelledby]="labelledBy()"
7944
+ [attr.aria-describedby]="describedBy()"
7823
7945
  (change)="onToggle($event)"
7824
7946
  (blur)="onTouched()"
7825
7947
  />
7826
7948
  <span class="strct-cb__box">
7827
7949
  <strct-icon name="check" [size]="11" [strokeWidth]="2" />
7828
7950
  </span>
7829
- <span class="strct-cb__label"><ng-content /></span>
7951
+ <span class="strct-cb__text">
7952
+ <!-- The projected slot is declared first so its selector wins over the
7953
+ catch-all below; CSS order puts it under the label. -->
7954
+ @if (projected()) {
7955
+ <span class="strct-cb__desc strct-cb__desc--projected" [id]="projDescId">
7956
+ <ng-content select="[strctControlDescription]" />
7957
+ </span>
7958
+ }
7959
+ <span class="strct-cb__label" [id]="labelId"><ng-content /></span>
7960
+ @if (description()) {
7961
+ <span class="strct-cb__desc" [id]="descId">{{ description() }}</span>
7962
+ }
7963
+ </span>
7830
7964
  </label>
7831
- `, styles: [".strct-cb{display:inline-flex;align-items:center;gap:8px;cursor:pointer;font-size:13px;color:var(--t1);-webkit-user-select:none;user-select:none}.strct-cb--disabled{opacity:.5;cursor:not-allowed}.strct-cb__native{position:absolute;opacity:0;width:0;height:0}.strct-cb__box{display:inline-flex;align-items:center;justify-content:center;width:17px;height:17px;border-radius:4px;flex-shrink:0;background:var(--bg-2);border:1px solid var(--b3);color:transparent;transition:background .14s ease,border-color .14s ease}.strct-cb__native:checked+.strct-cb__box{background:var(--acc);border-color:transparent;color:var(--inv)}.strct-cb__native:indeterminate+.strct-cb__box{background:var(--acc);border-color:transparent}.strct-cb__native:indeterminate+.strct-cb__box strct-icon{visibility:hidden}.strct-cb__native:indeterminate+.strct-cb__box:after{content:\"\";width:9px;height:2px;border-radius:1px;background:var(--inv)}.strct-cb__native:focus-visible+.strct-cb__box{box-shadow:0 0 0 3px var(--acc18)}\n"] }]
7832
- }], propDecorators: { checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
7965
+ `, styles: [".strct-cb{display:inline-flex;align-items:center;gap:8px;cursor:pointer;font-size:13px;color:var(--t1);-webkit-user-select:none;user-select:none}.strct-cb--disabled{opacity:.5;cursor:not-allowed}.strct-cb__native{position:absolute;opacity:0;width:0;height:0}.strct-cb__box{display:inline-flex;align-items:center;justify-content:center;width:17px;height:17px;border-radius:4px;flex-shrink:0;background:var(--bg-2);border:1px solid var(--b3);color:transparent;transition:background .14s ease,border-color .14s ease}.strct-cb__native:checked+.strct-cb__box{background:var(--acc);border-color:transparent;color:var(--inv)}.strct-cb__native:indeterminate+.strct-cb__box{background:var(--acc);border-color:transparent}.strct-cb__native:indeterminate+.strct-cb__box strct-icon{visibility:hidden}.strct-cb__native:indeterminate+.strct-cb__box:after{content:\"\";width:9px;height:2px;border-radius:1px;background:var(--inv)}.strct-cb__native:focus-visible+.strct-cb__box{box-shadow:0 0 0 3px var(--acc18)}.strct-cb__text{display:flex;flex-direction:column;gap:1px;min-width:0}.strct-cb__desc{font-size:var(--text-sm);line-height:1.4;color:var(--t3)}.strct-cb__desc--projected{order:1}.strct-cb--described{align-items:flex-start}.strct-cb--described .strct-cb__box{margin-block-start:1px}\n"] }]
7966
+ }], propDecorators: { checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], projected: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctControlDescription), { isSignal: true }] }] } });
7833
7967
 
7968
+ let toggleCounter = 0;
7834
7969
  /** On/off switch. Works with `[(ngModel)]` / reactive forms. */
7835
7970
  class StrctToggle {
7836
7971
  checked = signal(false, /* @ts-ignore */
@@ -7842,6 +7977,26 @@ class StrctToggle {
7842
7977
  ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
7843
7978
  /** Static disable; forms' setDisabledState also drives the disabled state. */
7844
7979
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
7980
+ /**
7981
+ * A sentence under the label explaining what turning this on does. It renders
7982
+ * inside the component's own `<label>` and is linked with `aria-describedby`;
7983
+ * `[strctControlDescription]` projects one with markup in it.
7984
+ */
7985
+ description = input('', /* @ts-ignore */
7986
+ ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
7987
+ n = ++toggleCounter;
7988
+ descId = `strct-tg-desc-${this.n}`;
7989
+ labelId = `strct-tg-label-${this.n}`;
7990
+ projDescId = `strct-tg-pdesc-${this.n}`;
7991
+ projected = contentChild(StrctControlDescription, /* @ts-ignore */
7992
+ ...(ngDevMode ? [{ debugName: "projected" }] : /* istanbul ignore next */ []));
7993
+ described = computed(() => !!this.description() || !!this.projected(), /* @ts-ignore */
7994
+ ...(ngDevMode ? [{ debugName: "described" }] : /* istanbul ignore next */ []));
7995
+ describedBy = computed(() => this.description() ? this.descId : this.projected() ? this.projDescId : null, /* @ts-ignore */
7996
+ ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
7997
+ /** Keeps the name to the label when the description shares its `<label>`. */
7998
+ labelledBy = computed(() => (this.described() ? this.labelId : null), /* @ts-ignore */
7999
+ ...(ngDevMode ? [{ debugName: "labelledBy" }] : /* istanbul ignore next */ []));
7845
8000
  onChange = () => { };
7846
8001
  onTouched = () => { };
7847
8002
  onToggle(event) {
@@ -7862,46 +8017,79 @@ class StrctToggle {
7862
8017
  this.cvaDisabled.set(isDisabled);
7863
8018
  }
7864
8019
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctToggle, deps: [], target: i0.ɵɵFactoryTarget.Component });
7865
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: StrctToggle, isStandalone: true, selector: "strct-toggle", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
8020
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctToggle, isStandalone: true, selector: "strct-toggle", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
7866
8021
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => StrctToggle), multi: true },
7867
- ], ngImport: i0, template: `
7868
- <label class="strct-tg" [class.strct-tg--disabled]="isDisabled()">
8022
+ ], queries: [{ propertyName: "projected", first: true, predicate: StrctControlDescription, descendants: true, isSignal: true }], ngImport: i0, template: `
8023
+ <label
8024
+ class="strct-tg"
8025
+ [class.strct-tg--disabled]="isDisabled()"
8026
+ [class.strct-tg--described]="described()"
8027
+ >
7869
8028
  <input
7870
8029
  type="checkbox"
7871
8030
  class="strct-tg__native"
7872
8031
  role="switch"
7873
8032
  [checked]="checked()"
7874
8033
  [disabled]="isDisabled()"
8034
+ [attr.aria-labelledby]="labelledBy()"
8035
+ [attr.aria-describedby]="describedBy()"
7875
8036
  (change)="onToggle($event)"
7876
8037
  (blur)="onTouched()"
7877
8038
  />
7878
8039
  <span class="strct-tg__track"><span class="strct-tg__thumb"></span></span>
7879
- <span class="strct-tg__label"><ng-content /></span>
8040
+ <span class="strct-tg__text">
8041
+ @if (projected()) {
8042
+ <span class="strct-tg__desc strct-tg__desc--projected" [id]="projDescId">
8043
+ <ng-content select="[strctControlDescription]" />
8044
+ </span>
8045
+ }
8046
+ <span class="strct-tg__label" [id]="labelId"><ng-content /></span>
8047
+ @if (description()) {
8048
+ <span class="strct-tg__desc" [id]="descId">{{ description() }}</span>
8049
+ }
8050
+ </span>
7880
8051
  </label>
7881
- `, isInline: true, styles: [".strct-tg{display:inline-flex;align-items:center;gap:9px;cursor:pointer;font-size:13px;color:var(--t1);-webkit-user-select:none;user-select:none}.strct-tg--disabled{opacity:.5;cursor:not-allowed}.strct-tg__native{position:absolute;opacity:0;width:0;height:0}.strct-tg__track{position:relative;width:34px;height:19px;border-radius:11px;flex-shrink:0;background:var(--bg-3);border:1px solid var(--b3);transition:background .16s ease,border-color .16s ease}.strct-tg__thumb{position:absolute;top:2px;left:2px;width:13px;height:13px;border-radius:50%;background:var(--t2);transition:transform .16s ease,background .16s ease}.strct-tg__native:checked+.strct-tg__track{background:var(--acc);border-color:transparent}.strct-tg__native:checked+.strct-tg__track .strct-tg__thumb{transform:translate(15px);background:var(--inv)}:host-context([dir=\"rtl\"]) .strct-tg__native:checked+.strct-tg__track .strct-tg__thumb{transform:translate(-15px)}.strct-tg__native:focus-visible+.strct-tg__track{box-shadow:0 0 0 3px var(--acc18)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8052
+ `, isInline: true, styles: [".strct-tg{display:inline-flex;align-items:center;gap:9px;cursor:pointer;font-size:13px;color:var(--t1);-webkit-user-select:none;user-select:none}.strct-tg--disabled{opacity:.5;cursor:not-allowed}.strct-tg__native{position:absolute;opacity:0;width:0;height:0}.strct-tg__track{position:relative;width:34px;height:19px;border-radius:11px;flex-shrink:0;background:var(--bg-3);border:1px solid var(--b3);transition:background .16s ease,border-color .16s ease}.strct-tg__thumb{position:absolute;top:2px;left:2px;width:13px;height:13px;border-radius:50%;background:var(--t2);transition:transform .16s ease,background .16s ease}.strct-tg__native:checked+.strct-tg__track{background:var(--acc);border-color:transparent}.strct-tg__native:checked+.strct-tg__track .strct-tg__thumb{transform:translate(15px);background:var(--inv)}:host-context([dir=\"rtl\"]) .strct-tg__native:checked+.strct-tg__track .strct-tg__thumb{transform:translate(-15px)}.strct-tg__native:focus-visible+.strct-tg__track{box-shadow:0 0 0 3px var(--acc18)}.strct-tg__text{display:flex;flex-direction:column;gap:1px;min-width:0}.strct-tg__desc{font-size:var(--text-sm);line-height:1.4;color:var(--t3)}.strct-tg__desc--projected{order:1}.strct-tg--described{align-items:flex-start}.strct-tg--described .strct-tg__track{margin-block-start:1px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7882
8053
  }
7883
8054
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctToggle, decorators: [{
7884
8055
  type: Component,
7885
8056
  args: [{ selector: 'strct-toggle', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
7886
8057
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => StrctToggle), multi: true },
7887
8058
  ], template: `
7888
- <label class="strct-tg" [class.strct-tg--disabled]="isDisabled()">
8059
+ <label
8060
+ class="strct-tg"
8061
+ [class.strct-tg--disabled]="isDisabled()"
8062
+ [class.strct-tg--described]="described()"
8063
+ >
7889
8064
  <input
7890
8065
  type="checkbox"
7891
8066
  class="strct-tg__native"
7892
8067
  role="switch"
7893
8068
  [checked]="checked()"
7894
8069
  [disabled]="isDisabled()"
8070
+ [attr.aria-labelledby]="labelledBy()"
8071
+ [attr.aria-describedby]="describedBy()"
7895
8072
  (change)="onToggle($event)"
7896
8073
  (blur)="onTouched()"
7897
8074
  />
7898
8075
  <span class="strct-tg__track"><span class="strct-tg__thumb"></span></span>
7899
- <span class="strct-tg__label"><ng-content /></span>
8076
+ <span class="strct-tg__text">
8077
+ @if (projected()) {
8078
+ <span class="strct-tg__desc strct-tg__desc--projected" [id]="projDescId">
8079
+ <ng-content select="[strctControlDescription]" />
8080
+ </span>
8081
+ }
8082
+ <span class="strct-tg__label" [id]="labelId"><ng-content /></span>
8083
+ @if (description()) {
8084
+ <span class="strct-tg__desc" [id]="descId">{{ description() }}</span>
8085
+ }
8086
+ </span>
7900
8087
  </label>
7901
- `, styles: [".strct-tg{display:inline-flex;align-items:center;gap:9px;cursor:pointer;font-size:13px;color:var(--t1);-webkit-user-select:none;user-select:none}.strct-tg--disabled{opacity:.5;cursor:not-allowed}.strct-tg__native{position:absolute;opacity:0;width:0;height:0}.strct-tg__track{position:relative;width:34px;height:19px;border-radius:11px;flex-shrink:0;background:var(--bg-3);border:1px solid var(--b3);transition:background .16s ease,border-color .16s ease}.strct-tg__thumb{position:absolute;top:2px;left:2px;width:13px;height:13px;border-radius:50%;background:var(--t2);transition:transform .16s ease,background .16s ease}.strct-tg__native:checked+.strct-tg__track{background:var(--acc);border-color:transparent}.strct-tg__native:checked+.strct-tg__track .strct-tg__thumb{transform:translate(15px);background:var(--inv)}:host-context([dir=\"rtl\"]) .strct-tg__native:checked+.strct-tg__track .strct-tg__thumb{transform:translate(-15px)}.strct-tg__native:focus-visible+.strct-tg__track{box-shadow:0 0 0 3px var(--acc18)}\n"] }]
7902
- }], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
8088
+ `, styles: [".strct-tg{display:inline-flex;align-items:center;gap:9px;cursor:pointer;font-size:13px;color:var(--t1);-webkit-user-select:none;user-select:none}.strct-tg--disabled{opacity:.5;cursor:not-allowed}.strct-tg__native{position:absolute;opacity:0;width:0;height:0}.strct-tg__track{position:relative;width:34px;height:19px;border-radius:11px;flex-shrink:0;background:var(--bg-3);border:1px solid var(--b3);transition:background .16s ease,border-color .16s ease}.strct-tg__thumb{position:absolute;top:2px;left:2px;width:13px;height:13px;border-radius:50%;background:var(--t2);transition:transform .16s ease,background .16s ease}.strct-tg__native:checked+.strct-tg__track{background:var(--acc);border-color:transparent}.strct-tg__native:checked+.strct-tg__track .strct-tg__thumb{transform:translate(15px);background:var(--inv)}:host-context([dir=\"rtl\"]) .strct-tg__native:checked+.strct-tg__track .strct-tg__thumb{transform:translate(-15px)}.strct-tg__native:focus-visible+.strct-tg__track{box-shadow:0 0 0 3px var(--acc18)}.strct-tg__text{display:flex;flex-direction:column;gap:1px;min-width:0}.strct-tg__desc{font-size:var(--text-sm);line-height:1.4;color:var(--t3)}.strct-tg__desc--projected{order:1}.strct-tg--described{align-items:flex-start}.strct-tg--described .strct-tg__track{margin-block-start:1px}\n"] }]
8089
+ }], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], projected: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctControlDescription), { isSignal: true }] }] } });
7903
8090
 
7904
8091
  let groupCounter = 0;
8092
+ let radioCounter = 0;
7905
8093
  /**
7906
8094
  * Radio group (the form control). Wrap `<strct-radio>` items:
7907
8095
  * <strct-radio-group [(ngModel)]="size">
@@ -7910,6 +8098,13 @@ let groupCounter = 0;
7910
8098
  * </strct-radio-group>
7911
8099
  */
7912
8100
  class StrctRadioGroup {
8101
+ /**
8102
+ * `'card'` renders each option as a tile with room for an icon and a
8103
+ * sentence — a choice between a few kinds of thing, each needing an
8104
+ * explanation. It stays a native radio group: one tab stop, arrow keys.
8105
+ */
8106
+ variant = input('default', /* @ts-ignore */
8107
+ ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
7913
8108
  name = `strct-radio-${++groupCounter}`;
7914
8109
  value = signal(null, /* @ts-ignore */
7915
8110
  ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
@@ -7935,16 +8130,20 @@ class StrctRadioGroup {
7935
8130
  this.isDisabled.set(isDisabled);
7936
8131
  }
7937
8132
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctRadioGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
7938
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.4", type: StrctRadioGroup, isStandalone: true, selector: "strct-radio-group", host: { attributes: { "role": "radiogroup" }, classAttribute: "strct-radio-group" }, providers: [
8133
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: StrctRadioGroup, isStandalone: true, selector: "strct-radio-group", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "radiogroup" }, properties: { "class.strct-radio-group--card": "variant() === 'card'" }, classAttribute: "strct-radio-group" }, providers: [
7939
8134
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => StrctRadioGroup), multi: true },
7940
- ], ngImport: i0, template: `<ng-content />`, isInline: true, styles: [".strct-radio-group{display:flex;flex-direction:column;gap:9px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
8135
+ ], ngImport: i0, template: `<ng-content />`, isInline: true, styles: [".strct-radio-group{display:flex;flex-direction:column;gap:9px}.strct-radio-group--card{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(var(--strct-radio-card-min, 220px),100%),1fr));gap:var(--space-2)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
7941
8136
  }
7942
8137
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctRadioGroup, decorators: [{
7943
8138
  type: Component,
7944
8139
  args: [{ selector: 'strct-radio-group', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
7945
8140
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => StrctRadioGroup), multi: true },
7946
- ], template: `<ng-content />`, host: { class: 'strct-radio-group', role: 'radiogroup' }, styles: [".strct-radio-group{display:flex;flex-direction:column;gap:9px}\n"] }]
7947
- }] });
8141
+ ], template: `<ng-content />`, host: {
8142
+ class: 'strct-radio-group',
8143
+ role: 'radiogroup',
8144
+ '[class.strct-radio-group--card]': "variant() === 'card'",
8145
+ }, styles: [".strct-radio-group{display:flex;flex-direction:column;gap:9px}.strct-radio-group--card{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(var(--strct-radio-card-min, 220px),100%),1fr));gap:var(--space-2)}\n"] }]
8146
+ }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }] } });
7948
8147
  /** One option inside a `<strct-radio-group>`. */
7949
8148
  class StrctRadio {
7950
8149
  /** Current value. */
@@ -7952,40 +8151,111 @@ class StrctRadio {
7952
8151
  ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
7953
8152
  /** Static disable flag. */
7954
8153
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
8154
+ /**
8155
+ * A sentence under the label. It renders inside the component's own
8156
+ * `<label>` and is linked with `aria-describedby`;
8157
+ * `[strctControlDescription]` projects one with markup in it.
8158
+ */
8159
+ description = input('', /* @ts-ignore */
8160
+ ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
8161
+ /** Leading icon — card variant only. */
8162
+ icon = input('', /* @ts-ignore */
8163
+ ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
7955
8164
  group = inject(StrctRadioGroup);
8165
+ card = computed(() => this.group.variant() === 'card', /* @ts-ignore */
8166
+ ...(ngDevMode ? [{ debugName: "card" }] : /* istanbul ignore next */ []));
8167
+ n = ++radioCounter;
8168
+ descId = `strct-rb-desc-${this.n}`;
8169
+ labelId = `strct-rb-label-${this.n}`;
8170
+ projDescId = `strct-rb-pdesc-${this.n}`;
8171
+ projected = contentChild(StrctControlDescription, /* @ts-ignore */
8172
+ ...(ngDevMode ? [{ debugName: "projected" }] : /* istanbul ignore next */ []));
8173
+ described = computed(() => !!this.description() || !!this.projected(), /* @ts-ignore */
8174
+ ...(ngDevMode ? [{ debugName: "described" }] : /* istanbul ignore next */ []));
8175
+ describedBy = computed(() => this.description() ? this.descId : this.projected() ? this.projDescId : null, /* @ts-ignore */
8176
+ ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
8177
+ /** Keeps the name to the label when the description shares its `<label>`. */
8178
+ labelledBy = computed(() => (this.described() ? this.labelId : null), /* @ts-ignore */
8179
+ ...(ngDevMode ? [{ debugName: "labelledBy" }] : /* istanbul ignore next */ []));
7956
8180
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctRadio, deps: [], target: i0.ɵɵFactoryTarget.Component });
7957
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: StrctRadio, isStandalone: true, selector: "strct-radio", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
7958
- <label class="strct-rb" [class.strct-rb--disabled]="disabled() || group.isDisabled()">
8181
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctRadio, isStandalone: true, selector: "strct-radio", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "projected", first: true, predicate: StrctControlDescription, descendants: true, isSignal: true }], ngImport: i0, template: `
8182
+ <label
8183
+ class="strct-rb"
8184
+ [class.strct-rb--disabled]="disabled() || group.isDisabled()"
8185
+ [class.strct-rb--card]="card()"
8186
+ [class.strct-rb--described]="described()"
8187
+ [class.strct-rb--checked]="group.value() === value()"
8188
+ >
7959
8189
  <input
7960
8190
  type="radio"
7961
8191
  class="strct-rb__native"
7962
8192
  [name]="group.name"
7963
8193
  [checked]="group.value() === value()"
7964
8194
  [disabled]="disabled() || group.isDisabled()"
8195
+ [attr.aria-labelledby]="labelledBy()"
8196
+ [attr.aria-describedby]="describedBy()"
7965
8197
  (change)="group.select(value())"
7966
8198
  />
7967
8199
  <span class="strct-rb__dot"></span>
7968
- <span class="strct-rb__label"><ng-content /></span>
8200
+ <span class="strct-rb__text">
8201
+ @if (projected()) {
8202
+ <span class="strct-rb__desc strct-rb__desc--projected" [id]="projDescId">
8203
+ <ng-content select="[strctControlDescription]" />
8204
+ </span>
8205
+ }
8206
+ <span class="strct-rb__label" [id]="labelId">
8207
+ @if (card() && icon()) {
8208
+ <strct-icon class="strct-rb__icon" [name]="icon()" [size]="15" />
8209
+ }
8210
+ <ng-content />
8211
+ </span>
8212
+ @if (description()) {
8213
+ <span class="strct-rb__desc" [id]="descId">{{ description() }}</span>
8214
+ }
8215
+ </span>
7969
8216
  </label>
7970
- `, isInline: true, styles: [".strct-rb{display:inline-flex;align-items:center;gap:8px;cursor:pointer;font-size:13px;color:var(--t1);-webkit-user-select:none;user-select:none}.strct-rb--disabled{opacity:.5;cursor:not-allowed}.strct-rb__native{position:absolute;opacity:0;width:0;height:0}.strct-rb__dot{position:relative;width:17px;height:17px;border-radius:50%;flex-shrink:0;background:var(--bg-2);border:1px solid var(--b3);transition:border-color .14s ease}.strct-rb__dot:after{content:\"\";position:absolute;inset:0;margin:auto;width:7px;height:7px;border-radius:50%;background:var(--acc);transform:scale(0);transition:transform .14s ease}.strct-rb__native:checked+.strct-rb__dot{border-color:var(--acc)}.strct-rb__native:checked+.strct-rb__dot:after{transform:scale(1)}.strct-rb__native:focus-visible+.strct-rb__dot{box-shadow:0 0 0 3px var(--acc18)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8217
+ `, isInline: true, styles: [".strct-rb{display:inline-flex;align-items:center;gap:8px;cursor:pointer;font-size:13px;color:var(--t1);-webkit-user-select:none;user-select:none}.strct-rb--disabled{opacity:.5;cursor:not-allowed}.strct-rb__native{position:absolute;opacity:0;width:0;height:0}.strct-rb__dot{position:relative;width:17px;height:17px;border-radius:50%;flex-shrink:0;background:var(--bg-2);border:1px solid var(--b3);transition:border-color .14s ease}.strct-rb__dot:after{content:\"\";position:absolute;inset:0;margin:auto;width:7px;height:7px;border-radius:50%;background:var(--acc);transform:scale(0);transition:transform .14s ease}.strct-rb__native:checked+.strct-rb__dot{border-color:var(--acc)}.strct-rb__native:checked+.strct-rb__dot:after{transform:scale(1)}.strct-rb__native:focus-visible+.strct-rb__dot{box-shadow:0 0 0 3px var(--acc18)}.strct-rb__text{display:flex;flex-direction:column;gap:1px;min-width:0}.strct-rb__label{display:inline-flex;align-items:center;gap:6px}.strct-rb__desc{font-size:var(--text-sm);line-height:1.4;color:var(--t3)}.strct-rb__desc--projected{order:1}.strct-rb--described{align-items:flex-start}.strct-rb--described .strct-rb__dot{margin-block-start:1px}.strct-rb--card{display:flex;align-items:flex-start;gap:var(--space-2);padding:var(--space-3);background:var(--bg-1);border:1px solid var(--b2);border-radius:var(--radius-md);height:100%;box-sizing:border-box;transition:border-color .14s ease,background .14s ease}.strct-rb--card:hover:not(.strct-rb--disabled){border-color:var(--b3)}.strct-rb--card.strct-rb--checked{border-color:var(--acc);background:var(--acc-s)}.strct-rb--card .strct-rb__label{font-weight:600}.strct-rb__icon{color:var(--acc);flex:none}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7971
8218
  }
7972
8219
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctRadio, decorators: [{
7973
8220
  type: Component,
7974
- args: [{ selector: 'strct-radio', changeDetection: ChangeDetectionStrategy.OnPush, template: `
7975
- <label class="strct-rb" [class.strct-rb--disabled]="disabled() || group.isDisabled()">
8221
+ args: [{ selector: 'strct-radio', changeDetection: ChangeDetectionStrategy.OnPush, imports: [StrctIcon], template: `
8222
+ <label
8223
+ class="strct-rb"
8224
+ [class.strct-rb--disabled]="disabled() || group.isDisabled()"
8225
+ [class.strct-rb--card]="card()"
8226
+ [class.strct-rb--described]="described()"
8227
+ [class.strct-rb--checked]="group.value() === value()"
8228
+ >
7976
8229
  <input
7977
8230
  type="radio"
7978
8231
  class="strct-rb__native"
7979
8232
  [name]="group.name"
7980
8233
  [checked]="group.value() === value()"
7981
8234
  [disabled]="disabled() || group.isDisabled()"
8235
+ [attr.aria-labelledby]="labelledBy()"
8236
+ [attr.aria-describedby]="describedBy()"
7982
8237
  (change)="group.select(value())"
7983
8238
  />
7984
8239
  <span class="strct-rb__dot"></span>
7985
- <span class="strct-rb__label"><ng-content /></span>
8240
+ <span class="strct-rb__text">
8241
+ @if (projected()) {
8242
+ <span class="strct-rb__desc strct-rb__desc--projected" [id]="projDescId">
8243
+ <ng-content select="[strctControlDescription]" />
8244
+ </span>
8245
+ }
8246
+ <span class="strct-rb__label" [id]="labelId">
8247
+ @if (card() && icon()) {
8248
+ <strct-icon class="strct-rb__icon" [name]="icon()" [size]="15" />
8249
+ }
8250
+ <ng-content />
8251
+ </span>
8252
+ @if (description()) {
8253
+ <span class="strct-rb__desc" [id]="descId">{{ description() }}</span>
8254
+ }
8255
+ </span>
7986
8256
  </label>
7987
- `, styles: [".strct-rb{display:inline-flex;align-items:center;gap:8px;cursor:pointer;font-size:13px;color:var(--t1);-webkit-user-select:none;user-select:none}.strct-rb--disabled{opacity:.5;cursor:not-allowed}.strct-rb__native{position:absolute;opacity:0;width:0;height:0}.strct-rb__dot{position:relative;width:17px;height:17px;border-radius:50%;flex-shrink:0;background:var(--bg-2);border:1px solid var(--b3);transition:border-color .14s ease}.strct-rb__dot:after{content:\"\";position:absolute;inset:0;margin:auto;width:7px;height:7px;border-radius:50%;background:var(--acc);transform:scale(0);transition:transform .14s ease}.strct-rb__native:checked+.strct-rb__dot{border-color:var(--acc)}.strct-rb__native:checked+.strct-rb__dot:after{transform:scale(1)}.strct-rb__native:focus-visible+.strct-rb__dot{box-shadow:0 0 0 3px var(--acc18)}\n"] }]
7988
- }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
8257
+ `, styles: [".strct-rb{display:inline-flex;align-items:center;gap:8px;cursor:pointer;font-size:13px;color:var(--t1);-webkit-user-select:none;user-select:none}.strct-rb--disabled{opacity:.5;cursor:not-allowed}.strct-rb__native{position:absolute;opacity:0;width:0;height:0}.strct-rb__dot{position:relative;width:17px;height:17px;border-radius:50%;flex-shrink:0;background:var(--bg-2);border:1px solid var(--b3);transition:border-color .14s ease}.strct-rb__dot:after{content:\"\";position:absolute;inset:0;margin:auto;width:7px;height:7px;border-radius:50%;background:var(--acc);transform:scale(0);transition:transform .14s ease}.strct-rb__native:checked+.strct-rb__dot{border-color:var(--acc)}.strct-rb__native:checked+.strct-rb__dot:after{transform:scale(1)}.strct-rb__native:focus-visible+.strct-rb__dot{box-shadow:0 0 0 3px var(--acc18)}.strct-rb__text{display:flex;flex-direction:column;gap:1px;min-width:0}.strct-rb__label{display:inline-flex;align-items:center;gap:6px}.strct-rb__desc{font-size:var(--text-sm);line-height:1.4;color:var(--t3)}.strct-rb__desc--projected{order:1}.strct-rb--described{align-items:flex-start}.strct-rb--described .strct-rb__dot{margin-block-start:1px}.strct-rb--card{display:flex;align-items:flex-start;gap:var(--space-2);padding:var(--space-3);background:var(--bg-1);border:1px solid var(--b2);border-radius:var(--radius-md);height:100%;box-sizing:border-box;transition:border-color .14s ease,background .14s ease}.strct-rb--card:hover:not(.strct-rb--disabled){border-color:var(--b3)}.strct-rb--card.strct-rb--checked{border-color:var(--acc);background:var(--acc-s)}.strct-rb--card .strct-rb__label{font-weight:600}.strct-rb__icon{color:var(--acc);flex:none}\n"] }]
8258
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], projected: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctControlDescription), { isSignal: true }] }] } });
7989
8259
 
7990
8260
  /**
7991
8261
  * One-of-N selection rendered as a joined segmented control with managed
@@ -8852,7 +9122,7 @@ class StrctChips {
8852
9122
  (blur)="commitDraft(); onTouched()"
8853
9123
  />
8854
9124
  </div>
8855
- `, isInline: true, styles: [".strct-chips{display:flex;flex-wrap:wrap;align-items:center;gap:6px;width:100%;min-height:38px;padding:5px 8px;background:var(--bg-2);border:1px solid var(--b2);border-radius:6px;cursor:text;transition:border-color .14s ease,box-shadow .14s ease}.strct-chips:focus-within{border-color:var(--acc50);box-shadow:0 0 0 3px var(--acc18);background:var(--bg-1)}.strct-chips__input{flex:1;min-width:80px;border:0;outline:none;background:transparent;font-family:var(--font);font-size:13px;color:var(--t1);padding:3px 2px}.strct-chips__input::placeholder{color:var(--t3)}\n"], dependencies: [{ kind: "component", type: StrctTag, selector: "strct-tag", inputs: ["status", "removable", "disabled", "removeLabel"], outputs: ["removed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
9125
+ `, isInline: true, styles: [".strct-chips{display:flex;flex-wrap:wrap;align-items:center;gap:6px;width:100%;min-height:38px;padding:5px 8px;background:var(--bg-2);border:1px solid var(--b2);border-radius:6px;cursor:text;transition:border-color .14s ease,box-shadow .14s ease}.strct-chips:focus-within{border-color:var(--acc50);box-shadow:0 0 0 3px var(--acc18);background:var(--bg-1)}.strct-chips__input{flex:1;min-width:80px;border:0;outline:none;background:transparent;font-family:var(--font);font-size:13px;color:var(--t1);padding:3px 2px}.strct-chips__input::placeholder{color:var(--t3)}\n"], dependencies: [{ kind: "component", type: StrctTag, selector: "strct-tag", inputs: ["status", "removable", "disabled", "removeLabel", "interactive", "shape", "mono"], outputs: ["removed", "activated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
8856
9126
  }
8857
9127
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctChips, decorators: [{
8858
9128
  type: Component,
@@ -11853,68 +12123,342 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
11853
12123
  }], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], striped: [{ type: i0.Input, args: [{ isSignal: true, alias: "striped", required: false }] }], hover: [{ type: i0.Input, args: [{ isSignal: true, alias: "hover", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], cellDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrctCellDef), { isSignal: true }] }] } });
11854
12124
 
11855
12125
  /**
11856
- * Minimal, dependency-free XLSX writer for the datagrid's Excel export.
12126
+ * Numeric stepper input: − / + buttons flanking a text field. The value is
12127
+ * `number | null` (null = empty); typing is free-form (intermediate states
12128
+ * like "-" are kept), committed values clamp to `min`/`max` on blur, and the
12129
+ * buttons + keyboard always clamp immediately.
11857
12130
  *
11858
- * An .xlsx file is a ZIP of SpreadsheetML parts. This builds the five
11859
- * required parts with inline strings and zips them with STORED (uncompressed)
11860
- * entries — no runtime dependency, byte-accurate CRC32, opens in Excel,
11861
- * LibreOffice and Google Sheets.
12131
+ * <strct-number [min]="0" [max]="64" [step]="4" [(ngModel)]="vcpus" />
12132
+ *
12133
+ * Keyboard on the field: ArrowUp/Down ±step, PageUp/Down ±10×step,
12134
+ * Home/End jump to min/max. The field exposes `role="spinbutton"` with
12135
+ * aria-valuemin/max/now so assistive tech announces it as a number control.
11862
12136
  */
11863
- const CRC_TABLE = (() => {
11864
- const t = new Uint32Array(256);
11865
- for (let n = 0; n < 256; n++) {
11866
- let c = n;
11867
- for (let k = 0; k < 8; k++)
11868
- c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
11869
- t[n] = c >>> 0;
12137
+ class StrctNumber {
12138
+ /** Minimum allowed value; null = unbounded. */
12139
+ min = input(null, /* @ts-ignore */
12140
+ ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
12141
+ /** Maximum allowed value; null = unbounded. */
12142
+ max = input(null, /* @ts-ignore */
12143
+ ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
12144
+ /** Step increment for buttons and Arrow keys (PageUp/Down use 10×). */
12145
+ step = input(1, /* @ts-ignore */
12146
+ ...(ngDevMode ? [{ debugName: "step" }] : /* istanbul ignore next */ []));
12147
+ /** Placeholder text when empty. */
12148
+ placeholder = input('', /* @ts-ignore */
12149
+ ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
12150
+ /** Accessible label of the + button (localizable). */
12151
+ incrementLabel = input('Increment', /* @ts-ignore */
12152
+ ...(ngDevMode ? [{ debugName: "incrementLabel" }] : /* istanbul ignore next */ []));
12153
+ /** Accessible label of the − button (localizable). */
12154
+ decrementLabel = input('Decrement', /* @ts-ignore */
12155
+ ...(ngDevMode ? [{ debugName: "decrementLabel" }] : /* istanbul ignore next */ []));
12156
+ /** Static disable; forms' setDisabledState also drives the disabled state. */
12157
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
12158
+ value = signal(null, /* @ts-ignore */
12159
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
12160
+ /** Raw field text — may hold an unparseable intermediate state while typing. */
12161
+ text = signal('', /* @ts-ignore */
12162
+ ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
12163
+ /** Disabled state pushed by the forms API (setDisabledState). */
12164
+ cvaDisabled = signal(false, /* @ts-ignore */
12165
+ ...(ngDevMode ? [{ debugName: "cvaDisabled" }] : /* istanbul ignore next */ []));
12166
+ isDisabled = computed(() => this.disabled() || this.cvaDisabled(), /* @ts-ignore */
12167
+ ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
12168
+ /** At/below min (or min unset → never) — greys out the − button. */
12169
+ atMin = computed(() => {
12170
+ const v = this.value();
12171
+ const m = this.min();
12172
+ return v !== null && m !== null && v <= m;
12173
+ }, /* @ts-ignore */
12174
+ ...(ngDevMode ? [{ debugName: "atMin" }] : /* istanbul ignore next */ []));
12175
+ /** At/above max (or max unset → never) — greys out the + button. */
12176
+ atMax = computed(() => {
12177
+ const v = this.value();
12178
+ const m = this.max();
12179
+ return v !== null && m !== null && v >= m;
12180
+ }, /* @ts-ignore */
12181
+ ...(ngDevMode ? [{ debugName: "atMax" }] : /* istanbul ignore next */ []));
12182
+ onChange = () => { };
12183
+ onTouched = () => { };
12184
+ onInput(event) {
12185
+ const raw = event.target.value;
12186
+ this.text.set(raw);
12187
+ const trimmed = raw.trim();
12188
+ if (trimmed === '') {
12189
+ this.value.set(null);
12190
+ this.onChange(null);
12191
+ return;
12192
+ }
12193
+ const parsed = Number(trimmed);
12194
+ // Intermediate states ("-", "1.", "2e") don't parse yet — keep the text,
12195
+ // hold the last value; clamping happens on blur.
12196
+ if (Number.isFinite(parsed)) {
12197
+ this.value.set(parsed);
12198
+ this.onChange(parsed);
12199
+ }
11870
12200
  }
11871
- return t;
11872
- })();
11873
- function crc32(data) {
11874
- let c = 0xffffffff;
11875
- for (const byte of data)
11876
- c = CRC_TABLE[(c ^ byte) & 0xff] ^ (c >>> 8);
11877
- return (c ^ 0xffffffff) >>> 0;
11878
- }
11879
- const enc = new TextEncoder();
11880
- /** ZIP with STORED entries (no compression — spreadsheets are small). */
11881
- function zip(entries) {
11882
- const chunks = [];
11883
- const central = [];
11884
- let offset = 0;
11885
- const u16 = (n) => new Uint8Array([n & 0xff, (n >> 8) & 0xff]);
11886
- const u32 = (n) => new Uint8Array([n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, (n >> 24) & 0xff]);
11887
- const cat = (...parts) => {
11888
- const total = parts.reduce((s, p) => s + p.length, 0);
11889
- const out = new Uint8Array(total);
11890
- let o = 0;
11891
- for (const p of parts) {
11892
- out.set(p, o);
11893
- o += p.length;
12201
+ onKeydown(event) {
12202
+ if (this.isDisabled())
12203
+ return;
12204
+ switch (event.key) {
12205
+ case 'ArrowUp':
12206
+ event.preventDefault();
12207
+ this.stepBy(1);
12208
+ break;
12209
+ case 'ArrowDown':
12210
+ event.preventDefault();
12211
+ this.stepBy(-1);
12212
+ break;
12213
+ case 'PageUp':
12214
+ event.preventDefault();
12215
+ this.stepBy(1, 10);
12216
+ break;
12217
+ case 'PageDown':
12218
+ event.preventDefault();
12219
+ this.stepBy(-1, 10);
12220
+ break;
12221
+ case 'Home': {
12222
+ const m = this.min();
12223
+ if (m === null)
12224
+ return;
12225
+ event.preventDefault();
12226
+ this.commitTo(m);
12227
+ break;
12228
+ }
12229
+ case 'End': {
12230
+ const m = this.max();
12231
+ if (m === null)
12232
+ return;
12233
+ event.preventDefault();
12234
+ this.commitTo(m);
12235
+ break;
12236
+ }
11894
12237
  }
11895
- return out;
11896
- };
11897
- for (const { name, data } of entries) {
11898
- const nameBytes = enc.encode(name);
11899
- const crc = crc32(data);
11900
- const local = cat(u32(0x04034b50), u16(20), // version needed
11901
- u16(0), // flags
11902
- u16(0), // method: stored
11903
- u16(0), u16(0), // mod time/date
11904
- u32(crc), u32(data.length), u32(data.length), u16(nameBytes.length), u16(0), nameBytes, data);
11905
- central.push(cat(u32(0x02014b50), u16(20), u16(20), u16(0), u16(0), u16(0), u16(0), u32(crc), u32(data.length), u32(data.length), u16(nameBytes.length), u16(0), u16(0), u16(0), u16(0), u32(0), u32(offset), nameBytes));
11906
- chunks.push(local);
11907
- offset += local.length;
11908
12238
  }
11909
- const centralStart = offset;
11910
- const centralBytes = cat(...central);
11911
- const end = cat(u32(0x06054b50), u16(0), u16(0), u16(entries.length), u16(entries.length), u32(centralBytes.length), u32(centralStart), u16(0));
11912
- return cat(...chunks, centralBytes, end);
11913
- }
11914
- const xml = (s) => String(s ?? '')
11915
- .replace(/&/g, '&amp;')
11916
- .replace(/</g, '&lt;')
11917
- .replace(/>/g, '&gt;')
12239
+ /** Commit the pending text on blur: parse, clamp, restore on garbage. */
12240
+ onBlur() {
12241
+ const trimmed = this.text().trim();
12242
+ if (trimmed === '') {
12243
+ if (this.value() !== null) {
12244
+ this.value.set(null);
12245
+ this.onChange(null);
12246
+ }
12247
+ this.text.set('');
12248
+ }
12249
+ else {
12250
+ const parsed = Number(trimmed);
12251
+ if (Number.isFinite(parsed)) {
12252
+ const clamped = this.clamp(parsed);
12253
+ this.value.set(clamped);
12254
+ if (clamped !== parsed)
12255
+ this.onChange(clamped);
12256
+ this.text.set(String(clamped));
12257
+ }
12258
+ else {
12259
+ // Unparseable — restore the last committed value.
12260
+ this.text.set(this.value() === null ? '' : String(this.value()));
12261
+ }
12262
+ }
12263
+ this.onTouched();
12264
+ }
12265
+ /** Button / keyboard step: an empty field first lands on min (or 0). */
12266
+ stepBy(dir, factor = 1) {
12267
+ if (this.isDisabled())
12268
+ return;
12269
+ const v = this.value();
12270
+ if (v === null) {
12271
+ this.commitTo(this.min() ?? 0);
12272
+ return;
12273
+ }
12274
+ this.commitTo(v + dir * factor * this.step());
12275
+ }
12276
+ commitTo(n) {
12277
+ const clamped = this.clamp(this.snap(n));
12278
+ this.value.set(clamped);
12279
+ this.text.set(String(clamped));
12280
+ this.onChange(clamped);
12281
+ this.onTouched();
12282
+ }
12283
+ clamp(n) {
12284
+ const lo = this.min();
12285
+ const hi = this.max();
12286
+ if (lo !== null && n < lo)
12287
+ return lo;
12288
+ if (hi !== null && n > hi)
12289
+ return hi;
12290
+ return n;
12291
+ }
12292
+ /** Trim float dust from step arithmetic (0.1 + 0.2), not a grid snap. */
12293
+ snap(n) {
12294
+ const step = this.step();
12295
+ if (!Number.isFinite(step) || step <= 0)
12296
+ return n;
12297
+ const decimals = (String(step).split('.')[1] ?? '').length;
12298
+ return Number(n.toFixed(Math.min(decimals + 2, 12)));
12299
+ }
12300
+ writeValue(value) {
12301
+ const parsed = value === null || value === undefined ? null : Number(value);
12302
+ const v = parsed !== null && Number.isFinite(parsed) ? this.clamp(parsed) : null;
12303
+ this.value.set(v);
12304
+ this.text.set(v === null ? '' : String(v));
12305
+ }
12306
+ registerOnChange(fn) {
12307
+ this.onChange = fn;
12308
+ }
12309
+ registerOnTouched(fn) {
12310
+ this.onTouched = fn;
12311
+ }
12312
+ setDisabledState(isDisabled) {
12313
+ this.cvaDisabled.set(isDisabled);
12314
+ }
12315
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctNumber, deps: [], target: i0.ɵɵFactoryTarget.Component });
12316
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: StrctNumber, isStandalone: true, selector: "strct-number", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, incrementLabel: { classPropertyName: "incrementLabel", publicName: "incrementLabel", isSignal: true, isRequired: false, transformFunction: null }, decrementLabel: { classPropertyName: "decrementLabel", publicName: "decrementLabel", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "strct-num" }, providers: [
12317
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => StrctNumber), multi: true },
12318
+ ], ngImport: i0, template: `
12319
+ <div class="strct-num__wrap">
12320
+ <button
12321
+ type="button"
12322
+ class="strct-num__btn"
12323
+ [attr.aria-label]="decrementLabel()"
12324
+ [disabled]="isDisabled() || atMin()"
12325
+ (click)="stepBy(-1)"
12326
+ >
12327
+ <strct-icon strictName="minus" [size]="12" [strokeWidth]="1.8" />
12328
+ </button>
12329
+ <input
12330
+ type="text"
12331
+ inputmode="decimal"
12332
+ class="strct-control strct-num__input"
12333
+ role="spinbutton"
12334
+ [attr.aria-valuemin]="min()"
12335
+ [attr.aria-valuemax]="max()"
12336
+ [attr.aria-valuenow]="value()"
12337
+ [placeholder]="placeholder()"
12338
+ [value]="text()"
12339
+ [disabled]="isDisabled()"
12340
+ (input)="onInput($event)"
12341
+ (keydown)="onKeydown($event)"
12342
+ (blur)="onBlur()"
12343
+ />
12344
+ <button
12345
+ type="button"
12346
+ class="strct-num__btn"
12347
+ [attr.aria-label]="incrementLabel()"
12348
+ [disabled]="isDisabled() || atMax()"
12349
+ (click)="stepBy(1)"
12350
+ >
12351
+ <strct-icon strictName="plus" [size]="12" [strokeWidth]="1.8" />
12352
+ </button>
12353
+ </div>
12354
+ `, isInline: true, styles: [".strct-num{display:block;width:100%}.strct-num__wrap{display:flex;align-items:stretch;gap:var(--space-1)}.strct-num__input{flex:1;min-width:0;text-align:center;font-variant-numeric:tabular-nums}.strct-num__btn{display:inline-flex;align-items:center;justify-content:center;flex:none;padding-inline:var(--space-2);color:var(--t2);background:var(--bg-2);border:1px solid var(--b2);border-radius:var(--radius-md);cursor:pointer;transition:border-color .14s ease,color .14s ease,background .14s ease}.strct-num__btn:hover:not(:disabled){color:var(--t1);border-color:var(--b3);background:var(--bg-3)}.strct-num__btn:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
12355
+ }
12356
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctNumber, decorators: [{
12357
+ type: Component,
12358
+ args: [{ selector: 'strct-number', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctIcon], providers: [
12359
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => StrctNumber), multi: true },
12360
+ ], template: `
12361
+ <div class="strct-num__wrap">
12362
+ <button
12363
+ type="button"
12364
+ class="strct-num__btn"
12365
+ [attr.aria-label]="decrementLabel()"
12366
+ [disabled]="isDisabled() || atMin()"
12367
+ (click)="stepBy(-1)"
12368
+ >
12369
+ <strct-icon strictName="minus" [size]="12" [strokeWidth]="1.8" />
12370
+ </button>
12371
+ <input
12372
+ type="text"
12373
+ inputmode="decimal"
12374
+ class="strct-control strct-num__input"
12375
+ role="spinbutton"
12376
+ [attr.aria-valuemin]="min()"
12377
+ [attr.aria-valuemax]="max()"
12378
+ [attr.aria-valuenow]="value()"
12379
+ [placeholder]="placeholder()"
12380
+ [value]="text()"
12381
+ [disabled]="isDisabled()"
12382
+ (input)="onInput($event)"
12383
+ (keydown)="onKeydown($event)"
12384
+ (blur)="onBlur()"
12385
+ />
12386
+ <button
12387
+ type="button"
12388
+ class="strct-num__btn"
12389
+ [attr.aria-label]="incrementLabel()"
12390
+ [disabled]="isDisabled() || atMax()"
12391
+ (click)="stepBy(1)"
12392
+ >
12393
+ <strct-icon strictName="plus" [size]="12" [strokeWidth]="1.8" />
12394
+ </button>
12395
+ </div>
12396
+ `, host: { class: 'strct-num' }, styles: [".strct-num{display:block;width:100%}.strct-num__wrap{display:flex;align-items:stretch;gap:var(--space-1)}.strct-num__input{flex:1;min-width:0;text-align:center;font-variant-numeric:tabular-nums}.strct-num__btn{display:inline-flex;align-items:center;justify-content:center;flex:none;padding-inline:var(--space-2);color:var(--t2);background:var(--bg-2);border:1px solid var(--b2);border-radius:var(--radius-md);cursor:pointer;transition:border-color .14s ease,color .14s ease,background .14s ease}.strct-num__btn:hover:not(:disabled){color:var(--t1);border-color:var(--b3);background:var(--bg-3)}.strct-num__btn:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}\n"] }]
12397
+ }], propDecorators: { min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], incrementLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "incrementLabel", required: false }] }], decrementLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "decrementLabel", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
12398
+
12399
+ /**
12400
+ * Minimal, dependency-free XLSX writer for the datagrid's Excel export.
12401
+ *
12402
+ * An .xlsx file is a ZIP of SpreadsheetML parts. This builds the five
12403
+ * required parts with inline strings and zips them with STORED (uncompressed)
12404
+ * entries — no runtime dependency, byte-accurate CRC32, opens in Excel,
12405
+ * LibreOffice and Google Sheets.
12406
+ */
12407
+ const CRC_TABLE = (() => {
12408
+ const t = new Uint32Array(256);
12409
+ for (let n = 0; n < 256; n++) {
12410
+ let c = n;
12411
+ for (let k = 0; k < 8; k++)
12412
+ c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
12413
+ t[n] = c >>> 0;
12414
+ }
12415
+ return t;
12416
+ })();
12417
+ function crc32(data) {
12418
+ let c = 0xffffffff;
12419
+ for (const byte of data)
12420
+ c = CRC_TABLE[(c ^ byte) & 0xff] ^ (c >>> 8);
12421
+ return (c ^ 0xffffffff) >>> 0;
12422
+ }
12423
+ const enc = new TextEncoder();
12424
+ /** ZIP with STORED entries (no compression — spreadsheets are small). */
12425
+ function zip(entries) {
12426
+ const chunks = [];
12427
+ const central = [];
12428
+ let offset = 0;
12429
+ const u16 = (n) => new Uint8Array([n & 0xff, (n >> 8) & 0xff]);
12430
+ const u32 = (n) => new Uint8Array([n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, (n >> 24) & 0xff]);
12431
+ const cat = (...parts) => {
12432
+ const total = parts.reduce((s, p) => s + p.length, 0);
12433
+ const out = new Uint8Array(total);
12434
+ let o = 0;
12435
+ for (const p of parts) {
12436
+ out.set(p, o);
12437
+ o += p.length;
12438
+ }
12439
+ return out;
12440
+ };
12441
+ for (const { name, data } of entries) {
12442
+ const nameBytes = enc.encode(name);
12443
+ const crc = crc32(data);
12444
+ const local = cat(u32(0x04034b50), u16(20), // version needed
12445
+ u16(0), // flags
12446
+ u16(0), // method: stored
12447
+ u16(0), u16(0), // mod time/date
12448
+ u32(crc), u32(data.length), u32(data.length), u16(nameBytes.length), u16(0), nameBytes, data);
12449
+ central.push(cat(u32(0x02014b50), u16(20), u16(20), u16(0), u16(0), u16(0), u16(0), u32(crc), u32(data.length), u32(data.length), u16(nameBytes.length), u16(0), u16(0), u16(0), u16(0), u32(0), u32(offset), nameBytes));
12450
+ chunks.push(local);
12451
+ offset += local.length;
12452
+ }
12453
+ const centralStart = offset;
12454
+ const centralBytes = cat(...central);
12455
+ const end = cat(u32(0x06054b50), u16(0), u16(0), u16(entries.length), u16(entries.length), u32(centralBytes.length), u32(centralStart), u16(0));
12456
+ return cat(...chunks, centralBytes, end);
12457
+ }
12458
+ const xml = (s) => String(s ?? '')
12459
+ .replace(/&/g, '&amp;')
12460
+ .replace(/</g, '&lt;')
12461
+ .replace(/>/g, '&gt;')
11918
12462
  .replace(/"/g, '&quot;');
11919
12463
  /** A1-style column ref: 0 → A, 26 → AA … */
11920
12464
  function colRef(i) {
@@ -12216,8 +12760,9 @@ class StrctDatagrid {
12216
12760
  rowAction = output();
12217
12761
  /** Server-side data request (lazy mode): load this page / sort and set `rows`. */
12218
12762
  lazyLoad = output();
12219
- /** An editable cell was committed (Enter / blur). The grid does not mutate
12220
- * rows — apply `value` to your data and pass the updated array back in. */
12763
+ /** An editable cell was committed (Enter / blur, or choosing in a `select`
12764
+ * editor). The grid does not mutate rows — apply the value to your data and
12765
+ * pass the updated array back in. */
12221
12766
  cellEdit = output();
12222
12767
  menu = inject(StrctMenuService);
12223
12768
  detailDef = contentChild(StrctRowDetailDef, /* @ts-ignore */
@@ -12592,9 +13137,80 @@ class StrctDatagrid {
12592
13137
  const e = this.editing();
12593
13138
  return !!e && e.rowKey === this.rowKey(row) && e.colKey === col.key;
12594
13139
  }
13140
+ /** The value a typed editor holds while it is open (committed on Enter / blur). */
13141
+ editDraft = signal(null, /* @ts-ignore */
13142
+ ...(ngDevMode ? [{ debugName: "editDraft" }] : /* istanbul ignore next */ []));
12595
13143
  startEdit(row, col) {
12596
13144
  this.editing.set({ rowKey: this.rowKey(row), colKey: col.key });
12597
- setTimeout(() => this.hostRef.nativeElement.querySelector('.strct-dg__editinput')?.focus());
13145
+ this.editDraft.set(row[col.key]);
13146
+ setTimeout(() => {
13147
+ const editor = this.hostRef.nativeElement.querySelector('.strct-dg__editinput, .strct-dg__editselect, .strct-dg__editnumber');
13148
+ if (!editor)
13149
+ return;
13150
+ // The stepper buttons come first in the DOM; the value is what the user
13151
+ // came to change, so focus lands on the field itself.
13152
+ (editor.matches('input')
13153
+ ? editor
13154
+ : (editor.querySelector('input') ??
13155
+ editor.querySelector('button')))?.focus();
13156
+ });
13157
+ }
13158
+ /** A select column reads as its option's label, not as the stored value. */
13159
+ displayValue(row, col) {
13160
+ const raw = row[col.key];
13161
+ if (col.editor !== 'select')
13162
+ return raw;
13163
+ return col.editorOptions?.find((o) => o.value === raw)?.label ?? raw;
13164
+ }
13165
+ /** Close the editor and emit `cellEdit` when the value actually changed. */
13166
+ commitValue(row, col, raw) {
13167
+ if (!this.isEditingCell(row, col))
13168
+ return;
13169
+ this.editing.set(null);
13170
+ const value = this.clampToColumn(col, raw);
13171
+ const previous = row[col.key];
13172
+ if (previous === value)
13173
+ return;
13174
+ this.cellEdit.emit({
13175
+ row,
13176
+ column: col,
13177
+ value: value == null ? '' : String(value),
13178
+ typedValue: value,
13179
+ previous,
13180
+ });
13181
+ }
13182
+ /** Enter / blur on a typed editor commits what it currently holds. */
13183
+ commitDraft(row, col, event) {
13184
+ event?.stopPropagation();
13185
+ this.commitValue(row, col, this.editDraft());
13186
+ }
13187
+ /**
13188
+ * A column that declares bounds means them: Enter commits what the field
13189
+ * holds, and `strct-number` only clamps on blur, so the grid clamps here
13190
+ * rather than letting an out-of-range value reach `cellEdit`.
13191
+ */
13192
+ clampToColumn(col, value) {
13193
+ if (col.editor !== 'number' || typeof value !== 'number' || !Number.isFinite(value))
13194
+ return value;
13195
+ const min = col.editorMin;
13196
+ const max = col.editorMax;
13197
+ let v = value;
13198
+ if (min != null && v < min)
13199
+ v = min;
13200
+ if (max != null && v > max)
13201
+ v = max;
13202
+ return v;
13203
+ }
13204
+ /**
13205
+ * A number editor is a field between two stepper buttons, so focus moves
13206
+ * inside it — only a move that actually leaves the editor is a blur.
13207
+ */
13208
+ commitOnLeave(row, col, event) {
13209
+ const editor = event.currentTarget;
13210
+ const next = event.relatedTarget;
13211
+ if (next instanceof Node && editor.contains(next))
13212
+ return;
13213
+ this.commitDraft(row, col, event);
12598
13214
  }
12599
13215
  commitEdit(row, col, event) {
12600
13216
  if (!this.isEditingCell(row, col))
@@ -12603,7 +13219,7 @@ class StrctDatagrid {
12603
13219
  this.editing.set(null);
12604
13220
  const previous = row[col.key];
12605
13221
  if (String(previous ?? '') !== value)
12606
- this.cellEdit.emit({ row, column: col, value, previous });
13222
+ this.cellEdit.emit({ row, column: col, value, typedValue: value, previous });
12607
13223
  }
12608
13224
  cancelEdit(event) {
12609
13225
  event?.stopPropagation();
@@ -13716,16 +14332,47 @@ class StrctDatagrid {
13716
14332
  }
13717
14333
  }
13718
14334
  @if (isEditingCell(row, col)) {
13719
- <input
13720
- class="strct-dg__editinput"
13721
- type="text"
13722
- [value]="row[col.key] ?? ''"
13723
- [attr.aria-label]="L().editCell + ': ' + col.label"
13724
- (keydown.enter)="commitEdit(row, col, $event)"
13725
- (keydown.escape)="cancelEdit($event)"
13726
- (blur)="commitEdit(row, col, $event)"
13727
- (click)="$event.stopPropagation()"
13728
- />
14335
+ @switch (col.editor ?? 'text') {
14336
+ @case ('select') {
14337
+ <!-- Choosing is the commit: there is nothing to
14338
+ confirm with Enter once an option is picked. -->
14339
+ <strct-select
14340
+ class="strct-dg__editselect"
14341
+ [options]="col.editorOptions ?? []"
14342
+ [listLabel]="L().editCell + ': ' + col.label"
14343
+ [ngModel]="row[col.key]"
14344
+ (ngModelChange)="commitValue(row, col, $event)"
14345
+ (keydown.escape)="cancelEdit($event)"
14346
+ (click)="$event.stopPropagation()"
14347
+ />
14348
+ }
14349
+ @case ('number') {
14350
+ <strct-number
14351
+ class="strct-dg__editnumber"
14352
+ [min]="col.editorMin ?? null"
14353
+ [max]="col.editorMax ?? null"
14354
+ [step]="col.editorStep ?? 1"
14355
+ [ngModel]="row[col.key]"
14356
+ (ngModelChange)="editDraft.set($event)"
14357
+ (keydown.enter)="commitDraft(row, col, $event)"
14358
+ (keydown.escape)="cancelEdit($event)"
14359
+ (focusout)="commitOnLeave(row, col, $event)"
14360
+ (click)="$event.stopPropagation()"
14361
+ />
14362
+ }
14363
+ @default {
14364
+ <input
14365
+ class="strct-dg__editinput"
14366
+ type="text"
14367
+ [value]="row[col.key] ?? ''"
14368
+ [attr.aria-label]="L().editCell + ': ' + col.label"
14369
+ (keydown.enter)="commitEdit(row, col, $event)"
14370
+ (keydown.escape)="cancelEdit($event)"
14371
+ (blur)="commitEdit(row, col, $event)"
14372
+ (click)="$event.stopPropagation()"
14373
+ />
14374
+ }
14375
+ }
13729
14376
  } @else if (cellTemplate(col.key); as tpl) {
13730
14377
  <ng-container
13731
14378
  [ngTemplateOutlet]="tpl"
@@ -13737,7 +14384,7 @@ class StrctDatagrid {
13737
14384
  }"
13738
14385
  />
13739
14386
  } @else {
13740
- {{ row[col.key] }}
14387
+ {{ displayValue(row, col) }}
13741
14388
  }
13742
14389
  </td>
13743
14390
  }
@@ -13872,7 +14519,7 @@ class StrctDatagrid {
13872
14519
  </div>
13873
14520
  </div>
13874
14521
  }
13875
- `, isInline: true, styles: [".strct-dg__radio{width:15px;height:15px;accent-color:var(--acc);cursor:pointer}.strct-dg__radio:disabled{cursor:not-allowed}.strct-dg__row--locked .strct-dg__sel{opacity:.55}.strct-dg__actioncaption:empty{display:none}.strct-dg__actioncaption{display:inline-flex;align-items:center;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-sm);color:var(--t3)}.strct-dg-host{display:block;border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-2);box-shadow:var(--shadow-rest)}.strct-dg__scroll{flex:1 1 auto;min-width:0;overflow-x:auto;-webkit-overflow-scrolling:touch}.strct-dg-host--virtual .strct-dg__scroll{overflow-y:auto}.strct-dg-host--virtual .strct-dg thead th{position:sticky;top:0;z-index:var(--z-raised)}.strct-dg__vspacer td{padding:0;border:0;background:transparent}.strct-dg th[draggable]{cursor:grab}.strct-dg__th--drop{box-shadow:inset 3px 0 0 var(--acc)}.strct-dg__grouprow td{background:var(--bg-2)!important;padding:0}.strct-dg__groupbtn{display:flex;align-items:center;gap:8px;width:100%;padding:7px 13px;border:0;background:transparent;color:var(--t1);font-family:var(--font);font-size:12.5px;font-weight:600;cursor:pointer;text-align:start}.strct-dg__groupbtn:hover{background:var(--bg-3)}.strct-dg__groupbtn:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__groupchev{display:inline-flex;color:var(--t3);transition:transform .15s ease}.strct-dg__groupchev--open{transform:rotate(90deg)}@media(prefers-reduced-motion:reduce){.strct-dg__groupchev{transition:none}}.strct-dg__groupcount{min-width:18px;height:18px;padding:0 5px;display:inline-flex;align-items:center;justify-content:center;font-size:12px;border-radius:9px;background:var(--acc-m);color:var(--acc);font-variant-numeric:tabular-nums}.strct-dg-host--sticky .strct-dg,.strct-dg-host--virtual .strct-dg{border-collapse:separate;border-spacing:0;overflow:visible;border-radius:0}.strct-dg-host--sticky .strct-dg{width:max-content;min-width:100%}.strct-dg .strct-dg__cell--sticky{position:sticky;z-index:calc(var(--z-base) + 2)}.strct-dg thead th.strct-dg__cell--sticky{z-index:calc(var(--z-raised) + 1)}.strct-dg .strct-dg__cell--sticky-last:after{content:\"\";position:absolute;top:0;bottom:0;inset-inline-end:-1px;width:7px;pointer-events:none;background:linear-gradient(to right,rgba(0,0,0,.14),transparent)}[dir=rtl] .strct-dg .strct-dg__cell--sticky-last:after{background:linear-gradient(to left,rgba(0,0,0,.14),transparent)}.strct-dg-host--sticky .strct-dg__expandcol,.strct-dg-host--sticky .strct-dg__expandcell{width:36px;min-width:36px;max-width:36px;box-sizing:border-box}.strct-dg-host--sticky .strct-dg__sel{width:40px;min-width:40px;max-width:40px;box-sizing:border-box}.strct-dg-host--sticky tbody .strct-dg__cell--sticky{background:var(--bg-1)}[data-theme=dark] .strct-dg-host--sticky tbody .strct-dg__cell--sticky{background:var(--bg-3)}.strct-dg-host--sticky tbody tr:hover .strct-dg__cell--sticky{background:linear-gradient(var(--acc-s),var(--acc-s)) var(--bg-1)}[data-theme=dark] .strct-dg-host--sticky tbody tr:hover .strct-dg__cell--sticky{background:linear-gradient(var(--acc-s),var(--acc-s)) var(--bg-3)}.strct-dg-host--sticky tbody .strct-dg__row--selected .strct-dg__cell--sticky{background:linear-gradient(var(--acc-m),var(--acc-m)) var(--bg-1)}[data-theme=dark] .strct-dg-host--sticky tbody .strct-dg__row--selected .strct-dg__cell--sticky{background:linear-gradient(var(--acc-m),var(--acc-m)) var(--bg-3)}.strct-dg{width:100%;border-collapse:collapse;font-size:13px;overflow:hidden;background:var(--bg-2)}.strct-dg-host:not(:has(.strct-dg__toolbar)) .strct-dg{border-start-start-radius:9px;border-start-end-radius:9px}.strct-dg-host:not(:has(.strct-dg__foot)) .strct-dg{border-end-start-radius:9px;border-end-end-radius:9px}.strct-dg th,.strct-dg td{padding:9px 13px;text-align:start;border-bottom:1px solid var(--b1)}.strct-dg tbody td{background:var(--bg-1)}[data-theme=dark] .strct-dg tbody td{background:var(--bg-3)}.strct-dg-host--compact .strct-dg th,.strct-dg-host--compact .strct-dg td{padding:5px 11px}.strct-dg-host--singleline .strct-dg tbody tr:not(.strct-dg__detailrow)>td{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:360px}.strct-dg th{position:relative;font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--t2);background:var(--bg-2);white-space:nowrap;-webkit-user-select:none;user-select:none}.strct-dg__th--sortable{cursor:pointer}.strct-dg__th--sortable:hover{color:var(--t1)}.strct-dg__th--sortable:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__hd{display:inline-flex;align-items:center;gap:5px}.strct-dg__sorticon{color:var(--t3)}.strct-dg__th--sortable:hover .strct-dg__sorticon{color:var(--acc)}.strct-dg__resize{position:absolute;inset-inline-end:0;top:0;bottom:0;width:4px;cursor:col-resize;background:transparent;z-index:calc(var(--z-base) + 1)}.strct-dg__resize:hover{background:var(--acc)}.strct-dg td{color:var(--t1)}.strct-dg tbody tr:last-child td{border-bottom:0}.strct-dg tbody tr:not(.strct-dg__detailrow):hover td{background:var(--acc-s)}.strct-dg__row--selected td{background:var(--acc-m)}.strct-dg__sel{width:1%;white-space:nowrap}.strct-dg__sel input{accent-color:var(--acc);width:15px;height:15px;cursor:pointer}.strct-dg__expandcol,.strct-dg__expandcell{width:1%;white-space:nowrap}.strct-dg__actioncol,.strct-dg__actioncell{width:1%;white-space:nowrap;text-align:end}.strct-dg__kebab{display:inline-flex;padding:4px;border:0;border-radius:5px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-dg__kebab:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__expandbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:transform .15s ease,color .15s ease}.strct-dg__expandbtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__expandbtn--open{transform:rotate(90deg);color:var(--acc)}.strct-dg__detailbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-dg__detailbtn:hover{color:var(--acc);background:var(--bg-3)}.strct-dg__detailbtn--active{color:var(--acc);background:var(--acc-m)}.strct-dg__detailrow td{background:var(--bg-2);padding:0}.strct-dg__detail{padding:14px 16px;font-size:13px;color:var(--t2)}.strct-dg__layout{display:flex;align-items:flex-start;min-width:0}.strct-dg__layout--paned{gap:0}.strct-dg__layout--paned .strct-dg__scroll{flex:0 0 auto;width:260px;min-width:260px;max-width:260px}.strct-dg__layout--paned .strct-dg{width:260px;min-width:260px;max-width:260px;flex-shrink:0;border-start-end-radius:0;border-end-end-radius:0}.strct-dg__row--clickable{cursor:pointer}.strct-dg__row--active td{background:var(--acc-m)}.strct-dg__layout--paned .strct-dg__row--active td:last-child{position:relative;padding-inline-end:26px}.strct-dg__layout--paned .strct-dg__row--active td:last-child:after{content:\"\";position:absolute;inset-inline-end:11px;top:50%;width:6px;height:6px;border-top:1.6px solid var(--acc);border-inline-end:1.6px solid var(--acc);transform:translateY(-50%) rotate(45deg)}.strct-dg__pane{flex:1;min-width:0;align-self:stretch;background:var(--bg-1);border:1px solid var(--b2);border-inline-start:2px solid var(--acc);border-radius:8px;border-start-start-radius:0;border-end-start-radius:0;overflow:hidden;animation:strct-dg-pane-in .14s ease}.strct-dg__pane-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:11px 14px;border-bottom:1px solid var(--b1);font-size:13px;font-weight:600;color:var(--t1)}.strct-dg__pane-close{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer}.strct-dg__pane-close:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__pane-body{padding:14px 16px;font-size:13px;color:var(--t2)}@keyframes strct-dg-pane-in{0%{opacity:0;transform:translate(8px)}}@keyframes strct-skeleton-pulse{0%,to{opacity:.4}50%{opacity:.7}}.strct-dg__skeleton-block{height:12px;border-radius:var(--radius-sm);background:linear-gradient(90deg,var(--bg-3) 25%,var(--skeleton-hi, var(--acc18)) 50%,var(--bg-3) 75%);background-size:200% 100%;animation:strct-dg-skeleton-sweep 1.1s linear infinite}@keyframes strct-dg-skeleton-sweep{0%{background-position:100% 0}to{background-position:-100% 0}}@media(prefers-reduced-motion:reduce){.strct-dg__skeleton-block{animation:none;background:var(--skeleton-hi, var(--acc18))}}.strct-dg__skeleton-row td{border-bottom:1px solid var(--b1)}.strct-dg__empty{text-align:center;color:var(--t3);padding:22px}.strct-dg__quickfilter{min-width:180px;max-width:260px}.strct-dg__quickfilter--end{order:2;margin-inline-start:auto}.strct-dg__filternote--end{order:3}.strct-dg__filternote{font-size:11.5px;color:var(--t3);font-variant-numeric:tabular-nums;white-space:nowrap}.strct-dg__toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:9px 14px;border-bottom:1px solid var(--b2)}.strct-dg__foot{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 14px;border-top:1px solid var(--b2);flex-wrap:wrap}.strct-dg__foot-left,.strct-dg__foot-right{display:flex;align-items:center;gap:12px}.strct-dg__actions{position:relative}.strct-dg__chooser-menu{position:absolute;bottom:calc(100% + 6px);inset-inline-start:0;z-index:var(--z-sticky);min-width:180px;background:var(--bg-1);border:1px solid var(--b2);border-radius:8px;box-shadow:var(--shadow-pop);padding:6px;display:flex;flex-direction:column;gap:2px}.strct-dg__chooser-menu--right{inset-inline-start:auto;inset-inline-end:0}.strct-dg__chooser-item{display:flex;align-items:center;gap:8px;padding:5px 8px;border-radius:6px;cursor:pointer;font-size:12px;color:var(--t1);transition:background .1s ease;-webkit-user-select:none;user-select:none}.strct-dg__chooser-item:hover{background:var(--bg-3)}.strct-dg__count{font-size:12px;color:var(--t2)}.strct-dg__count-sep{margin:0 8px;color:var(--b2)}.strct-dg__count-sel{color:var(--acc)}.strct-dg__filterbtn{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin-inline-start:2px;padding:0;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;vertical-align:middle}.strct-dg__filterbtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__filterbtn--active{color:var(--acc)}.strct-dg__filterbtn:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}.strct-dg__filterpanel{position:absolute;z-index:calc(var(--z-dropdown) + 10);display:flex;flex-direction:column;gap:6px;min-width:180px;padding:10px;background:var(--bg-1);border:1px solid var(--b2);border-radius:7px;box-shadow:var(--shh);font-weight:400;text-transform:none;letter-spacing:normal;white-space:nowrap}.strct-dg__filterinput{padding:5px 8px;border:1px solid var(--b2);border-radius:var(--radius-sm);background:var(--bg-2);color:var(--t1);font-family:var(--font);font-size:12px}.strct-dg__filterinput:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}.strct-dg__filteropt{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--t1);cursor:pointer}.strct-dg__filterclear{align-self:flex-start;padding:3px 8px;border:1px solid var(--b2);border-radius:var(--radius-sm);background:transparent;color:var(--t2);font-family:var(--font);font-size:11.5px;cursor:pointer}.strct-dg__filterclear:hover:not(:disabled){color:var(--t1);background:var(--bg-3)}.strct-dg__filterclear:disabled{color:var(--t4);cursor:default}.strct-dg tbody tr[tabindex]:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__treepad{display:inline-block;height:1px;vertical-align:middle}.strct-dg__treebtn{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;margin-inline-end:4px;padding:0;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;vertical-align:middle}.strct-dg__treebtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__treebtn:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}.strct-dg__treebtn strct-icon{transition:transform .15s ease}.strct-dg__treebtn--open strct-icon{transform:rotate(90deg)}.strct-dg__treebtn--leaf{cursor:default;pointer-events:none}@media(prefers-reduced-motion:reduce){.strct-dg__treebtn strct-icon{transition:none}}.strct-dg__cell--editable{cursor:text}.strct-dg__cell--editable:hover{box-shadow:inset 0 0 0 1px var(--b2)}.strct-dg__editinput{width:100%;box-sizing:border-box;padding:3px 6px;border:1px solid var(--acc);border-radius:var(--radius-sm);background:var(--bg-1);color:var(--t1);font:inherit}.strct-dg__editinput:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel"] }, { kind: "component", type: StrctPagination, selector: "strct-pagination", inputs: ["prevLabel", "nextLabel", "regionLabel", "pageLabel", "total", "pageSize", "page"], outputs: ["pageChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: StrctCheckbox, selector: "strct-checkbox", inputs: ["checked", "disabled", "indeterminate", "ariaLabel"], outputs: ["checkedChange"] }, { kind: "component", type: StrctButton, selector: "button[strct-button], a[strct-button]", inputs: ["variant", "size", "solid", "block", "iconOnly"] }, { kind: "component", type: StrctButtonGroup, selector: "strct-button-group" }, { kind: "directive", type: StrctOverlay, selector: "[strctOverlay]", inputs: ["strctOverlay", "strctOverlayPlacement", "strctOverlayMatchWidth", "strctOverlayGap"] }, { kind: "component", type: StrctSearchbox, selector: "strct-searchbox", inputs: ["placeholder", "hint", "trigger", "clearable", "ariaLabel", "clearLabel", "value"], outputs: ["valueChange", "search", "activated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
14522
+ `, isInline: true, styles: [".strct-dg__radio{width:15px;height:15px;accent-color:var(--acc);cursor:pointer}.strct-dg__radio:disabled{cursor:not-allowed}.strct-dg__row--locked .strct-dg__sel{opacity:.55}.strct-dg__actioncaption:empty{display:none}.strct-dg__actioncaption{display:inline-flex;align-items:center;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-sm);color:var(--t3)}.strct-dg-host{display:block;border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-2);box-shadow:var(--shadow-rest)}.strct-dg__scroll{flex:1 1 auto;min-width:0;overflow-x:auto;-webkit-overflow-scrolling:touch}.strct-dg-host--virtual .strct-dg__scroll{overflow-y:auto}.strct-dg-host--virtual .strct-dg thead th{position:sticky;top:0;z-index:var(--z-raised)}.strct-dg__vspacer td{padding:0;border:0;background:transparent}.strct-dg th[draggable]{cursor:grab}.strct-dg__th--drop{box-shadow:inset 3px 0 0 var(--acc)}.strct-dg__grouprow td{background:var(--bg-2)!important;padding:0}.strct-dg__groupbtn{display:flex;align-items:center;gap:8px;width:100%;padding:7px 13px;border:0;background:transparent;color:var(--t1);font-family:var(--font);font-size:12.5px;font-weight:600;cursor:pointer;text-align:start}.strct-dg__groupbtn:hover{background:var(--bg-3)}.strct-dg__groupbtn:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__groupchev{display:inline-flex;color:var(--t3);transition:transform .15s ease}.strct-dg__groupchev--open{transform:rotate(90deg)}@media(prefers-reduced-motion:reduce){.strct-dg__groupchev{transition:none}}.strct-dg__groupcount{min-width:18px;height:18px;padding:0 5px;display:inline-flex;align-items:center;justify-content:center;font-size:12px;border-radius:9px;background:var(--acc-m);color:var(--acc);font-variant-numeric:tabular-nums}.strct-dg-host--sticky .strct-dg,.strct-dg-host--virtual .strct-dg{border-collapse:separate;border-spacing:0;overflow:visible;border-radius:0}.strct-dg-host--sticky .strct-dg{width:max-content;min-width:100%}.strct-dg .strct-dg__cell--sticky{position:sticky;z-index:calc(var(--z-base) + 2)}.strct-dg thead th.strct-dg__cell--sticky{z-index:calc(var(--z-raised) + 1)}.strct-dg .strct-dg__cell--sticky-last:after{content:\"\";position:absolute;top:0;bottom:0;inset-inline-end:-1px;width:7px;pointer-events:none;background:linear-gradient(to right,rgba(0,0,0,.14),transparent)}[dir=rtl] .strct-dg .strct-dg__cell--sticky-last:after{background:linear-gradient(to left,rgba(0,0,0,.14),transparent)}.strct-dg-host--sticky .strct-dg__expandcol,.strct-dg-host--sticky .strct-dg__expandcell{width:36px;min-width:36px;max-width:36px;box-sizing:border-box}.strct-dg-host--sticky .strct-dg__sel{width:40px;min-width:40px;max-width:40px;box-sizing:border-box}.strct-dg-host--sticky tbody .strct-dg__cell--sticky{background:var(--bg-1)}[data-theme=dark] .strct-dg-host--sticky tbody .strct-dg__cell--sticky{background:var(--bg-3)}.strct-dg-host--sticky tbody tr:hover .strct-dg__cell--sticky{background:linear-gradient(var(--acc-s),var(--acc-s)) var(--bg-1)}[data-theme=dark] .strct-dg-host--sticky tbody tr:hover .strct-dg__cell--sticky{background:linear-gradient(var(--acc-s),var(--acc-s)) var(--bg-3)}.strct-dg-host--sticky tbody .strct-dg__row--selected .strct-dg__cell--sticky{background:linear-gradient(var(--acc-m),var(--acc-m)) var(--bg-1)}[data-theme=dark] .strct-dg-host--sticky tbody .strct-dg__row--selected .strct-dg__cell--sticky{background:linear-gradient(var(--acc-m),var(--acc-m)) var(--bg-3)}.strct-dg{width:100%;border-collapse:collapse;font-size:13px;overflow:hidden;background:var(--bg-2)}.strct-dg-host:not(:has(.strct-dg__toolbar)) .strct-dg{border-start-start-radius:9px;border-start-end-radius:9px}.strct-dg-host:not(:has(.strct-dg__foot)) .strct-dg{border-end-start-radius:9px;border-end-end-radius:9px}.strct-dg th,.strct-dg td{padding:9px 13px;text-align:start;border-bottom:1px solid var(--b1)}.strct-dg tbody td{background:var(--bg-1)}[data-theme=dark] .strct-dg tbody td{background:var(--bg-3)}.strct-dg-host--compact .strct-dg th,.strct-dg-host--compact .strct-dg td{padding:5px 11px}.strct-dg-host--singleline .strct-dg tbody tr:not(.strct-dg__detailrow)>td{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:360px}.strct-dg th{position:relative;font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--t2);background:var(--bg-2);white-space:nowrap;-webkit-user-select:none;user-select:none}.strct-dg__th--sortable{cursor:pointer}.strct-dg__th--sortable:hover{color:var(--t1)}.strct-dg__th--sortable:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__hd{display:inline-flex;align-items:center;gap:5px}.strct-dg__sorticon{color:var(--t3)}.strct-dg__th--sortable:hover .strct-dg__sorticon{color:var(--acc)}.strct-dg__resize{position:absolute;inset-inline-end:0;top:0;bottom:0;width:4px;cursor:col-resize;background:transparent;z-index:calc(var(--z-base) + 1)}.strct-dg__resize:hover{background:var(--acc)}.strct-dg td{color:var(--t1)}.strct-dg tbody tr:last-child td{border-bottom:0}.strct-dg tbody tr:not(.strct-dg__detailrow):hover td{background:var(--acc-s)}.strct-dg__row--selected td{background:var(--acc-m)}.strct-dg__sel{width:1%;white-space:nowrap}.strct-dg__sel input{accent-color:var(--acc);width:15px;height:15px;cursor:pointer}.strct-dg__expandcol,.strct-dg__expandcell{width:1%;white-space:nowrap}.strct-dg__actioncol,.strct-dg__actioncell{width:1%;white-space:nowrap;text-align:end}.strct-dg__kebab{display:inline-flex;padding:4px;border:0;border-radius:5px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-dg__kebab:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__expandbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:transform .15s ease,color .15s ease}.strct-dg__expandbtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__expandbtn--open{transform:rotate(90deg);color:var(--acc)}.strct-dg__detailbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-dg__detailbtn:hover{color:var(--acc);background:var(--bg-3)}.strct-dg__detailbtn--active{color:var(--acc);background:var(--acc-m)}.strct-dg__detailrow td{background:var(--bg-2);padding:0}.strct-dg__detail{padding:14px 16px;font-size:13px;color:var(--t2)}.strct-dg__layout{display:flex;align-items:flex-start;min-width:0}.strct-dg__layout--paned{gap:0}.strct-dg__layout--paned .strct-dg__scroll{flex:0 0 auto;width:260px;min-width:260px;max-width:260px}.strct-dg__layout--paned .strct-dg{width:260px;min-width:260px;max-width:260px;flex-shrink:0;border-start-end-radius:0;border-end-end-radius:0}.strct-dg__row--clickable{cursor:pointer}.strct-dg__row--active td{background:var(--acc-m)}.strct-dg__layout--paned .strct-dg__row--active td:last-child{position:relative;padding-inline-end:26px}.strct-dg__layout--paned .strct-dg__row--active td:last-child:after{content:\"\";position:absolute;inset-inline-end:11px;top:50%;width:6px;height:6px;border-top:1.6px solid var(--acc);border-inline-end:1.6px solid var(--acc);transform:translateY(-50%) rotate(45deg)}.strct-dg__pane{flex:1;min-width:0;align-self:stretch;background:var(--bg-1);border:1px solid var(--b2);border-inline-start:2px solid var(--acc);border-radius:8px;border-start-start-radius:0;border-end-start-radius:0;overflow:hidden;animation:strct-dg-pane-in .14s ease}.strct-dg__pane-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:11px 14px;border-bottom:1px solid var(--b1);font-size:13px;font-weight:600;color:var(--t1)}.strct-dg__pane-close{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer}.strct-dg__pane-close:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__pane-body{padding:14px 16px;font-size:13px;color:var(--t2)}@keyframes strct-dg-pane-in{0%{opacity:0;transform:translate(8px)}}@keyframes strct-skeleton-pulse{0%,to{opacity:.4}50%{opacity:.7}}.strct-dg__skeleton-block{height:12px;border-radius:var(--radius-sm);background:linear-gradient(90deg,var(--bg-3) 25%,var(--skeleton-hi, var(--acc18)) 50%,var(--bg-3) 75%);background-size:200% 100%;animation:strct-dg-skeleton-sweep 1.1s linear infinite}@keyframes strct-dg-skeleton-sweep{0%{background-position:100% 0}to{background-position:-100% 0}}@media(prefers-reduced-motion:reduce){.strct-dg__skeleton-block{animation:none;background:var(--skeleton-hi, var(--acc18))}}.strct-dg__skeleton-row td{border-bottom:1px solid var(--b1)}.strct-dg__empty{text-align:center;color:var(--t3);padding:22px}.strct-dg__quickfilter{min-width:180px;max-width:260px}.strct-dg__quickfilter--end{order:2;margin-inline-start:auto}.strct-dg__filternote--end{order:3}.strct-dg__filternote{font-size:11.5px;color:var(--t3);font-variant-numeric:tabular-nums;white-space:nowrap}.strct-dg__toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:9px 14px;border-bottom:1px solid var(--b2)}.strct-dg__foot{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 14px;border-top:1px solid var(--b2);flex-wrap:wrap}.strct-dg__foot-left,.strct-dg__foot-right{display:flex;align-items:center;gap:12px}.strct-dg__actions{position:relative}.strct-dg__chooser-menu{position:absolute;bottom:calc(100% + 6px);inset-inline-start:0;z-index:var(--z-sticky);min-width:180px;background:var(--bg-1);border:1px solid var(--b2);border-radius:8px;box-shadow:var(--shadow-pop);padding:6px;display:flex;flex-direction:column;gap:2px}.strct-dg__chooser-menu--right{inset-inline-start:auto;inset-inline-end:0}.strct-dg__chooser-item{display:flex;align-items:center;gap:8px;padding:5px 8px;border-radius:6px;cursor:pointer;font-size:12px;color:var(--t1);transition:background .1s ease;-webkit-user-select:none;user-select:none}.strct-dg__chooser-item:hover{background:var(--bg-3)}.strct-dg__count{font-size:12px;color:var(--t2)}.strct-dg__count-sep{margin:0 8px;color:var(--b2)}.strct-dg__count-sel{color:var(--acc)}.strct-dg__filterbtn{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin-inline-start:2px;padding:0;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;vertical-align:middle}.strct-dg__filterbtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__filterbtn--active{color:var(--acc)}.strct-dg__filterbtn:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}.strct-dg__filterpanel{position:absolute;z-index:calc(var(--z-dropdown) + 10);display:flex;flex-direction:column;gap:6px;min-width:180px;padding:10px;background:var(--bg-1);border:1px solid var(--b2);border-radius:7px;box-shadow:var(--shh);font-weight:400;text-transform:none;letter-spacing:normal;white-space:nowrap}.strct-dg__filterinput{padding:5px 8px;border:1px solid var(--b2);border-radius:var(--radius-sm);background:var(--bg-2);color:var(--t1);font-family:var(--font);font-size:12px}.strct-dg__filterinput:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}.strct-dg__filteropt{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--t1);cursor:pointer}.strct-dg__filterclear{align-self:flex-start;padding:3px 8px;border:1px solid var(--b2);border-radius:var(--radius-sm);background:transparent;color:var(--t2);font-family:var(--font);font-size:11.5px;cursor:pointer}.strct-dg__filterclear:hover:not(:disabled){color:var(--t1);background:var(--bg-3)}.strct-dg__filterclear:disabled{color:var(--t4);cursor:default}.strct-dg tbody tr[tabindex]:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__treepad{display:inline-block;height:1px;vertical-align:middle}.strct-dg__treebtn{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;margin-inline-end:4px;padding:0;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;vertical-align:middle}.strct-dg__treebtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__treebtn:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}.strct-dg__treebtn strct-icon{transition:transform .15s ease}.strct-dg__treebtn--open strct-icon{transform:rotate(90deg)}.strct-dg__treebtn--leaf{cursor:default;pointer-events:none}@media(prefers-reduced-motion:reduce){.strct-dg__treebtn strct-icon{transition:none}}.strct-dg__cell--editable{cursor:text}.strct-dg__cell--editable:hover{box-shadow:inset 0 0 0 1px var(--b2)}.strct-dg__editinput{width:100%;box-sizing:border-box;padding:3px 6px;border:1px solid var(--acc);border-radius:var(--radius-sm);background:var(--bg-1);color:var(--t1);font:inherit}.strct-dg__editselect,.strct-dg__editnumber{display:block;width:100%}.strct-dg__editinput:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel"] }, { kind: "component", type: StrctPagination, selector: "strct-pagination", inputs: ["prevLabel", "nextLabel", "regionLabel", "pageLabel", "total", "pageSize", "page"], outputs: ["pageChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: StrctCheckbox, selector: "strct-checkbox", inputs: ["checked", "disabled", "indeterminate", "ariaLabel", "description"], outputs: ["checkedChange"] }, { kind: "component", type: StrctButton, selector: "button[strct-button], a[strct-button]", inputs: ["variant", "size", "solid", "block", "iconOnly"] }, { kind: "component", type: StrctButtonGroup, selector: "strct-button-group" }, { kind: "directive", type: StrctOverlay, selector: "[strctOverlay]", inputs: ["strctOverlay", "strctOverlayPlacement", "strctOverlayMatchWidth", "strctOverlayGap"] }, { kind: "component", type: StrctSearchbox, selector: "strct-searchbox", inputs: ["placeholder", "hint", "trigger", "clearable", "ariaLabel", "clearLabel", "value"], outputs: ["valueChange", "search", "activated"] }, { kind: "component", type: StrctSelect, selector: "strct-select", inputs: ["options", "placeholder", "listLabel", "emptyText", "disabled", "compareWith"] }, { kind: "component", type: StrctNumber, selector: "strct-number", inputs: ["min", "max", "step", "placeholder", "incrementLabel", "decrementLabel", "disabled"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
13876
14523
  }
13877
14524
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctDatagrid, decorators: [{
13878
14525
  type: Component,
@@ -13885,6 +14532,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
13885
14532
  StrctButtonGroup,
13886
14533
  StrctOverlay,
13887
14534
  StrctSearchbox,
14535
+ StrctSelect,
14536
+ StrctNumber,
14537
+ FormsModule,
13888
14538
  ], template: `
13889
14539
  @if (actionBarDef() || quickFilterable()) {
13890
14540
  <div class="strct-dg__toolbar">
@@ -14249,18 +14899,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
14249
14899
  }
14250
14900
  }
14251
14901
  @if (isEditingCell(row, col)) {
14252
- <input
14253
- class="strct-dg__editinput"
14254
- type="text"
14255
- [value]="row[col.key] ?? ''"
14256
- [attr.aria-label]="L().editCell + ': ' + col.label"
14257
- (keydown.enter)="commitEdit(row, col, $event)"
14258
- (keydown.escape)="cancelEdit($event)"
14259
- (blur)="commitEdit(row, col, $event)"
14260
- (click)="$event.stopPropagation()"
14261
- />
14262
- } @else if (cellTemplate(col.key); as tpl) {
14263
- <ng-container
14902
+ @switch (col.editor ?? 'text') {
14903
+ @case ('select') {
14904
+ <!-- Choosing is the commit: there is nothing to
14905
+ confirm with Enter once an option is picked. -->
14906
+ <strct-select
14907
+ class="strct-dg__editselect"
14908
+ [options]="col.editorOptions ?? []"
14909
+ [listLabel]="L().editCell + ': ' + col.label"
14910
+ [ngModel]="row[col.key]"
14911
+ (ngModelChange)="commitValue(row, col, $event)"
14912
+ (keydown.escape)="cancelEdit($event)"
14913
+ (click)="$event.stopPropagation()"
14914
+ />
14915
+ }
14916
+ @case ('number') {
14917
+ <strct-number
14918
+ class="strct-dg__editnumber"
14919
+ [min]="col.editorMin ?? null"
14920
+ [max]="col.editorMax ?? null"
14921
+ [step]="col.editorStep ?? 1"
14922
+ [ngModel]="row[col.key]"
14923
+ (ngModelChange)="editDraft.set($event)"
14924
+ (keydown.enter)="commitDraft(row, col, $event)"
14925
+ (keydown.escape)="cancelEdit($event)"
14926
+ (focusout)="commitOnLeave(row, col, $event)"
14927
+ (click)="$event.stopPropagation()"
14928
+ />
14929
+ }
14930
+ @default {
14931
+ <input
14932
+ class="strct-dg__editinput"
14933
+ type="text"
14934
+ [value]="row[col.key] ?? ''"
14935
+ [attr.aria-label]="L().editCell + ': ' + col.label"
14936
+ (keydown.enter)="commitEdit(row, col, $event)"
14937
+ (keydown.escape)="cancelEdit($event)"
14938
+ (blur)="commitEdit(row, col, $event)"
14939
+ (click)="$event.stopPropagation()"
14940
+ />
14941
+ }
14942
+ }
14943
+ } @else if (cellTemplate(col.key); as tpl) {
14944
+ <ng-container
14264
14945
  [ngTemplateOutlet]="tpl"
14265
14946
  [ngTemplateOutletContext]="{
14266
14947
  $implicit: row,
@@ -14270,7 +14951,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
14270
14951
  }"
14271
14952
  />
14272
14953
  } @else {
14273
- {{ row[col.key] }}
14954
+ {{ displayValue(row, col) }}
14274
14955
  }
14275
14956
  </td>
14276
14957
  }
@@ -14411,7 +15092,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
14411
15092
  '[class.strct-dg-host--singleline]': 'singleLine()',
14412
15093
  '[class.strct-dg-host--virtual]': 'virtual()',
14413
15094
  '[class.strct-dg-host--sticky]': 'stickyActive()',
14414
- }, styles: [".strct-dg__radio{width:15px;height:15px;accent-color:var(--acc);cursor:pointer}.strct-dg__radio:disabled{cursor:not-allowed}.strct-dg__row--locked .strct-dg__sel{opacity:.55}.strct-dg__actioncaption:empty{display:none}.strct-dg__actioncaption{display:inline-flex;align-items:center;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-sm);color:var(--t3)}.strct-dg-host{display:block;border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-2);box-shadow:var(--shadow-rest)}.strct-dg__scroll{flex:1 1 auto;min-width:0;overflow-x:auto;-webkit-overflow-scrolling:touch}.strct-dg-host--virtual .strct-dg__scroll{overflow-y:auto}.strct-dg-host--virtual .strct-dg thead th{position:sticky;top:0;z-index:var(--z-raised)}.strct-dg__vspacer td{padding:0;border:0;background:transparent}.strct-dg th[draggable]{cursor:grab}.strct-dg__th--drop{box-shadow:inset 3px 0 0 var(--acc)}.strct-dg__grouprow td{background:var(--bg-2)!important;padding:0}.strct-dg__groupbtn{display:flex;align-items:center;gap:8px;width:100%;padding:7px 13px;border:0;background:transparent;color:var(--t1);font-family:var(--font);font-size:12.5px;font-weight:600;cursor:pointer;text-align:start}.strct-dg__groupbtn:hover{background:var(--bg-3)}.strct-dg__groupbtn:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__groupchev{display:inline-flex;color:var(--t3);transition:transform .15s ease}.strct-dg__groupchev--open{transform:rotate(90deg)}@media(prefers-reduced-motion:reduce){.strct-dg__groupchev{transition:none}}.strct-dg__groupcount{min-width:18px;height:18px;padding:0 5px;display:inline-flex;align-items:center;justify-content:center;font-size:12px;border-radius:9px;background:var(--acc-m);color:var(--acc);font-variant-numeric:tabular-nums}.strct-dg-host--sticky .strct-dg,.strct-dg-host--virtual .strct-dg{border-collapse:separate;border-spacing:0;overflow:visible;border-radius:0}.strct-dg-host--sticky .strct-dg{width:max-content;min-width:100%}.strct-dg .strct-dg__cell--sticky{position:sticky;z-index:calc(var(--z-base) + 2)}.strct-dg thead th.strct-dg__cell--sticky{z-index:calc(var(--z-raised) + 1)}.strct-dg .strct-dg__cell--sticky-last:after{content:\"\";position:absolute;top:0;bottom:0;inset-inline-end:-1px;width:7px;pointer-events:none;background:linear-gradient(to right,rgba(0,0,0,.14),transparent)}[dir=rtl] .strct-dg .strct-dg__cell--sticky-last:after{background:linear-gradient(to left,rgba(0,0,0,.14),transparent)}.strct-dg-host--sticky .strct-dg__expandcol,.strct-dg-host--sticky .strct-dg__expandcell{width:36px;min-width:36px;max-width:36px;box-sizing:border-box}.strct-dg-host--sticky .strct-dg__sel{width:40px;min-width:40px;max-width:40px;box-sizing:border-box}.strct-dg-host--sticky tbody .strct-dg__cell--sticky{background:var(--bg-1)}[data-theme=dark] .strct-dg-host--sticky tbody .strct-dg__cell--sticky{background:var(--bg-3)}.strct-dg-host--sticky tbody tr:hover .strct-dg__cell--sticky{background:linear-gradient(var(--acc-s),var(--acc-s)) var(--bg-1)}[data-theme=dark] .strct-dg-host--sticky tbody tr:hover .strct-dg__cell--sticky{background:linear-gradient(var(--acc-s),var(--acc-s)) var(--bg-3)}.strct-dg-host--sticky tbody .strct-dg__row--selected .strct-dg__cell--sticky{background:linear-gradient(var(--acc-m),var(--acc-m)) var(--bg-1)}[data-theme=dark] .strct-dg-host--sticky tbody .strct-dg__row--selected .strct-dg__cell--sticky{background:linear-gradient(var(--acc-m),var(--acc-m)) var(--bg-3)}.strct-dg{width:100%;border-collapse:collapse;font-size:13px;overflow:hidden;background:var(--bg-2)}.strct-dg-host:not(:has(.strct-dg__toolbar)) .strct-dg{border-start-start-radius:9px;border-start-end-radius:9px}.strct-dg-host:not(:has(.strct-dg__foot)) .strct-dg{border-end-start-radius:9px;border-end-end-radius:9px}.strct-dg th,.strct-dg td{padding:9px 13px;text-align:start;border-bottom:1px solid var(--b1)}.strct-dg tbody td{background:var(--bg-1)}[data-theme=dark] .strct-dg tbody td{background:var(--bg-3)}.strct-dg-host--compact .strct-dg th,.strct-dg-host--compact .strct-dg td{padding:5px 11px}.strct-dg-host--singleline .strct-dg tbody tr:not(.strct-dg__detailrow)>td{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:360px}.strct-dg th{position:relative;font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--t2);background:var(--bg-2);white-space:nowrap;-webkit-user-select:none;user-select:none}.strct-dg__th--sortable{cursor:pointer}.strct-dg__th--sortable:hover{color:var(--t1)}.strct-dg__th--sortable:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__hd{display:inline-flex;align-items:center;gap:5px}.strct-dg__sorticon{color:var(--t3)}.strct-dg__th--sortable:hover .strct-dg__sorticon{color:var(--acc)}.strct-dg__resize{position:absolute;inset-inline-end:0;top:0;bottom:0;width:4px;cursor:col-resize;background:transparent;z-index:calc(var(--z-base) + 1)}.strct-dg__resize:hover{background:var(--acc)}.strct-dg td{color:var(--t1)}.strct-dg tbody tr:last-child td{border-bottom:0}.strct-dg tbody tr:not(.strct-dg__detailrow):hover td{background:var(--acc-s)}.strct-dg__row--selected td{background:var(--acc-m)}.strct-dg__sel{width:1%;white-space:nowrap}.strct-dg__sel input{accent-color:var(--acc);width:15px;height:15px;cursor:pointer}.strct-dg__expandcol,.strct-dg__expandcell{width:1%;white-space:nowrap}.strct-dg__actioncol,.strct-dg__actioncell{width:1%;white-space:nowrap;text-align:end}.strct-dg__kebab{display:inline-flex;padding:4px;border:0;border-radius:5px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-dg__kebab:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__expandbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:transform .15s ease,color .15s ease}.strct-dg__expandbtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__expandbtn--open{transform:rotate(90deg);color:var(--acc)}.strct-dg__detailbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-dg__detailbtn:hover{color:var(--acc);background:var(--bg-3)}.strct-dg__detailbtn--active{color:var(--acc);background:var(--acc-m)}.strct-dg__detailrow td{background:var(--bg-2);padding:0}.strct-dg__detail{padding:14px 16px;font-size:13px;color:var(--t2)}.strct-dg__layout{display:flex;align-items:flex-start;min-width:0}.strct-dg__layout--paned{gap:0}.strct-dg__layout--paned .strct-dg__scroll{flex:0 0 auto;width:260px;min-width:260px;max-width:260px}.strct-dg__layout--paned .strct-dg{width:260px;min-width:260px;max-width:260px;flex-shrink:0;border-start-end-radius:0;border-end-end-radius:0}.strct-dg__row--clickable{cursor:pointer}.strct-dg__row--active td{background:var(--acc-m)}.strct-dg__layout--paned .strct-dg__row--active td:last-child{position:relative;padding-inline-end:26px}.strct-dg__layout--paned .strct-dg__row--active td:last-child:after{content:\"\";position:absolute;inset-inline-end:11px;top:50%;width:6px;height:6px;border-top:1.6px solid var(--acc);border-inline-end:1.6px solid var(--acc);transform:translateY(-50%) rotate(45deg)}.strct-dg__pane{flex:1;min-width:0;align-self:stretch;background:var(--bg-1);border:1px solid var(--b2);border-inline-start:2px solid var(--acc);border-radius:8px;border-start-start-radius:0;border-end-start-radius:0;overflow:hidden;animation:strct-dg-pane-in .14s ease}.strct-dg__pane-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:11px 14px;border-bottom:1px solid var(--b1);font-size:13px;font-weight:600;color:var(--t1)}.strct-dg__pane-close{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer}.strct-dg__pane-close:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__pane-body{padding:14px 16px;font-size:13px;color:var(--t2)}@keyframes strct-dg-pane-in{0%{opacity:0;transform:translate(8px)}}@keyframes strct-skeleton-pulse{0%,to{opacity:.4}50%{opacity:.7}}.strct-dg__skeleton-block{height:12px;border-radius:var(--radius-sm);background:linear-gradient(90deg,var(--bg-3) 25%,var(--skeleton-hi, var(--acc18)) 50%,var(--bg-3) 75%);background-size:200% 100%;animation:strct-dg-skeleton-sweep 1.1s linear infinite}@keyframes strct-dg-skeleton-sweep{0%{background-position:100% 0}to{background-position:-100% 0}}@media(prefers-reduced-motion:reduce){.strct-dg__skeleton-block{animation:none;background:var(--skeleton-hi, var(--acc18))}}.strct-dg__skeleton-row td{border-bottom:1px solid var(--b1)}.strct-dg__empty{text-align:center;color:var(--t3);padding:22px}.strct-dg__quickfilter{min-width:180px;max-width:260px}.strct-dg__quickfilter--end{order:2;margin-inline-start:auto}.strct-dg__filternote--end{order:3}.strct-dg__filternote{font-size:11.5px;color:var(--t3);font-variant-numeric:tabular-nums;white-space:nowrap}.strct-dg__toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:9px 14px;border-bottom:1px solid var(--b2)}.strct-dg__foot{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 14px;border-top:1px solid var(--b2);flex-wrap:wrap}.strct-dg__foot-left,.strct-dg__foot-right{display:flex;align-items:center;gap:12px}.strct-dg__actions{position:relative}.strct-dg__chooser-menu{position:absolute;bottom:calc(100% + 6px);inset-inline-start:0;z-index:var(--z-sticky);min-width:180px;background:var(--bg-1);border:1px solid var(--b2);border-radius:8px;box-shadow:var(--shadow-pop);padding:6px;display:flex;flex-direction:column;gap:2px}.strct-dg__chooser-menu--right{inset-inline-start:auto;inset-inline-end:0}.strct-dg__chooser-item{display:flex;align-items:center;gap:8px;padding:5px 8px;border-radius:6px;cursor:pointer;font-size:12px;color:var(--t1);transition:background .1s ease;-webkit-user-select:none;user-select:none}.strct-dg__chooser-item:hover{background:var(--bg-3)}.strct-dg__count{font-size:12px;color:var(--t2)}.strct-dg__count-sep{margin:0 8px;color:var(--b2)}.strct-dg__count-sel{color:var(--acc)}.strct-dg__filterbtn{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin-inline-start:2px;padding:0;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;vertical-align:middle}.strct-dg__filterbtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__filterbtn--active{color:var(--acc)}.strct-dg__filterbtn:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}.strct-dg__filterpanel{position:absolute;z-index:calc(var(--z-dropdown) + 10);display:flex;flex-direction:column;gap:6px;min-width:180px;padding:10px;background:var(--bg-1);border:1px solid var(--b2);border-radius:7px;box-shadow:var(--shh);font-weight:400;text-transform:none;letter-spacing:normal;white-space:nowrap}.strct-dg__filterinput{padding:5px 8px;border:1px solid var(--b2);border-radius:var(--radius-sm);background:var(--bg-2);color:var(--t1);font-family:var(--font);font-size:12px}.strct-dg__filterinput:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}.strct-dg__filteropt{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--t1);cursor:pointer}.strct-dg__filterclear{align-self:flex-start;padding:3px 8px;border:1px solid var(--b2);border-radius:var(--radius-sm);background:transparent;color:var(--t2);font-family:var(--font);font-size:11.5px;cursor:pointer}.strct-dg__filterclear:hover:not(:disabled){color:var(--t1);background:var(--bg-3)}.strct-dg__filterclear:disabled{color:var(--t4);cursor:default}.strct-dg tbody tr[tabindex]:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__treepad{display:inline-block;height:1px;vertical-align:middle}.strct-dg__treebtn{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;margin-inline-end:4px;padding:0;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;vertical-align:middle}.strct-dg__treebtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__treebtn:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}.strct-dg__treebtn strct-icon{transition:transform .15s ease}.strct-dg__treebtn--open strct-icon{transform:rotate(90deg)}.strct-dg__treebtn--leaf{cursor:default;pointer-events:none}@media(prefers-reduced-motion:reduce){.strct-dg__treebtn strct-icon{transition:none}}.strct-dg__cell--editable{cursor:text}.strct-dg__cell--editable:hover{box-shadow:inset 0 0 0 1px var(--b2)}.strct-dg__editinput{width:100%;box-sizing:border-box;padding:3px 6px;border:1px solid var(--acc);border-radius:var(--radius-sm);background:var(--bg-1);color:var(--t1);font:inherit}.strct-dg__editinput:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}\n"] }]
15095
+ }, styles: [".strct-dg__radio{width:15px;height:15px;accent-color:var(--acc);cursor:pointer}.strct-dg__radio:disabled{cursor:not-allowed}.strct-dg__row--locked .strct-dg__sel{opacity:.55}.strct-dg__actioncaption:empty{display:none}.strct-dg__actioncaption{display:inline-flex;align-items:center;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-sm);color:var(--t3)}.strct-dg-host{display:block;border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-2);box-shadow:var(--shadow-rest)}.strct-dg__scroll{flex:1 1 auto;min-width:0;overflow-x:auto;-webkit-overflow-scrolling:touch}.strct-dg-host--virtual .strct-dg__scroll{overflow-y:auto}.strct-dg-host--virtual .strct-dg thead th{position:sticky;top:0;z-index:var(--z-raised)}.strct-dg__vspacer td{padding:0;border:0;background:transparent}.strct-dg th[draggable]{cursor:grab}.strct-dg__th--drop{box-shadow:inset 3px 0 0 var(--acc)}.strct-dg__grouprow td{background:var(--bg-2)!important;padding:0}.strct-dg__groupbtn{display:flex;align-items:center;gap:8px;width:100%;padding:7px 13px;border:0;background:transparent;color:var(--t1);font-family:var(--font);font-size:12.5px;font-weight:600;cursor:pointer;text-align:start}.strct-dg__groupbtn:hover{background:var(--bg-3)}.strct-dg__groupbtn:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__groupchev{display:inline-flex;color:var(--t3);transition:transform .15s ease}.strct-dg__groupchev--open{transform:rotate(90deg)}@media(prefers-reduced-motion:reduce){.strct-dg__groupchev{transition:none}}.strct-dg__groupcount{min-width:18px;height:18px;padding:0 5px;display:inline-flex;align-items:center;justify-content:center;font-size:12px;border-radius:9px;background:var(--acc-m);color:var(--acc);font-variant-numeric:tabular-nums}.strct-dg-host--sticky .strct-dg,.strct-dg-host--virtual .strct-dg{border-collapse:separate;border-spacing:0;overflow:visible;border-radius:0}.strct-dg-host--sticky .strct-dg{width:max-content;min-width:100%}.strct-dg .strct-dg__cell--sticky{position:sticky;z-index:calc(var(--z-base) + 2)}.strct-dg thead th.strct-dg__cell--sticky{z-index:calc(var(--z-raised) + 1)}.strct-dg .strct-dg__cell--sticky-last:after{content:\"\";position:absolute;top:0;bottom:0;inset-inline-end:-1px;width:7px;pointer-events:none;background:linear-gradient(to right,rgba(0,0,0,.14),transparent)}[dir=rtl] .strct-dg .strct-dg__cell--sticky-last:after{background:linear-gradient(to left,rgba(0,0,0,.14),transparent)}.strct-dg-host--sticky .strct-dg__expandcol,.strct-dg-host--sticky .strct-dg__expandcell{width:36px;min-width:36px;max-width:36px;box-sizing:border-box}.strct-dg-host--sticky .strct-dg__sel{width:40px;min-width:40px;max-width:40px;box-sizing:border-box}.strct-dg-host--sticky tbody .strct-dg__cell--sticky{background:var(--bg-1)}[data-theme=dark] .strct-dg-host--sticky tbody .strct-dg__cell--sticky{background:var(--bg-3)}.strct-dg-host--sticky tbody tr:hover .strct-dg__cell--sticky{background:linear-gradient(var(--acc-s),var(--acc-s)) var(--bg-1)}[data-theme=dark] .strct-dg-host--sticky tbody tr:hover .strct-dg__cell--sticky{background:linear-gradient(var(--acc-s),var(--acc-s)) var(--bg-3)}.strct-dg-host--sticky tbody .strct-dg__row--selected .strct-dg__cell--sticky{background:linear-gradient(var(--acc-m),var(--acc-m)) var(--bg-1)}[data-theme=dark] .strct-dg-host--sticky tbody .strct-dg__row--selected .strct-dg__cell--sticky{background:linear-gradient(var(--acc-m),var(--acc-m)) var(--bg-3)}.strct-dg{width:100%;border-collapse:collapse;font-size:13px;overflow:hidden;background:var(--bg-2)}.strct-dg-host:not(:has(.strct-dg__toolbar)) .strct-dg{border-start-start-radius:9px;border-start-end-radius:9px}.strct-dg-host:not(:has(.strct-dg__foot)) .strct-dg{border-end-start-radius:9px;border-end-end-radius:9px}.strct-dg th,.strct-dg td{padding:9px 13px;text-align:start;border-bottom:1px solid var(--b1)}.strct-dg tbody td{background:var(--bg-1)}[data-theme=dark] .strct-dg tbody td{background:var(--bg-3)}.strct-dg-host--compact .strct-dg th,.strct-dg-host--compact .strct-dg td{padding:5px 11px}.strct-dg-host--singleline .strct-dg tbody tr:not(.strct-dg__detailrow)>td{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:360px}.strct-dg th{position:relative;font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--t2);background:var(--bg-2);white-space:nowrap;-webkit-user-select:none;user-select:none}.strct-dg__th--sortable{cursor:pointer}.strct-dg__th--sortable:hover{color:var(--t1)}.strct-dg__th--sortable:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__hd{display:inline-flex;align-items:center;gap:5px}.strct-dg__sorticon{color:var(--t3)}.strct-dg__th--sortable:hover .strct-dg__sorticon{color:var(--acc)}.strct-dg__resize{position:absolute;inset-inline-end:0;top:0;bottom:0;width:4px;cursor:col-resize;background:transparent;z-index:calc(var(--z-base) + 1)}.strct-dg__resize:hover{background:var(--acc)}.strct-dg td{color:var(--t1)}.strct-dg tbody tr:last-child td{border-bottom:0}.strct-dg tbody tr:not(.strct-dg__detailrow):hover td{background:var(--acc-s)}.strct-dg__row--selected td{background:var(--acc-m)}.strct-dg__sel{width:1%;white-space:nowrap}.strct-dg__sel input{accent-color:var(--acc);width:15px;height:15px;cursor:pointer}.strct-dg__expandcol,.strct-dg__expandcell{width:1%;white-space:nowrap}.strct-dg__actioncol,.strct-dg__actioncell{width:1%;white-space:nowrap;text-align:end}.strct-dg__kebab{display:inline-flex;padding:4px;border:0;border-radius:5px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-dg__kebab:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__expandbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:transform .15s ease,color .15s ease}.strct-dg__expandbtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__expandbtn--open{transform:rotate(90deg);color:var(--acc)}.strct-dg__detailbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-dg__detailbtn:hover{color:var(--acc);background:var(--bg-3)}.strct-dg__detailbtn--active{color:var(--acc);background:var(--acc-m)}.strct-dg__detailrow td{background:var(--bg-2);padding:0}.strct-dg__detail{padding:14px 16px;font-size:13px;color:var(--t2)}.strct-dg__layout{display:flex;align-items:flex-start;min-width:0}.strct-dg__layout--paned{gap:0}.strct-dg__layout--paned .strct-dg__scroll{flex:0 0 auto;width:260px;min-width:260px;max-width:260px}.strct-dg__layout--paned .strct-dg{width:260px;min-width:260px;max-width:260px;flex-shrink:0;border-start-end-radius:0;border-end-end-radius:0}.strct-dg__row--clickable{cursor:pointer}.strct-dg__row--active td{background:var(--acc-m)}.strct-dg__layout--paned .strct-dg__row--active td:last-child{position:relative;padding-inline-end:26px}.strct-dg__layout--paned .strct-dg__row--active td:last-child:after{content:\"\";position:absolute;inset-inline-end:11px;top:50%;width:6px;height:6px;border-top:1.6px solid var(--acc);border-inline-end:1.6px solid var(--acc);transform:translateY(-50%) rotate(45deg)}.strct-dg__pane{flex:1;min-width:0;align-self:stretch;background:var(--bg-1);border:1px solid var(--b2);border-inline-start:2px solid var(--acc);border-radius:8px;border-start-start-radius:0;border-end-start-radius:0;overflow:hidden;animation:strct-dg-pane-in .14s ease}.strct-dg__pane-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:11px 14px;border-bottom:1px solid var(--b1);font-size:13px;font-weight:600;color:var(--t1)}.strct-dg__pane-close{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer}.strct-dg__pane-close:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__pane-body{padding:14px 16px;font-size:13px;color:var(--t2)}@keyframes strct-dg-pane-in{0%{opacity:0;transform:translate(8px)}}@keyframes strct-skeleton-pulse{0%,to{opacity:.4}50%{opacity:.7}}.strct-dg__skeleton-block{height:12px;border-radius:var(--radius-sm);background:linear-gradient(90deg,var(--bg-3) 25%,var(--skeleton-hi, var(--acc18)) 50%,var(--bg-3) 75%);background-size:200% 100%;animation:strct-dg-skeleton-sweep 1.1s linear infinite}@keyframes strct-dg-skeleton-sweep{0%{background-position:100% 0}to{background-position:-100% 0}}@media(prefers-reduced-motion:reduce){.strct-dg__skeleton-block{animation:none;background:var(--skeleton-hi, var(--acc18))}}.strct-dg__skeleton-row td{border-bottom:1px solid var(--b1)}.strct-dg__empty{text-align:center;color:var(--t3);padding:22px}.strct-dg__quickfilter{min-width:180px;max-width:260px}.strct-dg__quickfilter--end{order:2;margin-inline-start:auto}.strct-dg__filternote--end{order:3}.strct-dg__filternote{font-size:11.5px;color:var(--t3);font-variant-numeric:tabular-nums;white-space:nowrap}.strct-dg__toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:9px 14px;border-bottom:1px solid var(--b2)}.strct-dg__foot{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 14px;border-top:1px solid var(--b2);flex-wrap:wrap}.strct-dg__foot-left,.strct-dg__foot-right{display:flex;align-items:center;gap:12px}.strct-dg__actions{position:relative}.strct-dg__chooser-menu{position:absolute;bottom:calc(100% + 6px);inset-inline-start:0;z-index:var(--z-sticky);min-width:180px;background:var(--bg-1);border:1px solid var(--b2);border-radius:8px;box-shadow:var(--shadow-pop);padding:6px;display:flex;flex-direction:column;gap:2px}.strct-dg__chooser-menu--right{inset-inline-start:auto;inset-inline-end:0}.strct-dg__chooser-item{display:flex;align-items:center;gap:8px;padding:5px 8px;border-radius:6px;cursor:pointer;font-size:12px;color:var(--t1);transition:background .1s ease;-webkit-user-select:none;user-select:none}.strct-dg__chooser-item:hover{background:var(--bg-3)}.strct-dg__count{font-size:12px;color:var(--t2)}.strct-dg__count-sep{margin:0 8px;color:var(--b2)}.strct-dg__count-sel{color:var(--acc)}.strct-dg__filterbtn{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin-inline-start:2px;padding:0;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;vertical-align:middle}.strct-dg__filterbtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__filterbtn--active{color:var(--acc)}.strct-dg__filterbtn:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}.strct-dg__filterpanel{position:absolute;z-index:calc(var(--z-dropdown) + 10);display:flex;flex-direction:column;gap:6px;min-width:180px;padding:10px;background:var(--bg-1);border:1px solid var(--b2);border-radius:7px;box-shadow:var(--shh);font-weight:400;text-transform:none;letter-spacing:normal;white-space:nowrap}.strct-dg__filterinput{padding:5px 8px;border:1px solid var(--b2);border-radius:var(--radius-sm);background:var(--bg-2);color:var(--t1);font-family:var(--font);font-size:12px}.strct-dg__filterinput:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}.strct-dg__filteropt{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--t1);cursor:pointer}.strct-dg__filterclear{align-self:flex-start;padding:3px 8px;border:1px solid var(--b2);border-radius:var(--radius-sm);background:transparent;color:var(--t2);font-family:var(--font);font-size:11.5px;cursor:pointer}.strct-dg__filterclear:hover:not(:disabled){color:var(--t1);background:var(--bg-3)}.strct-dg__filterclear:disabled{color:var(--t4);cursor:default}.strct-dg tbody tr[tabindex]:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__treepad{display:inline-block;height:1px;vertical-align:middle}.strct-dg__treebtn{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;margin-inline-end:4px;padding:0;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;vertical-align:middle}.strct-dg__treebtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__treebtn:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}.strct-dg__treebtn strct-icon{transition:transform .15s ease}.strct-dg__treebtn--open strct-icon{transform:rotate(90deg)}.strct-dg__treebtn--leaf{cursor:default;pointer-events:none}@media(prefers-reduced-motion:reduce){.strct-dg__treebtn strct-icon{transition:none}}.strct-dg__cell--editable{cursor:text}.strct-dg__cell--editable:hover{box-shadow:inset 0 0 0 1px var(--b2)}.strct-dg__editinput{width:100%;box-sizing:border-box;padding:3px 6px;border:1px solid var(--acc);border-radius:var(--radius-sm);background:var(--bg-1);color:var(--t1);font:inherit}.strct-dg__editselect,.strct-dg__editnumber{display:block;width:100%}.strct-dg__editinput:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}\n"] }]
14415
15096
  }], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], expandable: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandable", required: false }] }], detailPane: [{ type: i0.Input, args: [{ isSignal: true, alias: "detailPane", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], singleLine: [{ type: i0.Input, args: [{ isSignal: true, alias: "singleLine", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }], columnChooser: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnChooser", required: false }] }], sync: [{ type: i0.Input, args: [{ isSignal: true, alias: "sync", required: false }] }], footerActionsDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerActionsDisabled", required: false }] }], rowId: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowId", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], selectedId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedId", required: false }] }, { type: i0.Output, args: ["selectedIdChange"] }], rowSelectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowSelectable", required: false }] }], groupSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupSelect", required: false }] }], rowActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowActions", required: false }] }], initialSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialSelection", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], virtual: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtual", required: false }] }], viewportHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewportHeight", required: false }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: false }] }], lazy: [{ type: i0.Input, args: [{ isSignal: true, alias: "lazy", required: false }] }], total: [{ type: i0.Input, args: [{ isSignal: true, alias: "total", required: false }] }], stateKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "stateKey", required: false }] }], columnState: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnState", required: false }] }, { type: i0.Output, args: ["columnStateChange"] }], reorderable: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderable", required: false }] }], groupBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupBy", required: false }] }], filters: [{ type: i0.Input, args: [{ isSignal: true, alias: "filters", required: false }] }, { type: i0.Output, args: ["filtersChange"] }], quickFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickFilter", required: false }] }, { type: i0.Output, args: ["quickFilterChange"] }], quickFilterFields: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickFilterFields", required: false }] }], quickFilterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickFilterable", required: false }] }], quickFilterAlign: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickFilterAlign", required: false }] }], childrenKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "childrenKey", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], syncChange: [{ type: i0.Output, args: ["syncChange"] }], rowAction: [{ type: i0.Output, args: ["rowAction"] }], lazyLoad: [{ type: i0.Output, args: ["lazyLoad"] }], cellEdit: [{ type: i0.Output, args: ["cellEdit"] }], detailDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctRowDetailDef), { isSignal: true }] }], actionBarDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctDatagridActionBar), { isSignal: true }] }], cellDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrctCellDef), { isSignal: true }] }], onDocClickOverlays: [{
14416
15097
  type: HostListener,
14417
15098
  args: ['document:click', ['$event']]
@@ -19473,7 +20154,7 @@ class StrctTransfer {
19473
20154
  }
19474
20155
  </ul>
19475
20156
  </div>
19476
- `, isInline: true, styles: [".strct-tf{display:flex;align-items:stretch;gap:10px;width:100%}.strct-tf__col{flex:1 1 0;min-width:0;display:flex;flex-direction:column;gap:8px;padding:10px;background:var(--bg-2);border:1px solid var(--b2);border-radius:9px}.strct-tf__head{display:flex;align-items:baseline;gap:8px}.strct-tf__title{font-size:12.5px;font-weight:600;color:var(--t1)}.strct-tf__count{font-size:11px;color:var(--t3);font-variant-numeric:tabular-nums}.strct-tf__search{width:100%}.strct-tf__list{list-style:none;margin:0;padding:0;min-height:120px;max-height:240px;overflow:auto;display:flex;flex-direction:column;gap:1px}.strct-tf__item{display:flex;align-items:center;padding:2px 4px;border-radius:5px;color:var(--t1);font-size:12.5px}.strct-tf__item strct-icon{margin-inline-end:6px}.strct-tf__item:hover{background:var(--bg-3)}.strct-tf__item--disabled{color:var(--t4);cursor:default}.strct-tf__label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.strct-tf__empty{padding:12px 8px;font-size:12px;color:var(--t3)}.strct-tf__mid{display:flex;flex-direction:column;justify-content:center;gap:8px}[dir=rtl] .strct-tf__mid strct-icon{transform:rotate(180deg)}\n"], dependencies: [{ kind: "component", type: StrctButton, selector: "button[strct-button], a[strct-button]", inputs: ["variant", "size", "solid", "block", "iconOnly"] }, { kind: "component", type: StrctCheckbox, selector: "strct-checkbox", inputs: ["checked", "disabled", "indeterminate", "ariaLabel"], outputs: ["checkedChange"] }, { kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel"] }, { kind: "component", type: StrctSearchbox, selector: "strct-searchbox", inputs: ["placeholder", "hint", "trigger", "clearable", "ariaLabel", "clearLabel", "value"], outputs: ["valueChange", "search", "activated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
20157
+ `, isInline: true, styles: [".strct-tf{display:flex;align-items:stretch;gap:10px;width:100%}.strct-tf__col{flex:1 1 0;min-width:0;display:flex;flex-direction:column;gap:8px;padding:10px;background:var(--bg-2);border:1px solid var(--b2);border-radius:9px}.strct-tf__head{display:flex;align-items:baseline;gap:8px}.strct-tf__title{font-size:12.5px;font-weight:600;color:var(--t1)}.strct-tf__count{font-size:11px;color:var(--t3);font-variant-numeric:tabular-nums}.strct-tf__search{width:100%}.strct-tf__list{list-style:none;margin:0;padding:0;min-height:120px;max-height:240px;overflow:auto;display:flex;flex-direction:column;gap:1px}.strct-tf__item{display:flex;align-items:center;padding:2px 4px;border-radius:5px;color:var(--t1);font-size:12.5px}.strct-tf__item strct-icon{margin-inline-end:6px}.strct-tf__item:hover{background:var(--bg-3)}.strct-tf__item--disabled{color:var(--t4);cursor:default}.strct-tf__label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.strct-tf__empty{padding:12px 8px;font-size:12px;color:var(--t3)}.strct-tf__mid{display:flex;flex-direction:column;justify-content:center;gap:8px}[dir=rtl] .strct-tf__mid strct-icon{transform:rotate(180deg)}\n"], dependencies: [{ kind: "component", type: StrctButton, selector: "button[strct-button], a[strct-button]", inputs: ["variant", "size", "solid", "block", "iconOnly"] }, { kind: "component", type: StrctCheckbox, selector: "strct-checkbox", inputs: ["checked", "disabled", "indeterminate", "ariaLabel", "description"], outputs: ["checkedChange"] }, { kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel"] }, { kind: "component", type: StrctSearchbox, selector: "strct-searchbox", inputs: ["placeholder", "hint", "trigger", "clearable", "ariaLabel", "clearLabel", "value"], outputs: ["valueChange", "search", "activated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
19477
20158
  }
19478
20159
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctTransfer, decorators: [{
19479
20160
  type: Component,
@@ -20974,280 +21655,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
20974
21655
  }, styles: [".strct-dot{display:inline-flex;align-items:center;flex:none;line-height:0}.strct-dot__dot{width:10px;height:10px;border-radius:50%;background:var(--t3)}.strct-dot--sm .strct-dot__dot{width:8px;height:8px}.strct-dot--accent .strct-dot__dot{background:var(--acc)}.strct-dot--success .strct-dot__dot{background:var(--success)}.strct-dot--warning .strct-dot__dot{background:var(--warning)}.strct-dot--critical .strct-dot__dot{background:var(--critical)}.strct-dot__sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}\n"] }]
20975
21656
  }], propDecorators: { status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
20976
21657
 
20977
- /**
20978
- * Numeric stepper input: − / + buttons flanking a text field. The value is
20979
- * `number | null` (null = empty); typing is free-form (intermediate states
20980
- * like "-" are kept), committed values clamp to `min`/`max` on blur, and the
20981
- * buttons + keyboard always clamp immediately.
20982
- *
20983
- * <strct-number [min]="0" [max]="64" [step]="4" [(ngModel)]="vcpus" />
20984
- *
20985
- * Keyboard on the field: ArrowUp/Down ±step, PageUp/Down ±10×step,
20986
- * Home/End jump to min/max. The field exposes `role="spinbutton"` with
20987
- * aria-valuemin/max/now so assistive tech announces it as a number control.
20988
- */
20989
- class StrctNumber {
20990
- /** Minimum allowed value; null = unbounded. */
20991
- min = input(null, /* @ts-ignore */
20992
- ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
20993
- /** Maximum allowed value; null = unbounded. */
20994
- max = input(null, /* @ts-ignore */
20995
- ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
20996
- /** Step increment for buttons and Arrow keys (PageUp/Down use 10×). */
20997
- step = input(1, /* @ts-ignore */
20998
- ...(ngDevMode ? [{ debugName: "step" }] : /* istanbul ignore next */ []));
20999
- /** Placeholder text when empty. */
21000
- placeholder = input('', /* @ts-ignore */
21001
- ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
21002
- /** Accessible label of the + button (localizable). */
21003
- incrementLabel = input('Increment', /* @ts-ignore */
21004
- ...(ngDevMode ? [{ debugName: "incrementLabel" }] : /* istanbul ignore next */ []));
21005
- /** Accessible label of the − button (localizable). */
21006
- decrementLabel = input('Decrement', /* @ts-ignore */
21007
- ...(ngDevMode ? [{ debugName: "decrementLabel" }] : /* istanbul ignore next */ []));
21008
- /** Static disable; forms' setDisabledState also drives the disabled state. */
21009
- disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
21010
- value = signal(null, /* @ts-ignore */
21011
- ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
21012
- /** Raw field text — may hold an unparseable intermediate state while typing. */
21013
- text = signal('', /* @ts-ignore */
21014
- ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
21015
- /** Disabled state pushed by the forms API (setDisabledState). */
21016
- cvaDisabled = signal(false, /* @ts-ignore */
21017
- ...(ngDevMode ? [{ debugName: "cvaDisabled" }] : /* istanbul ignore next */ []));
21018
- isDisabled = computed(() => this.disabled() || this.cvaDisabled(), /* @ts-ignore */
21019
- ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
21020
- /** At/below min (or min unset → never) — greys out the − button. */
21021
- atMin = computed(() => {
21022
- const v = this.value();
21023
- const m = this.min();
21024
- return v !== null && m !== null && v <= m;
21025
- }, /* @ts-ignore */
21026
- ...(ngDevMode ? [{ debugName: "atMin" }] : /* istanbul ignore next */ []));
21027
- /** At/above max (or max unset → never) — greys out the + button. */
21028
- atMax = computed(() => {
21029
- const v = this.value();
21030
- const m = this.max();
21031
- return v !== null && m !== null && v >= m;
21032
- }, /* @ts-ignore */
21033
- ...(ngDevMode ? [{ debugName: "atMax" }] : /* istanbul ignore next */ []));
21034
- onChange = () => { };
21035
- onTouched = () => { };
21036
- onInput(event) {
21037
- const raw = event.target.value;
21038
- this.text.set(raw);
21039
- const trimmed = raw.trim();
21040
- if (trimmed === '') {
21041
- this.value.set(null);
21042
- this.onChange(null);
21043
- return;
21044
- }
21045
- const parsed = Number(trimmed);
21046
- // Intermediate states ("-", "1.", "2e") don't parse yet — keep the text,
21047
- // hold the last value; clamping happens on blur.
21048
- if (Number.isFinite(parsed)) {
21049
- this.value.set(parsed);
21050
- this.onChange(parsed);
21051
- }
21052
- }
21053
- onKeydown(event) {
21054
- if (this.isDisabled())
21055
- return;
21056
- switch (event.key) {
21057
- case 'ArrowUp':
21058
- event.preventDefault();
21059
- this.stepBy(1);
21060
- break;
21061
- case 'ArrowDown':
21062
- event.preventDefault();
21063
- this.stepBy(-1);
21064
- break;
21065
- case 'PageUp':
21066
- event.preventDefault();
21067
- this.stepBy(1, 10);
21068
- break;
21069
- case 'PageDown':
21070
- event.preventDefault();
21071
- this.stepBy(-1, 10);
21072
- break;
21073
- case 'Home': {
21074
- const m = this.min();
21075
- if (m === null)
21076
- return;
21077
- event.preventDefault();
21078
- this.commitTo(m);
21079
- break;
21080
- }
21081
- case 'End': {
21082
- const m = this.max();
21083
- if (m === null)
21084
- return;
21085
- event.preventDefault();
21086
- this.commitTo(m);
21087
- break;
21088
- }
21089
- }
21090
- }
21091
- /** Commit the pending text on blur: parse, clamp, restore on garbage. */
21092
- onBlur() {
21093
- const trimmed = this.text().trim();
21094
- if (trimmed === '') {
21095
- if (this.value() !== null) {
21096
- this.value.set(null);
21097
- this.onChange(null);
21098
- }
21099
- this.text.set('');
21100
- }
21101
- else {
21102
- const parsed = Number(trimmed);
21103
- if (Number.isFinite(parsed)) {
21104
- const clamped = this.clamp(parsed);
21105
- this.value.set(clamped);
21106
- if (clamped !== parsed)
21107
- this.onChange(clamped);
21108
- this.text.set(String(clamped));
21109
- }
21110
- else {
21111
- // Unparseable — restore the last committed value.
21112
- this.text.set(this.value() === null ? '' : String(this.value()));
21113
- }
21114
- }
21115
- this.onTouched();
21116
- }
21117
- /** Button / keyboard step: an empty field first lands on min (or 0). */
21118
- stepBy(dir, factor = 1) {
21119
- if (this.isDisabled())
21120
- return;
21121
- const v = this.value();
21122
- if (v === null) {
21123
- this.commitTo(this.min() ?? 0);
21124
- return;
21125
- }
21126
- this.commitTo(v + dir * factor * this.step());
21127
- }
21128
- commitTo(n) {
21129
- const clamped = this.clamp(this.snap(n));
21130
- this.value.set(clamped);
21131
- this.text.set(String(clamped));
21132
- this.onChange(clamped);
21133
- this.onTouched();
21134
- }
21135
- clamp(n) {
21136
- const lo = this.min();
21137
- const hi = this.max();
21138
- if (lo !== null && n < lo)
21139
- return lo;
21140
- if (hi !== null && n > hi)
21141
- return hi;
21142
- return n;
21143
- }
21144
- /** Trim float dust from step arithmetic (0.1 + 0.2), not a grid snap. */
21145
- snap(n) {
21146
- const step = this.step();
21147
- if (!Number.isFinite(step) || step <= 0)
21148
- return n;
21149
- const decimals = (String(step).split('.')[1] ?? '').length;
21150
- return Number(n.toFixed(Math.min(decimals + 2, 12)));
21151
- }
21152
- writeValue(value) {
21153
- const parsed = value === null || value === undefined ? null : Number(value);
21154
- const v = parsed !== null && Number.isFinite(parsed) ? this.clamp(parsed) : null;
21155
- this.value.set(v);
21156
- this.text.set(v === null ? '' : String(v));
21157
- }
21158
- registerOnChange(fn) {
21159
- this.onChange = fn;
21160
- }
21161
- registerOnTouched(fn) {
21162
- this.onTouched = fn;
21163
- }
21164
- setDisabledState(isDisabled) {
21165
- this.cvaDisabled.set(isDisabled);
21166
- }
21167
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctNumber, deps: [], target: i0.ɵɵFactoryTarget.Component });
21168
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: StrctNumber, isStandalone: true, selector: "strct-number", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, incrementLabel: { classPropertyName: "incrementLabel", publicName: "incrementLabel", isSignal: true, isRequired: false, transformFunction: null }, decrementLabel: { classPropertyName: "decrementLabel", publicName: "decrementLabel", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "strct-num" }, providers: [
21169
- { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => StrctNumber), multi: true },
21170
- ], ngImport: i0, template: `
21171
- <div class="strct-num__wrap">
21172
- <button
21173
- type="button"
21174
- class="strct-num__btn"
21175
- [attr.aria-label]="decrementLabel()"
21176
- [disabled]="isDisabled() || atMin()"
21177
- (click)="stepBy(-1)"
21178
- >
21179
- <strct-icon strictName="minus" [size]="12" [strokeWidth]="1.8" />
21180
- </button>
21181
- <input
21182
- type="text"
21183
- inputmode="decimal"
21184
- class="strct-control strct-num__input"
21185
- role="spinbutton"
21186
- [attr.aria-valuemin]="min()"
21187
- [attr.aria-valuemax]="max()"
21188
- [attr.aria-valuenow]="value()"
21189
- [placeholder]="placeholder()"
21190
- [value]="text()"
21191
- [disabled]="isDisabled()"
21192
- (input)="onInput($event)"
21193
- (keydown)="onKeydown($event)"
21194
- (blur)="onBlur()"
21195
- />
21196
- <button
21197
- type="button"
21198
- class="strct-num__btn"
21199
- [attr.aria-label]="incrementLabel()"
21200
- [disabled]="isDisabled() || atMax()"
21201
- (click)="stepBy(1)"
21202
- >
21203
- <strct-icon strictName="plus" [size]="12" [strokeWidth]="1.8" />
21204
- </button>
21205
- </div>
21206
- `, isInline: true, styles: [".strct-num{display:block;width:100%}.strct-num__wrap{display:flex;align-items:stretch;gap:var(--space-1)}.strct-num__input{flex:1;min-width:0;text-align:center;font-variant-numeric:tabular-nums}.strct-num__btn{display:inline-flex;align-items:center;justify-content:center;flex:none;padding-inline:var(--space-2);color:var(--t2);background:var(--bg-2);border:1px solid var(--b2);border-radius:var(--radius-md);cursor:pointer;transition:border-color .14s ease,color .14s ease,background .14s ease}.strct-num__btn:hover:not(:disabled){color:var(--t1);border-color:var(--b3);background:var(--bg-3)}.strct-num__btn:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
21207
- }
21208
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctNumber, decorators: [{
21209
- type: Component,
21210
- args: [{ selector: 'strct-number', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctIcon], providers: [
21211
- { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => StrctNumber), multi: true },
21212
- ], template: `
21213
- <div class="strct-num__wrap">
21214
- <button
21215
- type="button"
21216
- class="strct-num__btn"
21217
- [attr.aria-label]="decrementLabel()"
21218
- [disabled]="isDisabled() || atMin()"
21219
- (click)="stepBy(-1)"
21220
- >
21221
- <strct-icon strictName="minus" [size]="12" [strokeWidth]="1.8" />
21222
- </button>
21223
- <input
21224
- type="text"
21225
- inputmode="decimal"
21226
- class="strct-control strct-num__input"
21227
- role="spinbutton"
21228
- [attr.aria-valuemin]="min()"
21229
- [attr.aria-valuemax]="max()"
21230
- [attr.aria-valuenow]="value()"
21231
- [placeholder]="placeholder()"
21232
- [value]="text()"
21233
- [disabled]="isDisabled()"
21234
- (input)="onInput($event)"
21235
- (keydown)="onKeydown($event)"
21236
- (blur)="onBlur()"
21237
- />
21238
- <button
21239
- type="button"
21240
- class="strct-num__btn"
21241
- [attr.aria-label]="incrementLabel()"
21242
- [disabled]="isDisabled() || atMax()"
21243
- (click)="stepBy(1)"
21244
- >
21245
- <strct-icon strictName="plus" [size]="12" [strokeWidth]="1.8" />
21246
- </button>
21247
- </div>
21248
- `, host: { class: 'strct-num' }, styles: [".strct-num{display:block;width:100%}.strct-num__wrap{display:flex;align-items:stretch;gap:var(--space-1)}.strct-num__input{flex:1;min-width:0;text-align:center;font-variant-numeric:tabular-nums}.strct-num__btn{display:inline-flex;align-items:center;justify-content:center;flex:none;padding-inline:var(--space-2);color:var(--t2);background:var(--bg-2);border:1px solid var(--b2);border-radius:var(--radius-md);cursor:pointer;transition:border-color .14s ease,color .14s ease,background .14s ease}.strct-num__btn:hover:not(:disabled){color:var(--t1);border-color:var(--b3);background:var(--bg-3)}.strct-num__btn:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}\n"] }]
21249
- }], propDecorators: { min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], incrementLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "incrementLabel", required: false }] }], decrementLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "decrementLabel", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
21250
-
21251
21658
  /**
21252
21659
  * A generic anchored overlay panel for arbitrary projected content — the
21253
21660
  * public primitive behind menus, signposts and rich pickers:
@@ -23114,5 +23521,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
23114
23521
  * Generated bundle index. Do not edit.
23115
23522
  */
23116
23523
 
23117
- export { FOCUSABLE_SELECTOR, STRCT_DP_DOW, STRCT_DP_DOW_FULL, STRCT_DP_MONTHS, STRCT_ICONS, STRCT_ICON_GROUPS, STRCT_ICON_NAMES, STRCT_MASKS, STRCT_NOTIFICATION_HISTORY_LIMIT, STRCT_PALETTES, STRCT_RAW_ICONS, STRCT_TIME_RANGE_PRESETS, STRCT_WIZARD_DEFAULTS, StrctAccordion, StrctAccordionPanel, StrctAlert, StrctAnnouncer, StrctAvatar, StrctBadge, StrctBreadcrumb, StrctBreadcrumbItem, StrctButton, StrctButtonGroup, StrctBytesPipe, StrctCard, StrctCardBlock, StrctCardFooter, StrctCardHeader, StrctCardHeaderActions, StrctCardHeaderMeta, StrctCardHeaderNote, StrctCascadeColumn, StrctCascadeHost, StrctCascadeSelect, StrctCellDef, StrctCellStatus, StrctChart, StrctCheckbox, StrctChips, StrctCode, StrctCodeInline, StrctColorPicker, StrctCombobox, StrctCommandPalette, StrctConfirmOutlet, StrctConfirmService, StrctContextMenu, StrctContextMenuTrigger, StrctCopy, StrctDatagrid, StrctDatagridActionBar, StrctDatagridActionBarCaption, StrctDatepicker, StrctDatetimePicker, StrctDesc, StrctDescriptionList, StrctDiff, StrctDivider, StrctDonut, StrctDrawer, StrctDrawerFooter, StrctDropdown, StrctDropdownDivider, StrctDropdownItem, StrctDropdownTrigger, StrctDurationPipe, StrctEmptyState, StrctField, StrctFieldGroup, StrctFieldHint, StrctFieldPrefix, StrctFieldSuffix, StrctFile, StrctFilterBar, StrctFlow, StrctFooter, StrctGauge, StrctHeader, StrctHeatmap, StrctHero, StrctHotkeysHelp, StrctHotkeysService, StrctIcon, StrctInlineEdit, StrctInput, StrctInputMask, StrctInputOtp, StrctKbd, StrctKnob, StrctList, StrctListItem, StrctListItemDescription, StrctListItemLeading, StrctListItemMeta, StrctListItemTrailing, StrctLogViewer, StrctLogin, StrctMenuPanel, StrctMenuService, StrctMenubar, StrctMetricTile, StrctModal, StrctModalContent, StrctNav, StrctNavItem, StrctNotificationCenter, StrctNumber, StrctOverlay, StrctPageHeader, StrctPageHeaderActions, StrctPageHeaderCrumbs, StrctPageHeaderTitleMeta, StrctPagination, StrctPassword, StrctPopover, StrctPopoverTrigger, StrctProgress, StrctRadio, StrctRadioGroup, StrctRail, StrctRange, StrctRatePipe, StrctRating, StrctReorder, StrctReorderItem, StrctRowDetailDef, StrctSearchbox, StrctSectionHeader, StrctSectionHeaderActions, StrctSectionHeaderMeta, StrctSectionMenu, StrctSegmented, StrctSelect, StrctShell, StrctShellService, StrctSiPipe, StrctSignpost, StrctSignpostTrigger, StrctSkeleton, StrctSparkline, StrctSpeedDial, StrctSpinner, StrctSplitButton, StrctSplitter, StrctStack, StrctStackItem, StrctStatusDot, StrctStep, StrctSubmenu, StrctTab, StrctTable, StrctTabs, StrctTag, StrctThemeService, StrctThemeSwitcher, StrctTimeRangePicker, StrctTimeline, StrctTimelineItem, StrctToastOutlet, StrctToastService, StrctToggle, StrctToolbar, StrctToolbarCaption, StrctToolbarSpacer, StrctTooltip, StrctTour, StrctTransfer, StrctTree, StrctTreeNode, StrctTreeSelect, StrctVerticalNav, StrctWatermark, StrctWizard, StrctWizardAside, focusFirstIn, keepTabInside, lockBodyScroll, parseAnsi, provideStrctWizardDefaults, registerStrctIcon, restoreFocus, saveFocusedElement, strctComputeDiff, strctDpPad, strctFormatBytes, strctFormatDuration, strctFormatRate, strctFormatSi, strctValidationIcon, strctValidationTone, unlockBodyScroll };
23524
+ export { FOCUSABLE_SELECTOR, STRCT_DP_DOW, STRCT_DP_DOW_FULL, STRCT_DP_MONTHS, STRCT_ICONS, STRCT_ICON_GROUPS, STRCT_ICON_NAMES, STRCT_MASKS, STRCT_NOTIFICATION_HISTORY_LIMIT, STRCT_PALETTES, STRCT_RAW_ICONS, STRCT_TIME_RANGE_PRESETS, STRCT_WIZARD_DEFAULTS, StrctAccordion, StrctAccordionPanel, StrctAlert, StrctAnnouncer, StrctAvatar, StrctBadge, StrctBreadcrumb, StrctBreadcrumbItem, StrctButton, StrctButtonGroup, StrctBytesPipe, StrctCard, StrctCardBlock, StrctCardFooter, StrctCardHeader, StrctCardHeaderActions, StrctCardHeaderMeta, StrctCardHeaderNote, StrctCascadeColumn, StrctCascadeHost, StrctCascadeSelect, StrctCellDef, StrctCellStatus, StrctChart, StrctCheckbox, StrctChips, StrctCode, StrctCodeInline, StrctColorPicker, StrctCombobox, StrctCommandPalette, StrctConfirmOutlet, StrctConfirmService, StrctContextMenu, StrctContextMenuTrigger, StrctControlDescription, StrctCopy, StrctDatagrid, StrctDatagridActionBar, StrctDatagridActionBarCaption, StrctDatepicker, StrctDatetimePicker, StrctDesc, StrctDescriptionList, StrctDiff, StrctDivider, StrctDonut, StrctDrawer, StrctDrawerFooter, StrctDropdown, StrctDropdownDivider, StrctDropdownItem, StrctDropdownTrigger, StrctDurationPipe, StrctEmptyState, StrctField, StrctFieldGroup, StrctFieldHint, StrctFieldPrefix, StrctFieldSuffix, StrctFile, StrctFilterBar, StrctFlow, StrctFooter, StrctGauge, StrctHeader, StrctHeatmap, StrctHero, StrctHotkeysHelp, StrctHotkeysService, StrctIcon, StrctInlineEdit, StrctInput, StrctInputMask, StrctInputOtp, StrctKbd, StrctKnob, StrctList, StrctListItem, StrctListItemDescription, StrctListItemLeading, StrctListItemMeta, StrctListItemTrailing, StrctLogViewer, StrctLogin, StrctMenuPanel, StrctMenuService, StrctMenubar, StrctMetricTile, StrctModal, StrctModalContent, StrctNav, StrctNavItem, StrctNotificationCenter, StrctNumber, StrctOverlay, StrctPageHeader, StrctPageHeaderActions, StrctPageHeaderCrumbs, StrctPageHeaderTitleMeta, StrctPagination, StrctPassword, StrctPopover, StrctPopoverTrigger, StrctProgress, StrctRadio, StrctRadioGroup, StrctRail, StrctRange, StrctRatePipe, StrctRating, StrctReorder, StrctReorderItem, StrctRowDetailDef, StrctSearchbox, StrctSectionHeader, StrctSectionHeaderActions, StrctSectionHeaderMeta, StrctSectionMenu, StrctSegmented, StrctSelect, StrctShell, StrctShellService, StrctSiPipe, StrctSignpost, StrctSignpostTrigger, StrctSkeleton, StrctSparkline, StrctSpeedDial, StrctSpinner, StrctSplitButton, StrctSplitter, StrctStack, StrctStackItem, StrctStatusDot, StrctStep, StrctSubmenu, StrctTab, StrctTable, StrctTabs, StrctTag, StrctTagLeading, StrctThemeService, StrctThemeSwitcher, StrctTimeRangePicker, StrctTimeline, StrctTimelineItem, StrctToastOutlet, StrctToastService, StrctToggle, StrctToolbar, StrctToolbarCaption, StrctToolbarSpacer, StrctTooltip, StrctTour, StrctTransfer, StrctTree, StrctTreeNode, StrctTreeSelect, StrctVerticalNav, StrctWatermark, StrctWizard, StrctWizardAside, focusFirstIn, keepTabInside, lockBodyScroll, parseAnsi, provideStrctWizardDefaults, registerStrctIcon, restoreFocus, saveFocusedElement, strctComputeDiff, strctDpPad, strctFormatBytes, strctFormatDuration, strctFormatRate, strctFormatSi, strctValidationIcon, strctValidationTone, unlockBodyScroll };
23118
23525
  //# sourceMappingURL=akcelik-strct.mjs.map