@akcelik/strct 5.4.0 → 5.5.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.
@@ -2539,6 +2539,25 @@ class StrctProgress {
2539
2539
  /** A quiet line under the bar — "219 GB free across 2 nodes". */
2540
2540
  caption = input('', /* @ts-ignore */
2541
2541
  ...(ngDevMode ? [{ debugName: "caption" }] : /* istanbul ignore next */ []));
2542
+ /**
2543
+ * The caption's tone. A critical capacity line's note — "2 GB left after the
2544
+ * tightest node" — is the warning; `--t3` says it is an aside.
2545
+ */
2546
+ captionStatus = input(null, /* @ts-ignore */
2547
+ ...(ngDevMode ? [{ debugName: "captionStatus" }] : /* istanbul ignore next */ []));
2548
+ /**
2549
+ * The bar's accessible name, when the visible `label` is not it: a column of
2550
+ * per-cluster memory bars would otherwise all be named "Memory". Defaults to
2551
+ * `label`.
2552
+ */
2553
+ ariaLabel = input('', /* @ts-ignore */
2554
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
2555
+ /**
2556
+ * Where `showValue` puts the number: on its own row above the track, or
2557
+ * beside it — which is what a bar inside a table cell wants.
2558
+ */
2559
+ valuePosition = input('top', /* @ts-ignore */
2560
+ ...(ngDevMode ? [{ debugName: "valuePosition" }] : /* istanbul ignore next */ []));
2542
2561
  /** Running, but with no percentage to report. */
2543
2562
  indeterminate = input(false, { ...(ngDevMode ? { debugName: "indeterminate" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2544
2563
  /** Stack several fills (used now + what would arrive); clamped to 100 total. */
@@ -2594,13 +2613,13 @@ class StrctProgress {
2594
2613
  }, /* @ts-ignore */
2595
2614
  ...(ngDevMode ? [{ debugName: "resolvedStatus" }] : /* istanbul ignore next */ []));
2596
2615
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctProgress, deps: [], target: i0.ɵɵFactoryTarget.Component });
2597
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctProgress, isStandalone: true, selector: "strct-progress", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, visibleLabel: { classPropertyName: "visibleLabel", publicName: "visibleLabel", isSignal: true, isRequired: false, transformFunction: null }, showValue: { classPropertyName: "showValue", publicName: "showValue", isSignal: true, isRequired: false, transformFunction: null }, valueText: { classPropertyName: "valueText", publicName: "valueText", isSignal: true, isRequired: false, transformFunction: null }, caption: { classPropertyName: "caption", publicName: "caption", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, segments: { classPropertyName: "segments", publicName: "segments", isSignal: true, isRequired: false, transformFunction: null }, thresholds: { classPropertyName: "thresholds", publicName: "thresholds", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.strct-progress--neutral": "resolvedStatus() === 'neutral'", "class.strct-progress--success": "resolvedStatus() === 'success'", "class.strct-progress--warning": "resolvedStatus() === 'warning'", "class.strct-progress--critical": "resolvedStatus() === 'critical'" }, classAttribute: "strct-progress" }, ngImport: i0, template: `
2598
- @if (visibleLabel() || showValue()) {
2616
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctProgress, isStandalone: true, selector: "strct-progress", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, visibleLabel: { classPropertyName: "visibleLabel", publicName: "visibleLabel", isSignal: true, isRequired: false, transformFunction: null }, showValue: { classPropertyName: "showValue", publicName: "showValue", isSignal: true, isRequired: false, transformFunction: null }, valueText: { classPropertyName: "valueText", publicName: "valueText", isSignal: true, isRequired: false, transformFunction: null }, caption: { classPropertyName: "caption", publicName: "caption", isSignal: true, isRequired: false, transformFunction: null }, captionStatus: { classPropertyName: "captionStatus", publicName: "captionStatus", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, valuePosition: { classPropertyName: "valuePosition", publicName: "valuePosition", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, segments: { classPropertyName: "segments", publicName: "segments", isSignal: true, isRequired: false, transformFunction: null }, thresholds: { classPropertyName: "thresholds", publicName: "thresholds", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.strct-progress--neutral": "resolvedStatus() === 'neutral'", "class.strct-progress--success": "resolvedStatus() === 'success'", "class.strct-progress--warning": "resolvedStatus() === 'warning'", "class.strct-progress--critical": "resolvedStatus() === 'critical'", "class.strct-progress--endvalue": "showValue() && valuePosition() === 'end'" }, classAttribute: "strct-progress" }, ngImport: i0, template: `
2617
+ @if (visibleLabel() || (showValue() && valuePosition() === 'top')) {
2599
2618
  <div class="strct-progress__row">
2600
2619
  @if (visibleLabel()) {
2601
2620
  <span class="strct-progress__label">{{ label() }}</span>
2602
2621
  }
2603
- @if (showValue()) {
2622
+ @if (showValue() && valuePosition() === 'top') {
2604
2623
  <span class="strct-progress__value">{{ valueText() || clamped() + '%' }}</span>
2605
2624
  }
2606
2625
  </div>
@@ -2608,7 +2627,7 @@ class StrctProgress {
2608
2627
  <div
2609
2628
  class="strct-progress__track"
2610
2629
  role="progressbar"
2611
- [attr.aria-label]="label() || 'Progress'"
2630
+ [attr.aria-label]="ariaLabel() || label() || 'Progress'"
2612
2631
  [attr.aria-valuenow]="indeterminate() ? null : clamped()"
2613
2632
  [attr.aria-valuetext]="valueDescription()"
2614
2633
  [attr.aria-valuemin]="indeterminate() ? null : 0"
@@ -2627,20 +2646,28 @@ class StrctProgress {
2627
2646
  <div class="strct-progress__fill" [style.width.%]="clamped()"></div>
2628
2647
  }
2629
2648
  </div>
2649
+ @if (showValue() && valuePosition() === 'end') {
2650
+ <!-- A bar in a cell wants its number beside the track, not above it. -->
2651
+ <span class="strct-progress__value strct-progress__value--end">{{
2652
+ valueText() || clamped() + '%'
2653
+ }}</span>
2654
+ }
2630
2655
  @if (caption()) {
2631
- <p class="strct-progress__caption">{{ caption() }}</p>
2656
+ <p class="strct-progress__caption strct-progress__caption--{{ captionStatus() ?? 'none' }}">
2657
+ {{ caption() }}
2658
+ </p>
2632
2659
  }
2633
- `, isInline: true, styles: [".strct-progress{display:block}.strct-progress__row{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-2);margin-block-end:4px;font-size:var(--text-sm)}.strct-progress__label{color:var(--t2);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.strct-progress__value{color:var(--t1);font-variant-numeric:tabular-nums;white-space:nowrap}.strct-progress__caption{margin:4px 0 0;font-size:var(--text-sm);line-height:1.5;color:var(--t3)}.strct-progress__track{position:relative;display:flex;height:6px;border-radius:var(--radius-sm);background:var(--strct-progress-track, color-mix(in srgb, var(--t1) 12%, transparent));box-shadow:inset 0 0 0 1px var(--b2);overflow:hidden}.strct-progress__fill{height:100%;border-radius:var(--radius-sm);background:var(--acc);transition:width .3s ease}.strct-progress--neutral .strct-progress__fill{background:var(--t3)}.strct-progress--success .strct-progress__fill{background:var(--success)}.strct-progress--warning .strct-progress__fill{background:var(--warning)}.strct-progress--critical .strct-progress__fill{background:var(--critical)}.strct-progress .strct-progress__fill--neutral{background:var(--t3)}.strct-progress .strct-progress__fill--accent{background:var(--acc)}.strct-progress .strct-progress__fill--success{background:var(--success)}.strct-progress .strct-progress__fill--warning{background:var(--warning)}.strct-progress .strct-progress__fill--critical{background:var(--critical)}.strct-progress__track .strct-progress__fill+.strct-progress__fill{border-start-start-radius:0;border-end-start-radius:0}.strct-progress .strct-progress__fill--indeterminate{width:35%;animation:strct-progress-sweep 1.1s ease-in-out infinite}@keyframes strct-progress-sweep{0%{transform:translate(-120%)}to{transform:translate(340%)}}@media(prefers-reduced-motion:reduce){.strct-progress .strct-progress__fill--indeterminate{width:100%;animation:none;background:repeating-linear-gradient(135deg,var(--acc) 0 6px,color-mix(in srgb,var(--acc) 45%,transparent) 6px 12px)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
2660
+ `, isInline: true, styles: [".strct-progress{display:block}.strct-progress__row{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-2);margin-block-end:4px;font-size:var(--text-sm)}.strct-progress__label{color:var(--t2);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.strct-progress__value{color:var(--t1);font-variant-numeric:tabular-nums;white-space:nowrap}.strct-progress__caption{margin:4px 0 0;font-size:var(--text-sm);line-height:1.5;color:var(--t3)}.strct-progress__caption--accent{color:var(--acc)}.strct-progress__caption--success{color:var(--success)}.strct-progress__caption--warning{color:var(--warning)}.strct-progress__caption--critical{color:var(--critical)}.strct-progress--endvalue{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap}.strct-progress--endvalue .strct-progress__track{flex:1;min-width:0}.strct-progress__value--end{flex:none;font-size:var(--text-sm);color:var(--t2);font-variant-numeric:tabular-nums}.strct-progress--endvalue .strct-progress__caption,.strct-progress--endvalue .strct-progress__row{flex-basis:100%}.strct-progress__track{position:relative;display:flex;height:6px;border-radius:var(--radius-sm);background:var(--strct-progress-track, color-mix(in srgb, var(--t1) 12%, transparent));box-shadow:inset 0 0 0 1px var(--b2);overflow:hidden}.strct-progress__fill{height:100%;border-radius:var(--radius-sm);background:var(--acc);transition:width .3s ease}.strct-progress--neutral .strct-progress__fill{background:var(--t3)}.strct-progress--success .strct-progress__fill{background:var(--success)}.strct-progress--warning .strct-progress__fill{background:var(--warning)}.strct-progress--critical .strct-progress__fill{background:var(--critical)}.strct-progress .strct-progress__fill--neutral{background:var(--t3)}.strct-progress .strct-progress__fill--accent{background:var(--acc)}.strct-progress .strct-progress__fill--success{background:var(--success)}.strct-progress .strct-progress__fill--warning{background:var(--warning)}.strct-progress .strct-progress__fill--critical{background:var(--critical)}.strct-progress__track .strct-progress__fill+.strct-progress__fill{border-start-start-radius:0;border-end-start-radius:0}.strct-progress .strct-progress__fill--indeterminate{width:35%;animation:strct-progress-sweep 1.1s ease-in-out infinite}@keyframes strct-progress-sweep{0%{transform:translate(-120%)}to{transform:translate(340%)}}@media(prefers-reduced-motion:reduce){.strct-progress .strct-progress__fill--indeterminate{width:100%;animation:none;background:repeating-linear-gradient(135deg,var(--acc) 0 6px,color-mix(in srgb,var(--acc) 45%,transparent) 6px 12px)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
2634
2661
  }
2635
2662
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctProgress, decorators: [{
2636
2663
  type: Component,
2637
2664
  args: [{ selector: 'strct-progress', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: `
2638
- @if (visibleLabel() || showValue()) {
2665
+ @if (visibleLabel() || (showValue() && valuePosition() === 'top')) {
2639
2666
  <div class="strct-progress__row">
2640
2667
  @if (visibleLabel()) {
2641
2668
  <span class="strct-progress__label">{{ label() }}</span>
2642
2669
  }
2643
- @if (showValue()) {
2670
+ @if (showValue() && valuePosition() === 'top') {
2644
2671
  <span class="strct-progress__value">{{ valueText() || clamped() + '%' }}</span>
2645
2672
  }
2646
2673
  </div>
@@ -2648,7 +2675,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
2648
2675
  <div
2649
2676
  class="strct-progress__track"
2650
2677
  role="progressbar"
2651
- [attr.aria-label]="label() || 'Progress'"
2678
+ [attr.aria-label]="ariaLabel() || label() || 'Progress'"
2652
2679
  [attr.aria-valuenow]="indeterminate() ? null : clamped()"
2653
2680
  [attr.aria-valuetext]="valueDescription()"
2654
2681
  [attr.aria-valuemin]="indeterminate() ? null : 0"
@@ -2667,8 +2694,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
2667
2694
  <div class="strct-progress__fill" [style.width.%]="clamped()"></div>
2668
2695
  }
2669
2696
  </div>
2697
+ @if (showValue() && valuePosition() === 'end') {
2698
+ <!-- A bar in a cell wants its number beside the track, not above it. -->
2699
+ <span class="strct-progress__value strct-progress__value--end">{{
2700
+ valueText() || clamped() + '%'
2701
+ }}</span>
2702
+ }
2670
2703
  @if (caption()) {
2671
- <p class="strct-progress__caption">{{ caption() }}</p>
2704
+ <p class="strct-progress__caption strct-progress__caption--{{ captionStatus() ?? 'none' }}">
2705
+ {{ caption() }}
2706
+ </p>
2672
2707
  }
2673
2708
  `, host: {
2674
2709
  class: 'strct-progress',
@@ -2676,8 +2711,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
2676
2711
  '[class.strct-progress--success]': "resolvedStatus() === 'success'",
2677
2712
  '[class.strct-progress--warning]': "resolvedStatus() === 'warning'",
2678
2713
  '[class.strct-progress--critical]': "resolvedStatus() === 'critical'",
2679
- }, styles: [".strct-progress{display:block}.strct-progress__row{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-2);margin-block-end:4px;font-size:var(--text-sm)}.strct-progress__label{color:var(--t2);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.strct-progress__value{color:var(--t1);font-variant-numeric:tabular-nums;white-space:nowrap}.strct-progress__caption{margin:4px 0 0;font-size:var(--text-sm);line-height:1.5;color:var(--t3)}.strct-progress__track{position:relative;display:flex;height:6px;border-radius:var(--radius-sm);background:var(--strct-progress-track, color-mix(in srgb, var(--t1) 12%, transparent));box-shadow:inset 0 0 0 1px var(--b2);overflow:hidden}.strct-progress__fill{height:100%;border-radius:var(--radius-sm);background:var(--acc);transition:width .3s ease}.strct-progress--neutral .strct-progress__fill{background:var(--t3)}.strct-progress--success .strct-progress__fill{background:var(--success)}.strct-progress--warning .strct-progress__fill{background:var(--warning)}.strct-progress--critical .strct-progress__fill{background:var(--critical)}.strct-progress .strct-progress__fill--neutral{background:var(--t3)}.strct-progress .strct-progress__fill--accent{background:var(--acc)}.strct-progress .strct-progress__fill--success{background:var(--success)}.strct-progress .strct-progress__fill--warning{background:var(--warning)}.strct-progress .strct-progress__fill--critical{background:var(--critical)}.strct-progress__track .strct-progress__fill+.strct-progress__fill{border-start-start-radius:0;border-end-start-radius:0}.strct-progress .strct-progress__fill--indeterminate{width:35%;animation:strct-progress-sweep 1.1s ease-in-out infinite}@keyframes strct-progress-sweep{0%{transform:translate(-120%)}to{transform:translate(340%)}}@media(prefers-reduced-motion:reduce){.strct-progress .strct-progress__fill--indeterminate{width:100%;animation:none;background:repeating-linear-gradient(135deg,var(--acc) 0 6px,color-mix(in srgb,var(--acc) 45%,transparent) 6px 12px)}}\n"] }]
2680
- }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], visibleLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleLabel", required: false }] }], showValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValue", required: false }] }], valueText: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueText", required: false }] }], caption: [{ type: i0.Input, args: [{ isSignal: true, alias: "caption", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }], segments: [{ type: i0.Input, args: [{ isSignal: true, alias: "segments", required: false }] }], thresholds: [{ type: i0.Input, args: [{ isSignal: true, alias: "thresholds", required: false }] }] } });
2714
+ '[class.strct-progress--endvalue]': "showValue() && valuePosition() === 'end'",
2715
+ }, styles: [".strct-progress{display:block}.strct-progress__row{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-2);margin-block-end:4px;font-size:var(--text-sm)}.strct-progress__label{color:var(--t2);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.strct-progress__value{color:var(--t1);font-variant-numeric:tabular-nums;white-space:nowrap}.strct-progress__caption{margin:4px 0 0;font-size:var(--text-sm);line-height:1.5;color:var(--t3)}.strct-progress__caption--accent{color:var(--acc)}.strct-progress__caption--success{color:var(--success)}.strct-progress__caption--warning{color:var(--warning)}.strct-progress__caption--critical{color:var(--critical)}.strct-progress--endvalue{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap}.strct-progress--endvalue .strct-progress__track{flex:1;min-width:0}.strct-progress__value--end{flex:none;font-size:var(--text-sm);color:var(--t2);font-variant-numeric:tabular-nums}.strct-progress--endvalue .strct-progress__caption,.strct-progress--endvalue .strct-progress__row{flex-basis:100%}.strct-progress__track{position:relative;display:flex;height:6px;border-radius:var(--radius-sm);background:var(--strct-progress-track, color-mix(in srgb, var(--t1) 12%, transparent));box-shadow:inset 0 0 0 1px var(--b2);overflow:hidden}.strct-progress__fill{height:100%;border-radius:var(--radius-sm);background:var(--acc);transition:width .3s ease}.strct-progress--neutral .strct-progress__fill{background:var(--t3)}.strct-progress--success .strct-progress__fill{background:var(--success)}.strct-progress--warning .strct-progress__fill{background:var(--warning)}.strct-progress--critical .strct-progress__fill{background:var(--critical)}.strct-progress .strct-progress__fill--neutral{background:var(--t3)}.strct-progress .strct-progress__fill--accent{background:var(--acc)}.strct-progress .strct-progress__fill--success{background:var(--success)}.strct-progress .strct-progress__fill--warning{background:var(--warning)}.strct-progress .strct-progress__fill--critical{background:var(--critical)}.strct-progress__track .strct-progress__fill+.strct-progress__fill{border-start-start-radius:0;border-end-start-radius:0}.strct-progress .strct-progress__fill--indeterminate{width:35%;animation:strct-progress-sweep 1.1s ease-in-out infinite}@keyframes strct-progress-sweep{0%{transform:translate(-120%)}to{transform:translate(340%)}}@media(prefers-reduced-motion:reduce){.strct-progress .strct-progress__fill--indeterminate{width:100%;animation:none;background:repeating-linear-gradient(135deg,var(--acc) 0 6px,color-mix(in srgb,var(--acc) 45%,transparent) 6px 12px)}}\n"] }]
2716
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], visibleLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleLabel", required: false }] }], showValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValue", required: false }] }], valueText: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueText", required: false }] }], caption: [{ type: i0.Input, args: [{ isSignal: true, alias: "caption", required: false }] }], captionStatus: [{ type: i0.Input, args: [{ isSignal: true, alias: "captionStatus", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], valuePosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "valuePosition", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }], segments: [{ type: i0.Input, args: [{ isSignal: true, alias: "segments", required: false }] }], thresholds: [{ type: i0.Input, args: [{ isSignal: true, alias: "thresholds", required: false }] }] } });
2681
2717
 
2682
2718
  /** Indeterminate loading ring. `<strct-spinner size="sm" />`. */
2683
2719
  class StrctSpinner {
@@ -19633,16 +19669,33 @@ class StrctHero {
19633
19669
  /** Tighter padding for secondary placements. */
19634
19670
  dense = input(false, { ...(ngDevMode ? { debugName: "dense" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
19635
19671
  /**
19636
- * Opt into a polite live region (role="status") for banners whose content
19637
- * updates after load; static banners should leave this off. Critical heroes
19638
- * are always role="alert" regardless.
19672
+ * How the banner announces itself. `true` opts a non-critical hero into a
19673
+ * polite live region (`role="status"`), for content that updates after load.
19674
+ * `'polite'` and `'assertive'` say it outright, whatever the status — a page
19675
+ * that renders its verdict on navigation wants `'polite'`, so a critical
19676
+ * hero does not interrupt on every load.
19639
19677
  */
19640
- live = input(false, { ...(ngDevMode ? { debugName: "live" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
19678
+ live = input(false, { ...(ngDevMode ? { debugName: "live" } : /* istanbul ignore next */ {}), transform: (v) => v === 'assertive' || v === 'polite' ? v : booleanAttribute(v) });
19679
+ /**
19680
+ * A critical hero interrupts by default, because it usually appears in
19681
+ * answer to something the user did. A page that renders a verdict on
19682
+ * navigation would interrupt on every load instead, so `live="polite"` makes
19683
+ * it a `status`; `live="assertive"` asks for `alert` whatever the status.
19684
+ */
19685
+ liveRole = computed(() => {
19686
+ const live = this.live();
19687
+ if (live === 'polite')
19688
+ return 'status';
19689
+ if (live === 'assertive')
19690
+ return 'alert';
19691
+ return this.status() === 'critical' ? 'alert' : live ? 'status' : null;
19692
+ }, /* @ts-ignore */
19693
+ ...(ngDevMode ? [{ debugName: "liveRole" }] : /* istanbul ignore next */ []));
19641
19694
  headingId = `strct-hero-${++heroCounter}`;
19642
19695
  resolvedIcon = computed(() => this.icon() || DEFAULT_ICON[this.status()], /* @ts-ignore */
19643
19696
  ...(ngDevMode ? [{ debugName: "resolvedIcon" }] : /* istanbul ignore next */ []));
19644
19697
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctHero, deps: [], target: i0.ɵɵFactoryTarget.Component });
19645
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: StrctHero, isStandalone: true, selector: "strct-hero", inputs: { status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: true, transformFunction: null }, dense: { classPropertyName: "dense", publicName: "dense", isSignal: true, isRequired: false, transformFunction: null }, live: { classPropertyName: "live", publicName: "live", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.strct-hero--accent": "status() === 'accent'", "class.strct-hero--success": "status() === 'success'", "class.strct-hero--warning": "status() === 'warning'", "class.strct-hero--critical": "status() === 'critical'", "class.strct-hero--dense": "dense()", "attr.role": "status() === 'critical' ? 'alert' : live() ? 'status' : null", "attr.aria-labelledby": "headingId" }, classAttribute: "strct-hero" }, ngImport: i0, template: `
19698
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: StrctHero, isStandalone: true, selector: "strct-hero", inputs: { status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: true, transformFunction: null }, dense: { classPropertyName: "dense", publicName: "dense", isSignal: true, isRequired: false, transformFunction: null }, live: { classPropertyName: "live", publicName: "live", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.strct-hero--accent": "status() === 'accent'", "class.strct-hero--success": "status() === 'success'", "class.strct-hero--warning": "status() === 'warning'", "class.strct-hero--critical": "status() === 'critical'", "class.strct-hero--dense": "dense()", "attr.role": "liveRole()", "attr.aria-labelledby": "headingId" }, classAttribute: "strct-hero" }, ngImport: i0, template: `
19646
19699
  <span class="strct-hero__chip" aria-hidden="true">
19647
19700
  <strct-icon [name]="resolvedIcon()" [size]="dense() ? 16 : 18" />
19648
19701
  </span>
@@ -19681,7 +19734,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
19681
19734
  '[class.strct-hero--warning]': "status() === 'warning'",
19682
19735
  '[class.strct-hero--critical]': "status() === 'critical'",
19683
19736
  '[class.strct-hero--dense]': 'dense()',
19684
- '[attr.role]': "status() === 'critical' ? 'alert' : live() ? 'status' : null",
19737
+ '[attr.role]': 'liveRole()',
19685
19738
  '[attr.aria-labelledby]': 'headingId',
19686
19739
  }, styles: [".strct-hero{display:flex;align-items:flex-start;flex-wrap:wrap;gap:var(--space-3);padding:var(--space-4) var(--space-5);border-radius:var(--radius-lg);background:var(--bg-1);border:1px solid var(--b2);border-inline-start:3px solid var(--b3)}.strct-hero--dense{padding:var(--space-3) var(--space-4);gap:var(--space-2)}.strct-hero__chip{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:50%;flex-shrink:0;background:var(--bg-a);color:var(--t2)}.strct-hero--dense .strct-hero__chip{width:28px;height:28px}.strct-hero__text{flex:1 1 280px;min-width:0;display:flex;flex-direction:column;gap:3px}.strct-hero__heading{margin:0;font-size:var(--text-xl);font-weight:650;letter-spacing:-.01em;color:var(--t1);line-height:var(--leading-tight)}.strct-hero--dense .strct-hero__heading{font-size:var(--text-lg)}.strct-hero__desc{font-size:var(--text-md);color:var(--t2);line-height:var(--leading-normal)}.strct-hero__desc:empty{display:none}.strct-hero__aside{display:flex;flex-direction:column;align-items:flex-end;gap:var(--space-2);margin-inline-start:auto}.strct-hero__meta,.strct-hero__actions{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-2);justify-content:flex-end}.strct-hero__meta:empty,.strct-hero__actions:empty{display:none}.strct-hero__aside:not(:has(*:not(:empty))){display:none}.strct-hero--accent{border-inline-start-color:var(--acc)}.strct-hero--accent .strct-hero__chip{background:var(--acc);color:var(--inv)}.strct-hero--success{border-inline-start-color:var(--success)}.strct-hero--success .strct-hero__chip{background:var(--success);color:var(--inv)}.strct-hero--warning{border-inline-start-color:var(--warning)}.strct-hero--warning .strct-hero__chip{background:var(--warning);color:var(--inv)}.strct-hero--critical{border-inline-start-color:var(--critical)}.strct-hero--critical .strct-hero__chip{background:var(--critical);color:var(--inv)}@media(max-width:560px){.strct-hero__aside{margin-inline-start:0;align-items:stretch;width:100%}.strct-hero__meta,.strct-hero__actions{justify-content:flex-start}}\n"] }]
19687
19740
  }], propDecorators: { status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: true }] }], dense: [{ type: i0.Input, args: [{ isSignal: true, alias: "dense", required: false }] }], live: [{ type: i0.Input, args: [{ isSignal: true, alias: "live", required: false }] }] } });
@@ -20289,6 +20342,13 @@ class StrctEmptyState {
20289
20342
  ...(ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []));
20290
20343
  title = input.required(/* @ts-ignore */
20291
20344
  ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
20345
+ /**
20346
+ * Which heading element the title is. `null` renders a `<p>` — what a
20347
+ * loading state inside a card wants, since it should not add a heading to
20348
+ * the page outline.
20349
+ */
20350
+ titleLevel = input(3, /* @ts-ignore */
20351
+ ...(ngDevMode ? [{ debugName: "titleLevel" }] : /* istanbul ignore next */ []));
20292
20352
  /**
20293
20353
  * `sm` is the inline row a 240px frame wants: a 16px icon with the title and
20294
20354
  * description on one line. A page-sized empty state stays `md`.
@@ -20302,7 +20362,7 @@ class StrctEmptyState {
20302
20362
  toneClass = computed(() => this.tone() || VARIANTS[this.variant()].tone, /* @ts-ignore */
20303
20363
  ...(ngDevMode ? [{ debugName: "toneClass" }] : /* istanbul ignore next */ []));
20304
20364
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctEmptyState, deps: [], target: i0.ɵɵFactoryTarget.Component });
20305
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctEmptyState, isStandalone: true, selector: "strct-empty-state", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.strct-empty--sm": "size() === 'sm'", "attr.aria-busy": "variant() === 'loading' ? 'true' : null" }, classAttribute: "strct-empty" }, ngImport: i0, template: `
20365
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctEmptyState, isStandalone: true, selector: "strct-empty-state", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, titleLevel: { classPropertyName: "titleLevel", publicName: "titleLevel", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.strct-empty--sm": "size() === 'sm'", "attr.aria-busy": "variant() === 'loading' ? 'true' : null" }, classAttribute: "strct-empty" }, ngImport: i0, template: `
20306
20366
  <span class="strct-empty__icon strct-empty__icon--{{ toneClass() }}">
20307
20367
  @if (variant() === 'loading') {
20308
20368
  <strct-spinner [size]="size() === 'sm' ? 'sm' : 'md'" [label]="title()" />
@@ -20314,12 +20374,33 @@ class StrctEmptyState {
20314
20374
  />
20315
20375
  }
20316
20376
  </span>
20317
- <h3 class="strct-empty__title">{{ title() }}</h3>
20377
+ <!-- A zero state on a page is a heading; a loading state inside a card is
20378
+ not, and an outline that gains an h3 while data loads is noise. -->
20379
+ @switch (titleLevel()) {
20380
+ @case (2) {
20381
+ <h2 class="strct-empty__title">{{ title() }}</h2>
20382
+ }
20383
+ @case (3) {
20384
+ <h3 class="strct-empty__title">{{ title() }}</h3>
20385
+ }
20386
+ @case (4) {
20387
+ <h4 class="strct-empty__title">{{ title() }}</h4>
20388
+ }
20389
+ @case (5) {
20390
+ <h5 class="strct-empty__title">{{ title() }}</h5>
20391
+ }
20392
+ @case (6) {
20393
+ <h6 class="strct-empty__title">{{ title() }}</h6>
20394
+ }
20395
+ @default {
20396
+ <p class="strct-empty__title">{{ title() }}</p>
20397
+ }
20398
+ }
20318
20399
  @if (description()) {
20319
20400
  <p class="strct-empty__desc">{{ description() }}</p>
20320
20401
  }
20321
20402
  <div class="strct-empty__actions"><ng-content /></div>
20322
- `, 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 });
20403
+ `, 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:inherit;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 });
20323
20404
  }
20324
20405
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctEmptyState, decorators: [{
20325
20406
  type: Component,
@@ -20335,7 +20416,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
20335
20416
  />
20336
20417
  }
20337
20418
  </span>
20338
- <h3 class="strct-empty__title">{{ title() }}</h3>
20419
+ <!-- A zero state on a page is a heading; a loading state inside a card is
20420
+ not, and an outline that gains an h3 while data loads is noise. -->
20421
+ @switch (titleLevel()) {
20422
+ @case (2) {
20423
+ <h2 class="strct-empty__title">{{ title() }}</h2>
20424
+ }
20425
+ @case (3) {
20426
+ <h3 class="strct-empty__title">{{ title() }}</h3>
20427
+ }
20428
+ @case (4) {
20429
+ <h4 class="strct-empty__title">{{ title() }}</h4>
20430
+ }
20431
+ @case (5) {
20432
+ <h5 class="strct-empty__title">{{ title() }}</h5>
20433
+ }
20434
+ @case (6) {
20435
+ <h6 class="strct-empty__title">{{ title() }}</h6>
20436
+ }
20437
+ @default {
20438
+ <p class="strct-empty__title">{{ title() }}</p>
20439
+ }
20440
+ }
20339
20441
  @if (description()) {
20340
20442
  <p class="strct-empty__desc">{{ description() }}</p>
20341
20443
  }
@@ -20344,8 +20446,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
20344
20446
  class: 'strct-empty',
20345
20447
  '[class.strct-empty--sm]': "size() === 'sm'",
20346
20448
  '[attr.aria-busy]': "variant() === 'loading' ? 'true' : null",
20347
- }, 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"] }]
20348
- }], 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 }] }] } });
20449
+ }, 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:inherit;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"] }]
20450
+ }], 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 }] }], titleLevel: [{ type: i0.Input, args: [{ isSignal: true, alias: "titleLevel", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }] } });
20349
20451
 
20350
20452
  /**
20351
20453
  * Unit formatting for infrastructure consoles — bytes, rates, durations and
@@ -24050,6 +24152,13 @@ class StrctMediaFrame {
24050
24152
  /** The frame's aspect ratio, as a CSS `aspect-ratio` value. */
24051
24153
  ratio = input('4 / 3', /* @ts-ignore */
24052
24154
  ...(ngDevMode ? [{ debugName: "ratio" }] : /* istanbul ignore next */ []));
24155
+ /**
24156
+ * How the media fills the frame. `cover` crops to fill, as today; `contain`
24157
+ * shows all of it — what a console thumbnail needs, since the corner it
24158
+ * would crop is where the error is.
24159
+ */
24160
+ fit = input('cover', /* @ts-ignore */
24161
+ ...(ngDevMode ? [{ debugName: "fit" }] : /* istanbul ignore next */ []));
24053
24162
  /** What the frame shows: the projected picture, or why there is none. */
24054
24163
  state = input('content', /* @ts-ignore */
24055
24164
  ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
@@ -24075,7 +24184,7 @@ class StrctMediaFrame {
24075
24184
  }, /* @ts-ignore */
24076
24185
  ...(ngDevMode ? [{ debugName: "iconName" }] : /* istanbul ignore next */ []));
24077
24186
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctMediaFrame, deps: [], target: i0.ɵɵFactoryTarget.Component });
24078
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctMediaFrame, isStandalone: true, selector: "strct-media-frame", inputs: { ratio: { classPropertyName: "ratio", publicName: "ratio", isSignal: true, isRequired: false, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, activateLabel: { classPropertyName: "activateLabel", publicName: "activateLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activated: "activated" }, host: { properties: { "style.aspect-ratio": "ratio()", "attr.data-state": "state()", "class.strct-mf--interactive": "interactive()" }, classAttribute: "strct-mf" }, ngImport: i0, template: `
24187
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctMediaFrame, isStandalone: true, selector: "strct-media-frame", inputs: { ratio: { classPropertyName: "ratio", publicName: "ratio", isSignal: true, isRequired: false, transformFunction: null }, fit: { classPropertyName: "fit", publicName: "fit", isSignal: true, isRequired: false, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, activateLabel: { classPropertyName: "activateLabel", publicName: "activateLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activated: "activated" }, host: { properties: { "style.aspect-ratio": "ratio()", "attr.data-state": "state()", "class.strct-mf--interactive": "interactive()", "class.strct-mf--contain": "fit() === 'contain'" }, classAttribute: "strct-mf" }, ngImport: i0, template: `
24079
24188
  @if (state() === 'content') {
24080
24189
  <ng-content />
24081
24190
  } @else {
@@ -24098,7 +24207,7 @@ class StrctMediaFrame {
24098
24207
  (click)="activated.emit()"
24099
24208
  ></button>
24100
24209
  }
24101
- `, isInline: true, styles: [".strct-mf{position:relative;display:flex;align-items:center;justify-content:center;overflow:hidden;border:1px solid var(--b2);border-radius:var(--radius-md);background:var(--bg-3);min-width:0}.strct-mf>img,.strct-mf>video,.strct-mf>canvas{width:100%;height:100%;object-fit:cover;display:block}.strct-mf[data-state=off]{background:#000}.strct-mf__placeholder{display:flex;flex-direction:column;align-items:center;gap:6px;padding:var(--space-2);color:var(--t3);text-align:center}.strct-mf[data-state=off] .strct-mf__placeholder{color:#fff9}.strct-mf[data-state=error] .strct-mf__placeholder{color:var(--critical)}.strct-mf__msg{font-size:var(--text-sm);line-height:1.35}.strct-mf__hit{position:absolute;inset:-1px;padding:0;border:0;background:none;cursor:pointer}.strct-mf__hit:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}.strct-mf--interactive:hover{border-color:var(--b3)}\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 });
24210
+ `, isInline: true, styles: [".strct-mf{position:relative;display:flex;align-items:center;justify-content:center;overflow:hidden;border:1px solid var(--b2);border-radius:var(--radius-md);background:var(--bg-3);min-width:0}.strct-mf>img,.strct-mf>video,.strct-mf>canvas{width:100%;height:100%;object-fit:cover;display:block}.strct-mf--contain>img,.strct-mf--contain>video,.strct-mf--contain>canvas{object-fit:contain}.strct-mf[data-state=off]{background:#000}.strct-mf__placeholder{display:flex;flex-direction:column;align-items:center;gap:6px;padding:var(--space-2);color:var(--t3);text-align:center}.strct-mf[data-state=off] .strct-mf__placeholder{color:#fff9}.strct-mf[data-state=error] .strct-mf__placeholder{color:var(--critical)}.strct-mf__msg{font-size:var(--text-sm);line-height:1.35}.strct-mf__hit{position:absolute;inset:-1px;padding:0;border:0;background:none;cursor:pointer}.strct-mf__hit:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}.strct-mf--interactive:hover{border-color:var(--b3)}\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 });
24102
24211
  }
24103
24212
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctMediaFrame, decorators: [{
24104
24213
  type: Component,
@@ -24130,8 +24239,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
24130
24239
  '[style.aspect-ratio]': 'ratio()',
24131
24240
  '[attr.data-state]': 'state()',
24132
24241
  '[class.strct-mf--interactive]': 'interactive()',
24133
- }, styles: [".strct-mf{position:relative;display:flex;align-items:center;justify-content:center;overflow:hidden;border:1px solid var(--b2);border-radius:var(--radius-md);background:var(--bg-3);min-width:0}.strct-mf>img,.strct-mf>video,.strct-mf>canvas{width:100%;height:100%;object-fit:cover;display:block}.strct-mf[data-state=off]{background:#000}.strct-mf__placeholder{display:flex;flex-direction:column;align-items:center;gap:6px;padding:var(--space-2);color:var(--t3);text-align:center}.strct-mf[data-state=off] .strct-mf__placeholder{color:#fff9}.strct-mf[data-state=error] .strct-mf__placeholder{color:var(--critical)}.strct-mf__msg{font-size:var(--text-sm);line-height:1.35}.strct-mf__hit{position:absolute;inset:-1px;padding:0;border:0;background:none;cursor:pointer}.strct-mf__hit:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}.strct-mf--interactive:hover{border-color:var(--b3)}\n"] }]
24134
- }], propDecorators: { ratio: [{ type: i0.Input, args: [{ isSignal: true, alias: "ratio", required: false }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], activateLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "activateLabel", required: false }] }], activated: [{ type: i0.Output, args: ["activated"] }] } });
24242
+ '[class.strct-mf--contain]': "fit() === 'contain'",
24243
+ }, styles: [".strct-mf{position:relative;display:flex;align-items:center;justify-content:center;overflow:hidden;border:1px solid var(--b2);border-radius:var(--radius-md);background:var(--bg-3);min-width:0}.strct-mf>img,.strct-mf>video,.strct-mf>canvas{width:100%;height:100%;object-fit:cover;display:block}.strct-mf--contain>img,.strct-mf--contain>video,.strct-mf--contain>canvas{object-fit:contain}.strct-mf[data-state=off]{background:#000}.strct-mf__placeholder{display:flex;flex-direction:column;align-items:center;gap:6px;padding:var(--space-2);color:var(--t3);text-align:center}.strct-mf[data-state=off] .strct-mf__placeholder{color:#fff9}.strct-mf[data-state=error] .strct-mf__placeholder{color:var(--critical)}.strct-mf__msg{font-size:var(--text-sm);line-height:1.35}.strct-mf__hit{position:absolute;inset:-1px;padding:0;border:0;background:none;cursor:pointer}.strct-mf__hit:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}.strct-mf--interactive:hover{border-color:var(--b3)}\n"] }]
24244
+ }], propDecorators: { ratio: [{ type: i0.Input, args: [{ isSignal: true, alias: "ratio", required: false }] }], fit: [{ type: i0.Input, args: [{ isSignal: true, alias: "fit", required: false }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], activateLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "activateLabel", required: false }] }], activated: [{ type: i0.Output, args: ["activated"] }] } });
24135
24245
 
24136
24246
  const WINDOW_LABELS = {
24137
24247
  minimize: 'Minimize',
@@ -24859,6 +24969,11 @@ class StrctChatComposer {
24859
24969
  ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
24860
24970
  /** Disabled while the assistant is busy, say. */
24861
24971
  disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
24972
+ /**
24973
+ * Only the send button is disabled: the reader may draft their next question
24974
+ * while a reply is still streaming. `disabled` stops the typing as well.
24975
+ */
24976
+ sendDisabled = input(false, { ...(ngDevMode ? { debugName: "sendDisabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
24862
24977
  /** How tall the box grows before it scrolls. */
24863
24978
  maxRows = input(8, /* @ts-ignore */
24864
24979
  ...(ngDevMode ? [{ debugName: "maxRows" }] : /* istanbul ignore next */ []));
@@ -24891,7 +25006,7 @@ class StrctChatComposer {
24891
25006
  }
24892
25007
  submit() {
24893
25008
  const text = this.value().trim();
24894
- if (!text || this.disabled())
25009
+ if (!text || this.disabled() || this.sendDisabled())
24895
25010
  return;
24896
25011
  this.send.emit(text);
24897
25012
  this.value.set('');
@@ -24903,7 +25018,7 @@ class StrctChatComposer {
24903
25018
  }
24904
25019
  }
24905
25020
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctChatComposer, deps: [], target: i0.ɵɵFactoryTarget.Component });
24906
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: StrctChatComposer, isStandalone: true, selector: "strct-chat-composer", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null }, sendLabel: { classPropertyName: "sendLabel", publicName: "sendLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", send: "send" }, host: { classAttribute: "strct-composer" }, ngImport: i0, template: `
25021
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: StrctChatComposer, isStandalone: true, selector: "strct-chat-composer", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, sendDisabled: { classPropertyName: "sendDisabled", publicName: "sendDisabled", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null }, sendLabel: { classPropertyName: "sendLabel", publicName: "sendLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", send: "send" }, host: { classAttribute: "strct-composer" }, ngImport: i0, template: `
24907
25022
  <label class="strct-composer__label" [attr.for]="inputId">{{ label() }}</label>
24908
25023
  <div class="strct-composer__box">
24909
25024
  <textarea
@@ -24923,7 +25038,7 @@ class StrctChatComposer {
24923
25038
  type="button"
24924
25039
  class="strct-composer__send"
24925
25040
  [attr.aria-label]="sendLabel()"
24926
- [disabled]="disabled() || !value().trim()"
25041
+ [disabled]="disabled() || sendDisabled() || !value().trim()"
24927
25042
  (click)="submit()"
24928
25043
  >
24929
25044
  <strct-icon strictName="arrowUp" [size]="15" [strokeWidth]="1.8" />
@@ -24953,14 +25068,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
24953
25068
  type="button"
24954
25069
  class="strct-composer__send"
24955
25070
  [attr.aria-label]="sendLabel()"
24956
- [disabled]="disabled() || !value().trim()"
25071
+ [disabled]="disabled() || sendDisabled() || !value().trim()"
24957
25072
  (click)="submit()"
24958
25073
  >
24959
25074
  <strct-icon strictName="arrowUp" [size]="15" [strokeWidth]="1.8" />
24960
25075
  </button>
24961
25076
  </div>
24962
25077
  `, host: { class: 'strct-composer' }, styles: [".strct-composer{display:block}.strct-composer__label{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.strct-composer__box{display:flex;align-items:flex-end;gap:4px;padding:4px 4px 4px var(--space-3);border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-2);transition:border-color .14s ease,box-shadow .14s ease}.strct-composer__box:focus-within{border-color:var(--acc50);box-shadow:0 0 0 3px var(--acc18);background:var(--bg-1)}.strct-composer__input{flex:1;min-width:0;border:0;background:none;resize:none;padding:6px 0;font-family:var(--font);font-size:13px;line-height:20px;color:var(--t1);overflow-y:auto}.strct-composer__input:focus{outline:none}.strct-composer__input::placeholder{color:var(--t3)}.strct-composer__send{display:inline-flex;align-items:center;justify-content:center;flex:none;width:28px;height:28px;border:0;border-radius:var(--radius-md);background:var(--acc);color:var(--inv);cursor:pointer}.strct-composer__send:disabled{opacity:var(--disabled-opacity);cursor:not-allowed}.strct-composer__send:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}\n"] }]
24963
- }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], sendLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendLabel", required: false }] }], send: [{ type: i0.Output, args: ["send"] }] } });
25078
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], sendDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendDisabled", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], sendLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendLabel", required: false }] }], send: [{ type: i0.Output, args: ["send"] }] } });
24964
25079
  let composerCounter = 0;
24965
25080
 
24966
25081
  /**
@@ -26381,6 +26496,14 @@ class StrctToolbar {
26381
26496
  const idx = items.indexOf(active);
26382
26497
  if (idx < 0)
26383
26498
  return; // focus is not on a toolbar control
26499
+ // A control that has opened something owns its own arrow keys: a select's
26500
+ // listbox, a menu, a tree inside a popover. The bar's roving must not take
26501
+ // them, or the list cannot be walked from the keyboard at all.
26502
+ if (active?.getAttribute('aria-expanded') === 'true')
26503
+ return;
26504
+ const target = event.target;
26505
+ if (target?.closest('[role=listbox], [role=menu], [role=dialog], [role=tree], [role=grid]'))
26506
+ return;
26384
26507
  const vertical = this.orientation() === 'vertical';
26385
26508
  const prevKey = vertical ? 'ArrowUp' : 'ArrowLeft';
26386
26509
  const nextKey = vertical ? 'ArrowDown' : 'ArrowRight';