@akcelik/strct 5.0.0 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/akcelik-strct.mjs +178 -22
- package/fesm2022/akcelik-strct.mjs.map +1 -1
- package/package.json +1 -1
- package/styles/_base.scss +37 -0
- package/types/akcelik-strct.d.ts +25 -2
|
@@ -1749,7 +1749,7 @@ class StrctPageHeader {
|
|
|
1749
1749
|
<div class="strct-ph__actions"><ng-content select="[strctPageHeaderActions]" /></div>
|
|
1750
1750
|
</div>
|
|
1751
1751
|
<ng-content />
|
|
1752
|
-
`, isInline: true, styles: [".strct-ph{display:block}.strct-ph--divider{padding-bottom:16px;border-bottom:1px solid var(--b1)}.strct-ph__crumbs:empty{display:none}.strct-ph__crumbs{margin-bottom:6px}.strct-ph__row{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.strct-ph__text{flex:1;min-width:0}.strct-ph__titlerow{display:flex;align-items:baseline;gap:var(--space-2);min-width:0;flex-wrap:wrap}.strct-ph__icon{align-self:center;color:var(--t2);flex:none}.strct-ph__titlemeta:empty{display:none}.strct-ph__titlemeta{display:inline-flex;align-items:center;gap:var(--space-2)}.strct-ph--pane .strct-ph__title{font-size:
|
|
1752
|
+
`, isInline: true, styles: [".strct-ph{display:block}.strct-ph--divider{padding-bottom:16px;border-bottom:1px solid var(--b1)}.strct-ph__crumbs:empty{display:none}.strct-ph__crumbs{margin-bottom:6px}.strct-ph__row{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.strct-ph__text{flex:1;min-width:0}.strct-ph__titlerow{display:flex;align-items:baseline;gap:var(--space-2);min-width:0;flex-wrap:wrap}.strct-ph__icon{align-self:center;color:var(--t2);flex:none}.strct-ph__titlemeta:empty{display:none}.strct-ph__titlemeta{display:inline-flex;align-items:center;gap:var(--space-2)}.strct-ph--pane .strct-ph__title{font-size:18px;font-weight:600;letter-spacing:0}.strct-ph__title{margin:0;font-size:var(--text-2xl);font-weight:700;letter-spacing:-.01em;color:var(--t1);text-wrap:balance}.strct-ph__subtitle{margin:6px 0 0;font-size:13px;line-height:1.55;color:var(--t2);max-width:72ch}.strct-ph__actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.strct-ph__actions:empty{display:none}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel", "count", "countMax", "countStatus", "countLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1753
1753
|
}
|
|
1754
1754
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctPageHeader, decorators: [{
|
|
1755
1755
|
type: Component,
|
|
@@ -1794,7 +1794,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1794
1794
|
class: 'strct-ph',
|
|
1795
1795
|
'[class.strct-ph--divider]': 'divider()',
|
|
1796
1796
|
'[class.strct-ph--pane]': "size() === 'pane'",
|
|
1797
|
-
}, styles: [".strct-ph{display:block}.strct-ph--divider{padding-bottom:16px;border-bottom:1px solid var(--b1)}.strct-ph__crumbs:empty{display:none}.strct-ph__crumbs{margin-bottom:6px}.strct-ph__row{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.strct-ph__text{flex:1;min-width:0}.strct-ph__titlerow{display:flex;align-items:baseline;gap:var(--space-2);min-width:0;flex-wrap:wrap}.strct-ph__icon{align-self:center;color:var(--t2);flex:none}.strct-ph__titlemeta:empty{display:none}.strct-ph__titlemeta{display:inline-flex;align-items:center;gap:var(--space-2)}.strct-ph--pane .strct-ph__title{font-size:
|
|
1797
|
+
}, styles: [".strct-ph{display:block}.strct-ph--divider{padding-bottom:16px;border-bottom:1px solid var(--b1)}.strct-ph__crumbs:empty{display:none}.strct-ph__crumbs{margin-bottom:6px}.strct-ph__row{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap}.strct-ph__text{flex:1;min-width:0}.strct-ph__titlerow{display:flex;align-items:baseline;gap:var(--space-2);min-width:0;flex-wrap:wrap}.strct-ph__icon{align-self:center;color:var(--t2);flex:none}.strct-ph__titlemeta:empty{display:none}.strct-ph__titlemeta{display:inline-flex;align-items:center;gap:var(--space-2)}.strct-ph--pane .strct-ph__title{font-size:18px;font-weight:600;letter-spacing:0}.strct-ph__title{margin:0;font-size:var(--text-2xl);font-weight:700;letter-spacing:-.01em;color:var(--t1);text-wrap:balance}.strct-ph__subtitle{margin:6px 0 0;font-size:13px;line-height:1.55;color:var(--t2);max-width:72ch}.strct-ph__actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.strct-ph__actions:empty{display:none}\n"] }]
|
|
1798
1798
|
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], divider: [{ type: i0.Input, args: [{ isSignal: true, alias: "divider", required: false }] }], level: [{ type: i0.Input, args: [{ isSignal: true, alias: "level", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }] } });
|
|
1799
1799
|
|
|
1800
1800
|
/** Leading marker of a row — a badge, a status dot, an icon. */
|
|
@@ -2216,8 +2216,25 @@ function strctCheckHostInputs(host, selector, owns) {
|
|
|
2216
2216
|
* way to break a flex host.
|
|
2217
2217
|
*/
|
|
2218
2218
|
function strctCheckHostDisplay(host, selector, expected) {
|
|
2219
|
+
// A host inside a closed modal or an unshown tab is not in the document yet,
|
|
2220
|
+
// so getComputedStyle reports '' — which is not an override. Warning there
|
|
2221
|
+
// would be wrong twice over: the message is nonsense, and because the warning
|
|
2222
|
+
// deduplicates by key it would mask a real override later on the same page.
|
|
2223
|
+
// Wait for the element to be laid out instead.
|
|
2224
|
+
if (!host.isConnected) {
|
|
2225
|
+
if (typeof ResizeObserver === 'undefined')
|
|
2226
|
+
return;
|
|
2227
|
+
const ro = new ResizeObserver(() => {
|
|
2228
|
+
if (!host.isConnected)
|
|
2229
|
+
return;
|
|
2230
|
+
ro.disconnect();
|
|
2231
|
+
strctCheckHostDisplay(host, selector, expected);
|
|
2232
|
+
});
|
|
2233
|
+
ro.observe(host);
|
|
2234
|
+
return;
|
|
2235
|
+
}
|
|
2219
2236
|
const actual = getComputedStyle(host).display;
|
|
2220
|
-
if (actual === expected)
|
|
2237
|
+
if (!actual || actual === expected)
|
|
2221
2238
|
return;
|
|
2222
2239
|
strctDevWarn(`host-display:${selector}`, `[strct] <${selector}> needs display: ${expected}, but it computes to ${actual}. ` +
|
|
2223
2240
|
`Wrap it, or set the margin on a wrapper, rather than changing its display.`);
|
|
@@ -2660,7 +2677,7 @@ class StrctSpinner {
|
|
|
2660
2677
|
<span class="strct-spinner__ring"></span>
|
|
2661
2678
|
<span class="strct-spinner__caption">{{ caption() }}</span>
|
|
2662
2679
|
}
|
|
2663
|
-
`, isInline: true, styles: [".strct-spinner{display:inline-block;width:22px;height:22px;border:2.5px solid var(--b3);border-top-color:var(--acc);border-radius:50%;animation:strct-spin .7s linear infinite}.strct-spinner--sm{width:14px;height:14px;border-width:2px}.strct-spinner--lg{width:34px;height:34px;border-width:3px}@keyframes strct-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.strct-spinner{animation-duration:1.6s}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2680
|
+
`, isInline: true, styles: [".strct-spinner{display:inline-block;width:22px;height:22px;border:2.5px solid var(--b3);border-top-color:var(--acc);border-radius:50%;animation:strct-spin .7s linear infinite}.strct-spinner--sm{width:14px;height:14px;border-width:2px}.strct-spinner--lg{width:34px;height:34px;border-width:3px}@keyframes strct-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.strct-spinner{animation-duration:1.6s}}.strct-spinner--captioned{display:inline-flex;align-items:center;gap:var(--space-2);width:auto;height:auto;border:0;border-radius:0;animation:none}.strct-spinner__ring{flex:none;width:22px;height:22px;border:2.5px solid var(--b3);border-top-color:var(--acc);border-radius:50%;animation:strct-spin .7s linear infinite}.strct-spinner--sm .strct-spinner__ring{width:14px;height:14px;border-width:2px}.strct-spinner--lg .strct-spinner__ring{width:34px;height:34px;border-width:3px}@media(prefers-reduced-motion:reduce){.strct-spinner__ring{animation-duration:1.6s}}.strct-spinner__caption{font-size:var(--text-sm);color:var(--t3);line-height:1.3}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2664
2681
|
}
|
|
2665
2682
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctSpinner, decorators: [{
|
|
2666
2683
|
type: Component,
|
|
@@ -2676,7 +2693,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
2676
2693
|
'[attr.aria-label]': 'caption() || label()',
|
|
2677
2694
|
'[class.strct-spinner--sm]': "size() === 'sm'",
|
|
2678
2695
|
'[class.strct-spinner--lg]': "size() === 'lg'",
|
|
2679
|
-
}, styles: [".strct-spinner{display:inline-block;width:22px;height:22px;border:2.5px solid var(--b3);border-top-color:var(--acc);border-radius:50%;animation:strct-spin .7s linear infinite}.strct-spinner--sm{width:14px;height:14px;border-width:2px}.strct-spinner--lg{width:34px;height:34px;border-width:3px}@keyframes strct-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.strct-spinner{animation-duration:1.6s}}\n"] }]
|
|
2696
|
+
}, styles: [".strct-spinner{display:inline-block;width:22px;height:22px;border:2.5px solid var(--b3);border-top-color:var(--acc);border-radius:50%;animation:strct-spin .7s linear infinite}.strct-spinner--sm{width:14px;height:14px;border-width:2px}.strct-spinner--lg{width:34px;height:34px;border-width:3px}@keyframes strct-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.strct-spinner{animation-duration:1.6s}}.strct-spinner--captioned{display:inline-flex;align-items:center;gap:var(--space-2);width:auto;height:auto;border:0;border-radius:0;animation:none}.strct-spinner__ring{flex:none;width:22px;height:22px;border:2.5px solid var(--b3);border-top-color:var(--acc);border-radius:50%;animation:strct-spin .7s linear infinite}.strct-spinner--sm .strct-spinner__ring{width:14px;height:14px;border-width:2px}.strct-spinner--lg .strct-spinner__ring{width:34px;height:34px;border-width:3px}@media(prefers-reduced-motion:reduce){.strct-spinner__ring{animation-duration:1.6s}}.strct-spinner__caption{font-size:var(--text-sm);color:var(--t3);line-height:1.3}\n"] }]
|
|
2680
2697
|
}], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], caption: [{ type: i0.Input, args: [{ isSignal: true, alias: "caption", required: false }] }] } });
|
|
2681
2698
|
|
|
2682
2699
|
/**
|
|
@@ -7793,22 +7810,60 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
7793
7810
|
class StrctCodeInline {
|
|
7794
7811
|
/** Append a copy button that copies this element's text. */
|
|
7795
7812
|
copyable = input(false, { ...(ngDevMode ? { debugName: "copyable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
7813
|
+
/**
|
|
7814
|
+
* What the copy button puts on the clipboard, when that is not simply what
|
|
7815
|
+
* the element says — a span showing a shortened thumbprint copies the whole
|
|
7816
|
+
* one. Empty follows the element's own text, including later changes.
|
|
7817
|
+
*/
|
|
7818
|
+
value = input('', /* @ts-ignore */
|
|
7819
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
7820
|
+
/** Long ids wrap instead of overflowing a narrow card. */
|
|
7821
|
+
wrap = input(false, { ...(ngDevMode ? { debugName: "wrap" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
7796
7822
|
host = inject(ElementRef);
|
|
7797
7823
|
vcr = inject(ViewContainerRef);
|
|
7824
|
+
destroyRef = inject(DestroyRef);
|
|
7825
|
+
/** The button, once it exists; and a counter the observer bumps. */
|
|
7826
|
+
copyRef = signal(null, /* @ts-ignore */
|
|
7827
|
+
...(ngDevMode ? [{ debugName: "copyRef" }] : /* istanbul ignore next */ []));
|
|
7828
|
+
revision = signal(0, /* @ts-ignore */
|
|
7829
|
+
...(ngDevMode ? [{ debugName: "revision" }] : /* istanbul ignore next */ []));
|
|
7798
7830
|
constructor() {
|
|
7799
7831
|
afterNextRender(() => {
|
|
7800
7832
|
if (!this.copyable())
|
|
7801
7833
|
return;
|
|
7802
7834
|
const el = this.host.nativeElement;
|
|
7803
7835
|
const ref = this.vcr.createComponent(StrctCopy);
|
|
7804
|
-
// The text to copy is what the element says, before the button joins it.
|
|
7805
|
-
ref.setInput('text', el.textContent?.trim() ?? '');
|
|
7806
|
-
ref.changeDetectorRef.detectChanges();
|
|
7807
7836
|
el.appendChild(ref.location.nativeElement);
|
|
7837
|
+
this.copyRef.set(ref);
|
|
7838
|
+
// The element's text is not a signal, so watch it: a path or a thumbprint
|
|
7839
|
+
// that loads later must be the text that gets copied, not the first one.
|
|
7840
|
+
if (typeof MutationObserver !== 'undefined') {
|
|
7841
|
+
const mo = new MutationObserver(() => this.revision.update((n) => n + 1));
|
|
7842
|
+
mo.observe(el, { childList: true, characterData: true, subtree: true });
|
|
7843
|
+
this.destroyRef.onDestroy(() => mo.disconnect());
|
|
7844
|
+
}
|
|
7845
|
+
});
|
|
7846
|
+
// Keeps the button's text in step with `value`, or with the element.
|
|
7847
|
+
effect(() => {
|
|
7848
|
+
const ref = this.copyRef();
|
|
7849
|
+
if (!ref)
|
|
7850
|
+
return;
|
|
7851
|
+
this.revision(); // re-read the element whenever its text changed
|
|
7852
|
+
const text = this.value() || this.ownText();
|
|
7853
|
+
untracked(() => {
|
|
7854
|
+
ref.setInput('text', text);
|
|
7855
|
+
ref.changeDetectorRef.detectChanges();
|
|
7856
|
+
});
|
|
7808
7857
|
});
|
|
7809
7858
|
}
|
|
7859
|
+
/** What the element says, without the copy button's own content. */
|
|
7860
|
+
ownText() {
|
|
7861
|
+
const clone = this.host.nativeElement.cloneNode(true);
|
|
7862
|
+
clone.querySelector('strct-copy')?.remove();
|
|
7863
|
+
return clone.textContent?.trim() ?? '';
|
|
7864
|
+
}
|
|
7810
7865
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctCodeInline, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
7811
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.4", type: StrctCodeInline, isStandalone: true, selector: "[strctCode]", inputs: { copyable: { classPropertyName: "copyable", publicName: "copyable", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.strct-code-inline--copyable": "copyable()" }, classAttribute: "strct-code-inline" }, ngImport: i0 });
|
|
7866
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.4", type: StrctCodeInline, isStandalone: true, selector: "[strctCode]", inputs: { copyable: { classPropertyName: "copyable", publicName: "copyable", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, wrap: { classPropertyName: "wrap", publicName: "wrap", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.strct-code-inline--copyable": "copyable()", "class.strct-code-inline--wrap": "wrap()" }, classAttribute: "strct-code-inline" }, ngImport: i0 });
|
|
7812
7867
|
}
|
|
7813
7868
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctCodeInline, decorators: [{
|
|
7814
7869
|
type: Directive,
|
|
@@ -7817,9 +7872,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
7817
7872
|
host: {
|
|
7818
7873
|
class: 'strct-code-inline',
|
|
7819
7874
|
'[class.strct-code-inline--copyable]': 'copyable()',
|
|
7875
|
+
'[class.strct-code-inline--wrap]': 'wrap()',
|
|
7820
7876
|
},
|
|
7821
7877
|
}]
|
|
7822
|
-
}], ctorParameters: () => [], propDecorators: { copyable: [{ type: i0.Input, args: [{ isSignal: true, alias: "copyable", required: false }] }] } });
|
|
7878
|
+
}], ctorParameters: () => [], propDecorators: { copyable: [{ type: i0.Input, args: [{ isSignal: true, alias: "copyable", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], wrap: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrap", required: false }] }] } });
|
|
7823
7879
|
|
|
7824
7880
|
/**
|
|
7825
7881
|
* The standard strip above a data grid: a search field, the active filter
|
|
@@ -12522,6 +12578,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
12522
12578
|
/**
|
|
12523
12579
|
* One projected `label → value` row inside a `<strct-description-list>`. The
|
|
12524
12580
|
* value is whatever you project, so it can host a badge, icon or formatted text.
|
|
12581
|
+
*
|
|
12582
|
+
* Use **`<div strctDesc>`** inside a list: `<dl>` allows only `dt` / `dd` pairs
|
|
12583
|
+
* or `<div>` wrappers as children, so a `<strct-desc>` element between them is
|
|
12584
|
+
* invalid and assistive tech loses the pairing. `<strct-desc>` still works for a
|
|
12585
|
+
* row rendered outside a list.
|
|
12525
12586
|
*/
|
|
12526
12587
|
class StrctDesc {
|
|
12527
12588
|
/** The row's label. */
|
|
@@ -12544,7 +12605,7 @@ class StrctDesc {
|
|
|
12544
12605
|
note = input('', /* @ts-ignore */
|
|
12545
12606
|
...(ngDevMode ? [{ debugName: "note" }] : /* istanbul ignore next */ []));
|
|
12546
12607
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctDesc, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
12547
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctDesc, isStandalone: true, selector: "strct-desc", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, mono: { classPropertyName: "mono", publicName: "mono", isSignal: true, isRequired: false, transformFunction: null }, muted: { classPropertyName: "muted", publicName: "muted", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, statusLabel: { classPropertyName: "statusLabel", publicName: "statusLabel", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, note: { classPropertyName: "note", publicName: "note", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.strct-desc--mono": "mono()", "class.strct-desc--muted": "muted()" }, classAttribute: "strct-desc" }, ngImport: i0, template: `
|
|
12608
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctDesc, isStandalone: true, selector: "strct-desc, div[strctDesc]", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, mono: { classPropertyName: "mono", publicName: "mono", isSignal: true, isRequired: false, transformFunction: null }, muted: { classPropertyName: "muted", publicName: "muted", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, statusLabel: { classPropertyName: "statusLabel", publicName: "statusLabel", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, note: { classPropertyName: "note", publicName: "note", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.strct-desc--mono": "mono()", "class.strct-desc--muted": "muted()" }, classAttribute: "strct-desc" }, ngImport: i0, template: `
|
|
12548
12609
|
<dt class="strct-desc__label">
|
|
12549
12610
|
@if (status()) {
|
|
12550
12611
|
<strct-status-dot size="sm" [status]="status()!" [label]="statusLabel()" />
|
|
@@ -12565,7 +12626,11 @@ class StrctDesc {
|
|
|
12565
12626
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctDesc, decorators: [{
|
|
12566
12627
|
type: Component,
|
|
12567
12628
|
args: [{
|
|
12568
|
-
|
|
12629
|
+
// Both spellings. `<strct-desc>` is the readable one, but a custom element
|
|
12630
|
+
// between `<dl>` and its `dt` / `dd` breaks the content model — axe reports
|
|
12631
|
+
// definition-list and dlitem — so inside a list, use `<div strctDesc>`, which
|
|
12632
|
+
// the model does allow. (`StrctInput` gained `strct-input` the same way.)
|
|
12633
|
+
selector: 'strct-desc, div[strctDesc]',
|
|
12569
12634
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
12570
12635
|
encapsulation: ViewEncapsulation.None,
|
|
12571
12636
|
imports: [StrctIcon, StrctStatusDot],
|
|
@@ -14283,6 +14348,51 @@ class StrctDatagrid {
|
|
|
14283
14348
|
return;
|
|
14284
14349
|
untracked(() => this.selected.set(new Set(init)));
|
|
14285
14350
|
});
|
|
14351
|
+
// A selection must not outlive its rows: after a delete the footer said
|
|
14352
|
+
// "2 selected" and selectionChange consumers held ids for rows that are
|
|
14353
|
+
// gone. Prune to the ids the current rows can account for, and emit only
|
|
14354
|
+
// when the pruning actually removed something. A lazy grid cannot prove a
|
|
14355
|
+
// row is gone rather than on another page, so it is left alone.
|
|
14356
|
+
effect(() => {
|
|
14357
|
+
const rows = this.rows();
|
|
14358
|
+
if (this.lazy())
|
|
14359
|
+
return;
|
|
14360
|
+
untracked(() => {
|
|
14361
|
+
const selected = this.selected();
|
|
14362
|
+
if (!selected.size)
|
|
14363
|
+
return;
|
|
14364
|
+
const present = new Set(rows.map((r) => this.idOf(r)));
|
|
14365
|
+
const kept = new Set([...selected].filter((id) => present.has(id)));
|
|
14366
|
+
if (kept.size === selected.size)
|
|
14367
|
+
return;
|
|
14368
|
+
this.commitSelection(kept);
|
|
14369
|
+
});
|
|
14370
|
+
});
|
|
14371
|
+
// Single mode: the checked row follows `selectedId`, whoever wrote it — the
|
|
14372
|
+
// user picking, or a consumer restoring a pick from an earlier step. It
|
|
14373
|
+
// writes `selected` directly rather than through commitSelection, so an
|
|
14374
|
+
// external write never emits selectionChange (a user's own pick already
|
|
14375
|
+
// emitted one).
|
|
14376
|
+
effect(() => {
|
|
14377
|
+
if (this.mode() !== 'single')
|
|
14378
|
+
return;
|
|
14379
|
+
const id = this.selectedId();
|
|
14380
|
+
untracked(() => {
|
|
14381
|
+
const next = id == null ? new Set() : new Set([id]);
|
|
14382
|
+
const current = this.selected();
|
|
14383
|
+
if (current.size === next.size && [...next].every((v) => current.has(v)))
|
|
14384
|
+
return;
|
|
14385
|
+
this.selected.set(next);
|
|
14386
|
+
// Keep the row snapshot in step when the row is loaded; a pick set
|
|
14387
|
+
// before the rows arrive is cached when it is toggled later.
|
|
14388
|
+
this.selectedRowCache.clear();
|
|
14389
|
+
if (id != null) {
|
|
14390
|
+
const row = this.rows().find((r) => this.idOf(r) === id);
|
|
14391
|
+
if (row)
|
|
14392
|
+
this.selectedRowCache.set(id, row);
|
|
14393
|
+
}
|
|
14394
|
+
});
|
|
14395
|
+
});
|
|
14286
14396
|
// Dev mode only: say so when rowId or initialSelection cannot do what they
|
|
14287
14397
|
// were given to do. In production the effect is never registered.
|
|
14288
14398
|
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
|
|
@@ -19737,7 +19847,7 @@ class StrctEmptyState {
|
|
|
19737
19847
|
<p class="strct-empty__desc">{{ description() }}</p>
|
|
19738
19848
|
}
|
|
19739
19849
|
<div class="strct-empty__actions"><ng-content /></div>
|
|
19740
|
-
`, isInline: true, styles: [".strct-empty{display:flex;flex-direction:column;align-items:center;text-align:center;gap:10px;padding:40px 24px}.strct-empty__icon{display:inline-flex;align-items:center;justify-content:center;width:56px;height:56px;border-radius:14px;margin-bottom:2px}.strct-empty__icon--neutral{background:var(--bg-3);color:var(--t2)}.strct-empty__icon--warning{background:var(--warning-bg);color:var(--warning)}.strct-empty__icon--critical{background:var(--critical-bg);color:var(--critical)}.strct-empty__icon--accent{background:var(--acc-m);color:var(--acc)}.strct-empty__title{margin:0;font-size:15px;font-weight:600;color:var(--t1)}.strct-empty__desc{margin:0;max-width:360px;font-size:13px;line-height:1.5;color:var(--t3)}.strct-empty__actions{display:flex;align-items:center;gap:8px;margin-top:6px}.strct-empty__actions:empty{display:none}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel", "count", "countMax", "countStatus", "countLabel"] }, { kind: "component", type: StrctSpinner, selector: "strct-spinner", inputs: ["size", "label", "caption"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
19850
|
+
`, isInline: true, styles: [".strct-empty{display:flex;flex-direction:column;align-items:center;text-align:center;gap:10px;padding:40px 24px}.strct-empty__icon{display:inline-flex;align-items:center;justify-content:center;width:56px;height:56px;border-radius:14px;margin-bottom:2px}.strct-empty__icon--neutral{background:var(--bg-3);color:var(--t2)}.strct-empty__icon--warning{background:var(--warning-bg);color:var(--warning)}.strct-empty__icon--critical{background:var(--critical-bg);color:var(--critical)}.strct-empty__icon--accent{background:var(--acc-m);color:var(--acc)}.strct-empty__title{margin:0;font-size:15px;font-weight:600;color:var(--t1)}.strct-empty__desc{margin:0;max-width:360px;font-size:13px;line-height:1.5;color:var(--t3)}.strct-empty--sm{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:2px var(--space-2);text-align:start;padding:var(--space-3)}.strct-empty--sm .strct-empty__icon{width:16px;height:16px;border-radius:0;margin-bottom:0;background:none;grid-row:1}.strct-empty--sm .strct-empty__title{font-size:13px;grid-row:1}.strct-empty--sm .strct-empty__desc,.strct-empty--sm .strct-empty__actions{grid-column:2}.strct-empty--sm .strct-empty__desc{font-size:var(--text-sm);max-width:none}.strct-empty--sm .strct-empty__actions:empty{display:none}.strct-empty__actions{display:flex;align-items:center;gap:8px;margin-top:6px}.strct-empty__actions:empty{display:none}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel", "count", "countMax", "countStatus", "countLabel"] }, { kind: "component", type: StrctSpinner, selector: "strct-spinner", inputs: ["size", "label", "caption"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
19741
19851
|
}
|
|
19742
19852
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctEmptyState, decorators: [{
|
|
19743
19853
|
type: Component,
|
|
@@ -19762,7 +19872,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
19762
19872
|
class: 'strct-empty',
|
|
19763
19873
|
'[class.strct-empty--sm]': "size() === 'sm'",
|
|
19764
19874
|
'[attr.aria-busy]': "variant() === 'loading' ? 'true' : null",
|
|
19765
|
-
}, styles: [".strct-empty{display:flex;flex-direction:column;align-items:center;text-align:center;gap:10px;padding:40px 24px}.strct-empty__icon{display:inline-flex;align-items:center;justify-content:center;width:56px;height:56px;border-radius:14px;margin-bottom:2px}.strct-empty__icon--neutral{background:var(--bg-3);color:var(--t2)}.strct-empty__icon--warning{background:var(--warning-bg);color:var(--warning)}.strct-empty__icon--critical{background:var(--critical-bg);color:var(--critical)}.strct-empty__icon--accent{background:var(--acc-m);color:var(--acc)}.strct-empty__title{margin:0;font-size:15px;font-weight:600;color:var(--t1)}.strct-empty__desc{margin:0;max-width:360px;font-size:13px;line-height:1.5;color:var(--t3)}.strct-empty__actions{display:flex;align-items:center;gap:8px;margin-top:6px}.strct-empty__actions:empty{display:none}\n"] }]
|
|
19875
|
+
}, styles: [".strct-empty{display:flex;flex-direction:column;align-items:center;text-align:center;gap:10px;padding:40px 24px}.strct-empty__icon{display:inline-flex;align-items:center;justify-content:center;width:56px;height:56px;border-radius:14px;margin-bottom:2px}.strct-empty__icon--neutral{background:var(--bg-3);color:var(--t2)}.strct-empty__icon--warning{background:var(--warning-bg);color:var(--warning)}.strct-empty__icon--critical{background:var(--critical-bg);color:var(--critical)}.strct-empty__icon--accent{background:var(--acc-m);color:var(--acc)}.strct-empty__title{margin:0;font-size:15px;font-weight:600;color:var(--t1)}.strct-empty__desc{margin:0;max-width:360px;font-size:13px;line-height:1.5;color:var(--t3)}.strct-empty--sm{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:2px var(--space-2);text-align:start;padding:var(--space-3)}.strct-empty--sm .strct-empty__icon{width:16px;height:16px;border-radius:0;margin-bottom:0;background:none;grid-row:1}.strct-empty--sm .strct-empty__title{font-size:13px;grid-row:1}.strct-empty--sm .strct-empty__desc,.strct-empty--sm .strct-empty__actions{grid-column:2}.strct-empty--sm .strct-empty__desc{font-size:var(--text-sm);max-width:none}.strct-empty--sm .strct-empty__actions:empty{display:none}.strct-empty__actions{display:flex;align-items:center;gap:8px;margin-top:6px}.strct-empty__actions:empty{display:none}\n"] }]
|
|
19766
19876
|
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }] } });
|
|
19767
19877
|
|
|
19768
19878
|
/**
|
|
@@ -22922,7 +23032,9 @@ class StrctReorderItem {
|
|
|
22922
23032
|
// Captured before our own binding ever writes tabindex, so it never flips.
|
|
22923
23033
|
hadOwnTabindex = this.el.nativeElement.hasAttribute('tabindex');
|
|
22924
23034
|
hostTabindex() {
|
|
22925
|
-
|
|
23035
|
+
if (this.hadOwnTabindex)
|
|
23036
|
+
return null;
|
|
23037
|
+
return this.list.reorderDisabled() ? null : 0;
|
|
22926
23038
|
}
|
|
22927
23039
|
/** The keys that apply: the sideways pair only when there is somewhere to go. */
|
|
22928
23040
|
shortcuts() {
|
|
@@ -23008,7 +23120,7 @@ class StrctReorderItem {
|
|
|
23008
23120
|
setTimeout(() => this.list.items()[to]?.focus());
|
|
23009
23121
|
}
|
|
23010
23122
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctReorderItem, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
23011
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.4", type: StrctReorderItem, isStandalone: true, selector: "[strctReorderItem]", host: { listeners: { "pointerdown": "onPointerDown($event)", "dragstart": "onDragStart($event)", "dragover": "onDragOver($event)", "drop": "onDrop($event)", "dragend": "onDragEnd()", "keydown": "onKeydown($event)" }, properties: { "attr.draggable": "!list.reorderDisabled()", "attr.tabindex": "hostTabindex()", "class.strct-reorder--dragging": "isDragging()", "class.strct-reorder--over": "isOver()", "attr.aria-roledescription": "'sortable'", "attr.aria-keyshortcuts": "shortcuts()", "attr.aria-posinset": "index() + 1", "attr.aria-setsize": "list.items().length", "attr.aria-describedby": "list.instructions() ? list.instructionsId
|
|
23123
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.4", type: StrctReorderItem, isStandalone: true, selector: "[strctReorderItem]", host: { listeners: { "pointerdown": "onPointerDown($event)", "dragstart": "onDragStart($event)", "dragover": "onDragOver($event)", "drop": "onDrop($event)", "dragend": "onDragEnd()", "keydown": "onKeydown($event)" }, properties: { "attr.draggable": "!list.reorderDisabled()", "attr.tabindex": "hostTabindex()", "class.strct-reorder--dragging": "isDragging()", "class.strct-reorder--over": "isOver()", "attr.aria-roledescription": "list.reorderDisabled() ? null : 'sortable'", "attr.aria-keyshortcuts": "list.reorderDisabled() ? null : shortcuts()", "attr.aria-posinset": "list.reorderDisabled() ? null : index() + 1", "attr.aria-setsize": "list.reorderDisabled() ? null : list.items().length", "attr.aria-describedby": "list.reorderDisabled() || !list.instructions() ? null : list.instructionsId" } }, ngImport: i0 });
|
|
23012
23124
|
}
|
|
23013
23125
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctReorderItem, decorators: [{
|
|
23014
23126
|
type: Directive,
|
|
@@ -23019,11 +23131,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
23019
23131
|
'[attr.tabindex]': 'hostTabindex()',
|
|
23020
23132
|
'[class.strct-reorder--dragging]': 'isDragging()',
|
|
23021
23133
|
'[class.strct-reorder--over]': 'isOver()',
|
|
23022
|
-
|
|
23023
|
-
|
|
23024
|
-
|
|
23025
|
-
'[attr.aria-
|
|
23026
|
-
'[attr.aria-
|
|
23134
|
+
// A display-only list says nothing about sorting: no roledescription, no
|
|
23135
|
+
// shortcuts, no tab stop of its own, and no description pointing at
|
|
23136
|
+
// instructions that do not apply.
|
|
23137
|
+
'[attr.aria-roledescription]': "list.reorderDisabled() ? null : 'sortable'",
|
|
23138
|
+
'[attr.aria-keyshortcuts]': 'list.reorderDisabled() ? null : shortcuts()',
|
|
23139
|
+
'[attr.aria-posinset]': 'list.reorderDisabled() ? null : index() + 1',
|
|
23140
|
+
'[attr.aria-setsize]': 'list.reorderDisabled() ? null : list.items().length',
|
|
23141
|
+
'[attr.aria-describedby]': 'list.reorderDisabled() || !list.instructions() ? null : list.instructionsId',
|
|
23027
23142
|
},
|
|
23028
23143
|
}]
|
|
23029
23144
|
}], propDecorators: { onPointerDown: [{
|
|
@@ -23598,6 +23713,7 @@ class StrctWindow {
|
|
|
23598
23713
|
...(ngDevMode ? [{ debugName: "L" }] : /* istanbul ignore next */ []));
|
|
23599
23714
|
service = inject(StrctWindowService);
|
|
23600
23715
|
doc = inject(DOCUMENT$1);
|
|
23716
|
+
zone = inject(NgZone);
|
|
23601
23717
|
host = inject(ElementRef);
|
|
23602
23718
|
zOffset = signal(0, /* @ts-ignore */
|
|
23603
23719
|
...(ngDevMode ? [{ debugName: "zOffset" }] : /* istanbul ignore next */ []));
|
|
@@ -23612,6 +23728,16 @@ class StrctWindow {
|
|
|
23612
23728
|
rect = computed(() => this.bounds() ?? this.fallback(), /* @ts-ignore */
|
|
23613
23729
|
...(ngDevMode ? [{ debugName: "rect" }] : /* istanbul ignore next */ []));
|
|
23614
23730
|
restoreTo = null;
|
|
23731
|
+
/** A click beside the window, when `closeOnOutside` asks for one. */
|
|
23732
|
+
onOutside = (event) => {
|
|
23733
|
+
if (this.closeOnOutside() !== 'minimize' || !this.open() || this.minimized())
|
|
23734
|
+
return;
|
|
23735
|
+
const frame = this.host.nativeElement.querySelector('.strct-window__frame');
|
|
23736
|
+
const target = event.target;
|
|
23737
|
+
if (frame && target instanceof Node && frame.contains(target))
|
|
23738
|
+
return;
|
|
23739
|
+
this.zone.run(() => this.minimize());
|
|
23740
|
+
};
|
|
23615
23741
|
constructor() {
|
|
23616
23742
|
this.service.register(this);
|
|
23617
23743
|
effect(() => {
|
|
@@ -23621,6 +23747,19 @@ class StrctWindow {
|
|
|
23621
23747
|
queueMicrotask(() => this.focusTitle());
|
|
23622
23748
|
}
|
|
23623
23749
|
});
|
|
23750
|
+
// `closeOnOutside` was declared and never read. The listener is added only
|
|
23751
|
+
// while a window asks for it, and outside the zone — a click anywhere on
|
|
23752
|
+
// the page must not cost a change-detection pass for every open window.
|
|
23753
|
+
effect((onCleanup) => {
|
|
23754
|
+
if (this.closeOnOutside() !== 'minimize' || !this.open() || this.minimized())
|
|
23755
|
+
return;
|
|
23756
|
+
// Deferred, so the click that opened the window does not close it.
|
|
23757
|
+
const timer = setTimeout(() => this.zone.runOutsideAngular(() => this.doc.addEventListener('pointerdown', this.onOutside, true)));
|
|
23758
|
+
onCleanup(() => {
|
|
23759
|
+
clearTimeout(timer);
|
|
23760
|
+
this.doc.removeEventListener('pointerdown', this.onOutside, true);
|
|
23761
|
+
});
|
|
23762
|
+
});
|
|
23624
23763
|
}
|
|
23625
23764
|
/** Raise this window above the others when it is clicked. */
|
|
23626
23765
|
focusWindow() {
|
|
@@ -24011,8 +24150,25 @@ class StrctChatThread {
|
|
|
24011
24150
|
/** False once the reader scrolls away from the end; true again at the end. */
|
|
24012
24151
|
atEnd = signal(true, /* @ts-ignore */
|
|
24013
24152
|
...(ngDevMode ? [{ debugName: "atEnd" }] : /* istanbul ignore next */ []));
|
|
24153
|
+
destroyRef = inject(DestroyRef);
|
|
24014
24154
|
constructor() {
|
|
24015
|
-
afterNextRender(() =>
|
|
24155
|
+
afterNextRender(() => {
|
|
24156
|
+
this.scrollToEnd();
|
|
24157
|
+
// A new message, or a streaming one growing, changes the list's height —
|
|
24158
|
+
// and nothing else tells the thread that. Following `busy` alone left the
|
|
24159
|
+
// reader looking at the message before last.
|
|
24160
|
+
if (typeof ResizeObserver === 'undefined')
|
|
24161
|
+
return;
|
|
24162
|
+
const list = this.host.nativeElement.querySelector('.strct-chat__list');
|
|
24163
|
+
if (!list)
|
|
24164
|
+
return;
|
|
24165
|
+
const ro = new ResizeObserver(() => {
|
|
24166
|
+
if (this.autoScroll() && this.atEnd())
|
|
24167
|
+
this.scrollToEnd();
|
|
24168
|
+
});
|
|
24169
|
+
ro.observe(list);
|
|
24170
|
+
this.destroyRef.onDestroy(() => ro.disconnect());
|
|
24171
|
+
});
|
|
24016
24172
|
effect(() => {
|
|
24017
24173
|
this.busy();
|
|
24018
24174
|
if (this.autoScroll() && this.atEnd())
|