@akcelik/strct 1.22.0 → 2.0.1

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.
@@ -1,5 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { OnDestroy, InjectionToken, Provider, TemplateRef, PipeTransform } from '@angular/core';
2
+ import { OnDestroy, ElementRef, InjectionToken, Provider, TemplateRef, PipeTransform } from '@angular/core';
3
3
  import { SafeHtml, SafeStyle } from '@angular/platform-browser';
4
4
  import { ControlValueAccessor } from '@angular/forms';
5
5
  import * as _akcelik_strct from '@akcelik/strct';
@@ -51,8 +51,11 @@ declare class StrctThemeService {
51
51
  /** Palette dots + light/dark pill, wired to {@link StrctThemeService}. */
52
52
  declare class StrctThemeSwitcher {
53
53
  protected readonly theme: StrctThemeService;
54
+ /** Labels for the Light / Dark mode buttons (localizable). */
55
+ readonly lightLabel: _angular_core.InputSignal<string>;
56
+ readonly darkLabel: _angular_core.InputSignal<string>;
54
57
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctThemeSwitcher, never>;
55
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctThemeSwitcher, "strct-theme-switcher", never, {}, {}, never, never, true, never>;
58
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctThemeSwitcher, "strct-theme-switcher", never, { "lightLabel": { "alias": "lightLabel"; "required": false; "isSignal": true; }; "darkLabel": { "alias": "darkLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
56
59
  }
57
60
 
58
61
  /**
@@ -379,10 +382,14 @@ declare class StrctOverlay implements OnDestroy {
379
382
  private readonly zone;
380
383
  /** Anchor element for positioning. */
381
384
  readonly anchor: _angular_core.InputSignal<HTMLElement>;
382
- /** Preferred placement relative to the anchor. */
385
+ /**
386
+ * Preferred placement relative to the anchor. `start`/`end` follow the
387
+ * anchor's text direction (mirrored under RTL); `left`/`right` are
388
+ * physical sides in every direction.
389
+ */
383
390
  readonly placement: _angular_core.InputSignal<StrctOverlayPlacement>;
384
391
  /** Match the panel width to the anchor (combobox / date / cascade fields). */
385
- readonly matchWidth: _angular_core.InputSignal<boolean>;
392
+ readonly matchWidth: _angular_core.InputSignalWithTransform<boolean, unknown>;
386
393
  /** Gap between anchor and panel in pixels. */
387
394
  readonly gap: _angular_core.InputSignal<number>;
388
395
  private readonly onScrollResize;
@@ -398,6 +405,8 @@ declare class StrctOverlay implements OnDestroy {
398
405
  /** Shared layout state between shell parts. */
399
406
  declare class StrctShellService {
400
407
  readonly mobileNavOpen: _angular_core.WritableSignal<boolean>;
408
+ /** Id of the vertical nav controlled by the header drawer toggle. */
409
+ readonly navId: string;
401
410
  }
402
411
  /**
403
412
  * Application frame: a full-viewport grid of header / body / footer rows.
@@ -413,9 +422,11 @@ declare class StrctShell {
413
422
  }
414
423
  /** Top application bar. Holds brand on the left and actions on the right. */
415
424
  declare class StrctHeader {
425
+ /** Accessible label of the mobile drawer toggle. */
426
+ readonly drawerToggleAriaLabel: _angular_core.InputSignal<string>;
416
427
  protected readonly shell: StrctShellService;
417
428
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctHeader, never>;
418
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctHeader, "strct-header", never, {}, {}, never, ["*"], true, never>;
429
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctHeader, "strct-header", never, { "drawerToggleAriaLabel": { "alias": "drawerToggleAriaLabel"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
419
430
  }
420
431
  /** Bottom status bar. */
421
432
  declare class StrctFooter {
@@ -426,6 +437,8 @@ declare class StrctFooter {
426
437
  /** Scrollable left sidebar surface. Holds the icon nav and/or a tree. */
427
438
  declare class StrctVerticalNav {
428
439
  protected readonly shell: StrctShellService;
440
+ /** Closes the mobile nav on Escape. */
441
+ protected onEscape(): void;
429
442
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctVerticalNav, never>;
430
443
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctVerticalNav, "strct-vertical-nav", never, {}, {}, never, ["*"], true, never>;
431
444
  }
@@ -437,9 +450,12 @@ declare class StrctNav {
437
450
  /** A single icon tab inside `<strct-nav>`. */
438
451
  declare class StrctNavItem {
439
452
  /** Whether the item is active / selected. */
440
- readonly active: _angular_core.InputSignal<boolean>;
453
+ readonly active: _angular_core.InputSignalWithTransform<boolean, unknown>;
441
454
  /** Label text. */
442
455
  readonly label: _angular_core.InputSignal<string>;
456
+ private readonly host;
457
+ /** Activates the item from the keyboard, like a native button. */
458
+ protected activate(event: Event): void;
443
459
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctNavItem, never>;
444
460
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctNavItem, "strct-nav-item", never, { "active": { "alias": "active"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
445
461
  }
@@ -491,9 +507,15 @@ declare class StrctRail {
491
507
  /** Collapsed (icon-only) state (two-way). */
492
508
  readonly collapsed: _angular_core.ModelSignal<boolean>;
493
509
  /** Show the collapse toggle at the foot of the rail. */
494
- readonly collapsible: _angular_core.InputSignal<boolean>;
510
+ readonly collapsible: _angular_core.InputSignalWithTransform<boolean, unknown>;
495
511
  /** Accessible label for the nav landmark. */
496
512
  readonly ariaLabel: _angular_core.InputSignal<string>;
513
+ /** Accessible label of the foot toggle when the rail is collapsed. */
514
+ readonly expandAriaLabel: _angular_core.InputSignal<string>;
515
+ /** Accessible label of the foot toggle when the rail is expanded. */
516
+ readonly collapseAriaLabel: _angular_core.InputSignal<string>;
517
+ /** Visible text of the foot toggle (expanded state). */
518
+ readonly collapseText: _angular_core.InputSignal<string>;
497
519
  /** Emitted when an item is chosen. */
498
520
  readonly select: _angular_core.OutputEmitterRef<StrctRailItem>;
499
521
  protected readonly topItems: _angular_core.Signal<StrctRailItem[]>;
@@ -507,7 +529,7 @@ declare class StrctRail {
507
529
  protected isActive(item: StrctRailItem, routerActive: boolean): boolean;
508
530
  protected pick(item: StrctRailItem, event?: MouseEvent): void;
509
531
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctRail, never>;
510
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctRail, "strct-rail", never, { "items": { "alias": "items"; "required": true; "isSignal": true; }; "activeId": { "alias": "activeId"; "required": false; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "activeId": "activeIdChange"; "collapsed": "collapsedChange"; "select": "select"; }, never, never, true, never>;
532
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctRail, "strct-rail", never, { "items": { "alias": "items"; "required": true; "isSignal": true; }; "activeId": { "alias": "activeId"; "required": false; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "expandAriaLabel": { "alias": "expandAriaLabel"; "required": false; "isSignal": true; }; "collapseAriaLabel": { "alias": "collapseAriaLabel"; "required": false; "isSignal": true; }; "collapseText": { "alias": "collapseText"; "required": false; "isSignal": true; }; }, { "activeId": "activeIdChange"; "collapsed": "collapsedChange"; "select": "select"; }, never, never, true, never>;
511
533
  }
512
534
 
513
535
  /**
@@ -618,10 +640,14 @@ declare class StrctTag {
618
640
  readonly status: _angular_core.InputSignal<StrctTagStatus>;
619
641
  /** Show a remove button. */
620
642
  readonly removable: _angular_core.InputSignalWithTransform<boolean, unknown>;
643
+ /** Hide the remove button (e.g. when the parent control is disabled). */
644
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
645
+ /** Accessible label for the remove button. */
646
+ readonly removeLabel: _angular_core.InputSignal<string>;
621
647
  /** Emitted when the user clicks the remove button. */
622
648
  readonly removed: _angular_core.OutputEmitterRef<void>;
623
649
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctTag, never>;
624
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctTag, "strct-tag", never, { "status": { "alias": "status"; "required": false; "isSignal": true; }; "removable": { "alias": "removable"; "required": false; "isSignal": true; }; }, { "removed": "removed"; }, never, ["*"], true, never>;
650
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctTag, "strct-tag", never, { "status": { "alias": "status"; "required": false; "isSignal": true; }; "removable": { "alias": "removable"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "removeLabel": { "alias": "removeLabel"; "required": false; "isSignal": true; }; }, { "removed": "removed"; }, never, ["*"], true, never>;
625
651
  }
626
652
 
627
653
  /** Avatar size variants. */
@@ -713,14 +739,20 @@ declare class StrctSpeedDial {
713
739
  private readonly host;
714
740
  /** Icon name. */
715
741
  readonly icon: _angular_core.InputSignal<string>;
742
+ /** Accessible name for the icon-only FAB. */
743
+ readonly ariaLabel: _angular_core.InputSignal<string>;
716
744
  /** Direction the actions fan out. */
717
745
  readonly direction: _angular_core.InputSignal<StrctSpeedDialDirection>;
718
746
  readonly open: _angular_core.WritableSignal<boolean>;
747
+ /** Trigger to hand focus back to on Escape close. */
748
+ private trigger;
719
749
  toggle(): void;
750
+ /** Activating a projected action closes the dial (the FAB toggles itself). */
751
+ protected onActionClick(): void;
720
752
  protected onDocClick(event: MouseEvent): void;
721
- protected onEscape(): void;
753
+ protected onEscape(event: Event): void;
722
754
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctSpeedDial, never>;
723
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctSpeedDial, "strct-speed-dial", never, { "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "direction": { "alias": "direction"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
755
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctSpeedDial, "strct-speed-dial", never, { "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "direction": { "alias": "direction"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
724
756
  }
725
757
 
726
758
  /**
@@ -793,6 +825,8 @@ declare class StrctAccordionPanel {
793
825
  readonly heading: _angular_core.InputSignal<string>;
794
826
  /** Whether the panel is open (two-way). */
795
827
  readonly expanded: _angular_core.ModelSignal<boolean>;
828
+ protected readonly bodyId: string;
829
+ protected readonly headId: string;
796
830
  toggle(): void;
797
831
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctAccordionPanel, never>;
798
832
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctAccordionPanel, "strct-accordion-panel", never, { "heading": { "alias": "heading"; "required": true; "isSignal": true; }; "expanded": { "alias": "expanded"; "required": false; "isSignal": true; }; }, { "expanded": "expandedChange"; }, never, ["*"], true, never>;
@@ -804,10 +838,20 @@ declare class StrctTab {
804
838
  readonly label: _angular_core.InputSignal<string>;
805
839
  /** Static disable flag. */
806
840
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
841
+ private readonly _id;
842
+ /** Id of this tab's panel element. */
843
+ readonly panelId: string;
844
+ /** Id of this tab's button element. */
845
+ readonly buttonId: string;
807
846
  private readonly _active;
808
847
  readonly active: _angular_core.Signal<boolean>;
848
+ private readonly _keepAlive;
849
+ /** Whether inactive content stays in the DOM (hidden) instead of being destroyed. */
850
+ readonly keepAlive: _angular_core.Signal<boolean>;
809
851
  /** @internal called by the parent tab group */
810
852
  setActive(value: boolean): void;
853
+ /** @internal called by the parent tab group */
854
+ setKeepAlive(value: boolean): void;
811
855
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctTab, never>;
812
856
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctTab, "strct-tab", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
813
857
  }
@@ -815,11 +859,16 @@ declare class StrctTab {
815
859
  declare class StrctTabs {
816
860
  readonly tabs: _angular_core.Signal<readonly StrctTab[]>;
817
861
  readonly selectedIndex: _angular_core.ModelSignal<number>;
862
+ /**
863
+ * Keep inactive panels in the DOM with the `hidden` attribute instead of
864
+ * destroying them, preserving their state (e.g. form values) across switches.
865
+ */
866
+ readonly keepAlive: _angular_core.InputSignalWithTransform<boolean, unknown>;
818
867
  constructor();
819
868
  select(index: number): void;
820
869
  onKeydown(event: KeyboardEvent, bar: HTMLElement): void;
821
870
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctTabs, never>;
822
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctTabs, "strct-tabs", never, { "selectedIndex": { "alias": "selectedIndex"; "required": false; "isSignal": true; }; }, { "selectedIndex": "selectedIndexChange"; }, ["tabs"], ["*"], true, never>;
871
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctTabs, "strct-tabs", never, { "selectedIndex": { "alias": "selectedIndex"; "required": false; "isSignal": true; }; "keepAlive": { "alias": "keepAlive"; "required": false; "isSignal": true; }; }, { "selectedIndex": "selectedIndexChange"; }, ["tabs"], ["*"], true, never>;
823
872
  }
824
873
 
825
874
  /** A single entry in a data-driven menu. */
@@ -865,6 +914,8 @@ declare class StrctMenuPanel {
865
914
  readonly back: _angular_core.OutputEmitterRef<void>;
866
915
  protected readonly posX: _angular_core.WritableSignal<number>;
867
916
  protected readonly posY: _angular_core.WritableSignal<number>;
917
+ /** Vertical offset of a submenu fly-out (matches the CSS `top: -5px` default). */
918
+ protected readonly subTop: _angular_core.WritableSignal<number>;
868
919
  protected readonly flipLeft: _angular_core.WritableSignal<boolean>;
869
920
  protected readonly activeIndex: _angular_core.WritableSignal<number>;
870
921
  protected readonly openSubIndex: _angular_core.WritableSignal<number | null>;
@@ -904,6 +955,8 @@ declare class StrctMenuService {
904
955
  private readonly zone;
905
956
  private readonly doc;
906
957
  private ref;
958
+ /** Element focused before opening — focus returns here on close. */
959
+ private restoreTo;
907
960
  open(opts: StrctMenuOpenOptions): void;
908
961
  private readonly onClose;
909
962
  private readonly onOutside;
@@ -978,7 +1031,7 @@ declare class StrctTreeNode {
978
1031
  /** Status dot variant. */
979
1032
  readonly badge: _angular_core.InputSignal<StrctIconBadge>;
980
1033
  /** Whether the item is active / selected. */
981
- readonly active: _angular_core.InputSignal<boolean>;
1034
+ readonly active: _angular_core.InputSignalWithTransform<boolean, unknown>;
982
1035
  /** Whether the panel is open (two-way). */
983
1036
  readonly expanded: _angular_core.ModelSignal<boolean>;
984
1037
  /** Per-node menu resolver (data mode); bubbles down the recursion. */
@@ -1000,18 +1053,37 @@ declare class StrctTreeNode {
1000
1053
  /** 1-based depth, exposed as aria-level. */
1001
1054
  readonly level: number;
1002
1055
  private readonly hostEl;
1056
+ private readonly _id;
1057
+ /** Id of the children group container — the row's aria-owns target. */
1058
+ protected readonly groupId: string;
1003
1059
  private readonly childNodes;
1060
+ /** Direct projected children only (descendants would skew the sibling count). */
1061
+ private readonly directChildNodes;
1004
1062
  /** Data-mode expansion fallback when there is no owning tree (seeded from node.expanded). */
1005
1063
  private readonly dataExpanded;
1006
1064
  protected readonly displayLabel: _angular_core.Signal<string>;
1007
1065
  protected readonly displayIcon: _angular_core.Signal<string | undefined>;
1008
1066
  protected readonly displayBadge: _angular_core.Signal<StrctIconBadge>;
1009
1067
  protected readonly displayActive: _angular_core.Signal<boolean>;
1068
+ /** Data-mode siblings (null in content mode): the parent's children, else the tree roots. */
1069
+ private readonly siblingData;
1070
+ /** Content-mode siblings: the parent's (or owning tree's) direct projected nodes. */
1071
+ private readonly contentSiblings;
1072
+ /** Sibling count, exposed as aria-setsize. */
1073
+ protected readonly setSize: _angular_core.Signal<number>;
1074
+ /** 1-based position among the siblings, exposed as aria-posinset. */
1075
+ protected readonly posInSet: _angular_core.Signal<number>;
1076
+ /** Direct projected child nodes (content mode) — sibling source for aria-setsize/posinset. */
1077
+ contentChildNodes(): readonly StrctTreeNode[];
1078
+ /** Visible label text — matched by the owning tree's typeahead. */
1079
+ typeaheadLabel(): string;
1010
1080
  constructor();
1011
1081
  /** The focusable row element of this node. */
1012
1082
  rowEl(): HTMLElement | null;
1013
1083
  /** Roving tabindex: inside a tree only the active row is tabbable. */
1014
1084
  protected readonly rowTabindex: _angular_core.Signal<0 | -1>;
1085
+ /** Accessible label of the chevron toggle (factory from the owning tree). */
1086
+ protected readonly chevronAriaLabel: _angular_core.Signal<string>;
1015
1087
  protected onRowFocus(): void;
1016
1088
  protected onRowKeydown(event: KeyboardEvent): void;
1017
1089
  readonly hasChildren: _angular_core.Signal<boolean>;
@@ -1020,7 +1092,7 @@ declare class StrctTreeNode {
1020
1092
  protected onActivate(): void;
1021
1093
  protected onMenuSelect(item: StrctMenuItem): void;
1022
1094
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctTreeNode, never>;
1023
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctTreeNode, "strct-tree-node", never, { "node": { "alias": "node"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; "expanded": { "alias": "expanded"; "required": false; "isSignal": true; }; "nodeMenu": { "alias": "nodeMenu"; "required": false; "isSignal": true; }; }, { "expanded": "expandedChange"; "activated": "activated"; "nodeActivated": "nodeActivated"; "nodeMenuSelect": "nodeMenuSelect"; }, ["childNodes"], ["[strctTreeTrailing]", "*"], true, never>;
1095
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctTreeNode, "strct-tree-node", never, { "node": { "alias": "node"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; "expanded": { "alias": "expanded"; "required": false; "isSignal": true; }; "nodeMenu": { "alias": "nodeMenu"; "required": false; "isSignal": true; }; }, { "expanded": "expandedChange"; "activated": "activated"; "nodeActivated": "nodeActivated"; "nodeMenuSelect": "nodeMenuSelect"; }, ["childNodes", "directChildNodes"], ["[strctTreeTrailing]", "*"], true, never>;
1024
1096
  }
1025
1097
  /**
1026
1098
  * Root container for a tree. Either project `<strct-tree-node>` children, or
@@ -1038,6 +1110,8 @@ declare class StrctTree {
1038
1110
  readonly density: _angular_core.InputSignal<"compact" | "comfortable">;
1039
1111
  /** Per-node right-click menu resolver. */
1040
1112
  readonly nodeMenu: _angular_core.InputSignal<StrctTreeNodeMenuFn | null>;
1113
+ /** Accessible label of each node's chevron toggle; receives the expanded state and the node label. */
1114
+ readonly chevronAriaLabel: _angular_core.InputSignal<(expanded: boolean, label: string) => string>;
1041
1115
  /** Emitted when any data-driven node is clicked. */
1042
1116
  readonly nodeActivated: _angular_core.OutputEmitterRef<StrctTreeNodeData>;
1043
1117
  /** Emitted when a data-driven node's right-click menu item is chosen. */
@@ -1069,8 +1143,16 @@ declare class StrctTree {
1069
1143
  isNodeOpen(node: StrctTreeNodeData): boolean;
1070
1144
  private readonly registeredNodes;
1071
1145
  private readonly activeRoving;
1146
+ /** Direct projected root nodes (content mode) — sibling source for aria-setsize/posinset. */
1147
+ private readonly projectedNodes;
1148
+ /** Document-ordered cache of the visible nodes; null = stale. */
1149
+ private orderedCache;
1150
+ /** `nodes` identity the cache was built for (data-mode `@for` can reorder in place). */
1151
+ private orderedCacheNodes;
1072
1152
  registerNode(node: StrctTreeNode): void;
1073
1153
  unregisterNode(node: StrctTreeNode): void;
1154
+ /** Direct projected root nodes (content mode); empty in data mode. */
1155
+ contentChildNodes(): readonly StrctTreeNode[];
1074
1156
  /** Visible nodes in document order (collapsed subtrees are never registered). */
1075
1157
  private ordered;
1076
1158
  /** Whether this node currently holds the roving tabindex (0). */
@@ -1079,10 +1161,20 @@ declare class StrctTree {
1079
1161
  private focusNode;
1080
1162
  /** Keyboard navigation between visible rows (called from the focused node). */
1081
1163
  navigate(node: StrctTreeNode, key: string): void;
1164
+ /** Idle gap after which the accumulated typeahead search string resets (ms). */
1165
+ private static readonly TYPEAHEAD_TIMEOUT;
1166
+ private typeaheadQuery;
1167
+ private typeaheadStamp;
1168
+ /**
1169
+ * APG typeahead: move focus to the next visible node whose label starts with
1170
+ * the typed prefix. Repeating one character cycles through its matches;
1171
+ * different characters accumulate into a search string (reset after a pause).
1172
+ */
1173
+ typeahead(from: StrctTreeNode, key: string): void;
1082
1174
  /** Toggle a node's expansion, updating state and emitting outputs. */
1083
1175
  toggleNode(node: StrctTreeNodeData): void;
1084
1176
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctTree, never>;
1085
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctTree, "strct-tree", never, { "nodes": { "alias": "nodes"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "nodeMenu": { "alias": "nodeMenu"; "required": false; "isSignal": true; }; "expandedIds": { "alias": "expandedIds"; "required": false; "isSignal": true; }; }, { "nodeActivated": "nodeActivated"; "nodeMenuSelect": "nodeMenuSelect"; "expandedIds": "expandedIdsChange"; "expandedChange": "expandedChange"; "nodeToggled": "nodeToggled"; }, never, ["*"], true, never>;
1177
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctTree, "strct-tree", never, { "nodes": { "alias": "nodes"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "nodeMenu": { "alias": "nodeMenu"; "required": false; "isSignal": true; }; "chevronAriaLabel": { "alias": "chevronAriaLabel"; "required": false; "isSignal": true; }; "expandedIds": { "alias": "expandedIds"; "required": false; "isSignal": true; }; }, { "nodeActivated": "nodeActivated"; "nodeMenuSelect": "nodeMenuSelect"; "expandedIds": "expandedIdsChange"; "expandedChange": "expandedChange"; "nodeToggled": "nodeToggled"; }, ["projectedNodes"], ["*"], true, never>;
1086
1178
  }
1087
1179
 
1088
1180
  /** Fixed modal width presets: sm 480 · md 640 · lg 860 · xl 1080 (px). */
@@ -1180,6 +1272,8 @@ type StrctDrawerSize = 'sm' | 'md' | 'lg';
1180
1272
  * </strct-drawer>
1181
1273
  */
1182
1274
  declare class StrctDrawer {
1275
+ private readonly elementRef;
1276
+ private readonly doc;
1183
1277
  /** Open state (two-way). */
1184
1278
  readonly open: _angular_core.ModelSignal<boolean>;
1185
1279
  /** Edge to anchor to. Defaults to `end` (right in LTR). */
@@ -1190,13 +1284,26 @@ declare class StrctDrawer {
1190
1284
  readonly title: _angular_core.InputSignal<string>;
1191
1285
  /** Show the close button and allow backdrop/Esc dismissal. */
1192
1286
  readonly dismissable: _angular_core.InputSignalWithTransform<boolean, unknown>;
1287
+ /** Accessible name of the dialog when no `title` is set (localizable). */
1288
+ readonly ariaLabel: _angular_core.InputSignal<string>;
1289
+ /** Accessible label of the X close button (localizable). */
1290
+ readonly closeLabel: _angular_core.InputSignal<string>;
1193
1291
  protected readonly footerDef: _angular_core.Signal<StrctDrawerFooter | undefined>;
1194
1292
  protected readonly hasFooter: _angular_core.Signal<boolean>;
1293
+ /** Element that had focus before the drawer opened, restored on close. */
1294
+ private previousActive;
1295
+ /** Whether this instance currently holds a scroll lock. */
1296
+ private locked;
1297
+ constructor();
1195
1298
  protected onBackdrop(): void;
1196
- protected onEscape(): void;
1299
+ protected onEscape(event: Event): void;
1300
+ /** Wrap Tab focus within the panel. */
1301
+ protected onTab(event: Event): void;
1197
1302
  close(): void;
1303
+ private panel;
1304
+ private focusInitial;
1198
1305
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctDrawer, never>;
1199
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctDrawer, "strct-drawer", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "side": { "alias": "side"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "dismissable": { "alias": "dismissable"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, ["footerDef"], ["*", "[strctDrawerFooter]"], true, never>;
1306
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctDrawer, "strct-drawer", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "side": { "alias": "side"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "dismissable": { "alias": "dismissable"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "closeLabel": { "alias": "closeLabel"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, ["footerDef"], ["*", "[strctDrawerFooter]"], true, never>;
1200
1307
  }
1201
1308
 
1202
1309
  /**
@@ -1296,18 +1403,43 @@ declare class StrctDropdownDivider {
1296
1403
  * <strct-dropdown-item critical>Delete</strct-dropdown-item>
1297
1404
  * </ng-container>
1298
1405
  * </strct-context-menu>
1406
+ *
1407
+ * Keyboard model mirrors `StrctMenuPanel` (menu.ts): focus moves into the
1408
+ * menu on open, Arrow/Home/End roam it, Enter/Space picks the active item,
1409
+ * Escape closes with stopPropagation, and focus returns to the trigger.
1410
+ *
1411
+ * @deprecated Prefer the data-driven `[strctContextMenu]` directive backed by
1412
+ * `StrctMenuService` (menu.ts) for new code — same visual menu, portaled into
1413
+ * `<body>`, with submenus and item actions.
1299
1414
  */
1300
1415
  declare class StrctContextMenu {
1301
1416
  readonly open: _angular_core.WritableSignal<boolean>;
1302
1417
  readonly x: _angular_core.WritableSignal<number>;
1303
1418
  readonly y: _angular_core.WritableSignal<number>;
1304
- /** Approximate menu box used to keep it inside the viewport. */
1305
- private static readonly MENU_W;
1306
- private static readonly MENU_H;
1419
+ protected readonly menuEl: _angular_core.Signal<ElementRef<HTMLElement> | undefined>;
1420
+ /** Index within the navigable (non-disabled) items. */
1421
+ protected readonly activeIndex: _angular_core.WritableSignal<number>;
1422
+ /** Element focused before opening — focus returns here on close. */
1423
+ private restoreTo;
1307
1424
  onContextMenu(event: MouseEvent): void;
1308
1425
  close(): void;
1309
- protected onDocClick(): void;
1310
- protected onEscape(): void;
1426
+ /** Enabled `strct-dropdown-item` elements in DOM order. */
1427
+ private navItems;
1428
+ /**
1429
+ * Focus-based roving: items keep the `tabindex="-1"` their host binding
1430
+ * sets (so Tab never stops mid-menu), the active element moves instead.
1431
+ */
1432
+ protected focusItem(i: number): void;
1433
+ /** Re-position with the measured box so the menu stays inside the viewport. */
1434
+ private clampToViewport;
1435
+ /** Close on a real item pick only — padding / divider misclicks keep the menu open. */
1436
+ protected onMenuClick(event: MouseEvent): void;
1437
+ /** Keep the arrow-key anchor in sync with the hovered item. */
1438
+ protected onMenuMouseOver(event: MouseEvent): void;
1439
+ protected onMenuKeydown(event: KeyboardEvent): void;
1440
+ protected onDocClick(event: MouseEvent): void;
1441
+ /** Fallback for focus landing outside the panel; in-panel Escape stops first. */
1442
+ protected onEscape(event: Event): void;
1311
1443
  protected onResize(): void;
1312
1444
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctContextMenu, never>;
1313
1445
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctContextMenu, "strct-context-menu", never, {}, {}, never, ["*", "[strctContextMenuItems]"], true, never>;
@@ -1315,8 +1447,10 @@ declare class StrctContextMenu {
1315
1447
 
1316
1448
  /**
1317
1449
  * A nested fly-out inside a `strct-context-menu` or `strct-dropdown`. Opens on
1318
- * hover, click/tap, or the keyboard (Enter / Space / →), and flips to the left
1319
- * near the right edge of the viewport. Reuse `strct-dropdown-item` for entries.
1450
+ * hover, click/tap, or the keyboard (Enter / Space / → — focus then moves into
1451
+ * the fly-out, ← / Escape hand it back to the trigger), and flips to the left
1452
+ * near the right edge of the viewport, upward near the bottom edge.
1453
+ * Reuse `strct-dropdown-item` for entries.
1320
1454
  * <strct-submenu label="Power">
1321
1455
  * <strct-dropdown-item>Power on</strct-dropdown-item>
1322
1456
  * <strct-dropdown-item>Power off</strct-dropdown-item>
@@ -1324,15 +1458,32 @@ declare class StrctContextMenu {
1324
1458
  */
1325
1459
  declare class StrctSubmenu {
1326
1460
  private readonly host;
1461
+ private readonly trigger;
1462
+ private readonly panel;
1327
1463
  /** Label text. */
1328
1464
  readonly label: _angular_core.InputSignal<string>;
1329
1465
  /** Optional leading icon; when omitted the icon column is still reserved so
1330
1466
  * the label stays aligned with sibling items that do have icons. */
1331
1467
  readonly icon: _angular_core.InputSignal<string>;
1332
1468
  readonly open: _angular_core.WritableSignal<boolean>;
1333
- /** Open to the left when the fly-out would overflow the right edge. */
1469
+ /** Open toward the inline start when the fly-out would overflow the inline-end edge. */
1334
1470
  protected readonly flip: _angular_core.WritableSignal<boolean>;
1471
+ /** Open upward when the fly-out would overflow the bottom edge. */
1472
+ protected readonly flipUp: _angular_core.WritableSignal<boolean>;
1335
1473
  protected setOpen(value: boolean): void;
1474
+ /**
1475
+ * Keyboard open (Enter / Space / →): focus the first fly-out entry once the
1476
+ * panel has rendered — otherwise the fly-out is a keyboard dead end.
1477
+ */
1478
+ protected openFromKeyboard(): void;
1479
+ /**
1480
+ * APG keyboarding inside the fly-out: arrows rove, Home/End jump,
1481
+ * ← / Escape close and hand focus back to the trigger. Handled keys stop at
1482
+ * the panel so a host menu's own roving/Escape does not also run.
1483
+ */
1484
+ protected onPanelKeydown(event: KeyboardEvent): void;
1485
+ /** Rovable rows of the open fly-out (dropdown items, skipping disabled). */
1486
+ private panelItems;
1336
1487
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctSubmenu, never>;
1337
1488
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctSubmenu, "strct-submenu", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; }, {}, never, ["[strctSubmenuLabel]", "*"], true, never>;
1338
1489
  }
@@ -1478,8 +1629,10 @@ declare class StrctDivider {
1478
1629
 
1479
1630
  /** Breadcrumb trail container. Wraps `<strct-breadcrumb-item>` children. */
1480
1631
  declare class StrctBreadcrumb {
1632
+ /** Accessible label for the navigation region (localizable). */
1633
+ readonly regionLabel: _angular_core.InputSignal<string>;
1481
1634
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctBreadcrumb, never>;
1482
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctBreadcrumb, "strct-breadcrumb", never, {}, {}, never, ["*"], true, never>;
1635
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctBreadcrumb, "strct-breadcrumb", never, { "regionLabel": { "alias": "regionLabel"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
1483
1636
  }
1484
1637
  /** One crumb. Mark the final one `current`. */
1485
1638
  declare class StrctBreadcrumbItem {
@@ -1499,6 +1652,8 @@ declare class StrctPagination {
1499
1652
  readonly prevLabel: _angular_core.InputSignal<string>;
1500
1653
  readonly nextLabel: _angular_core.InputSignal<string>;
1501
1654
  readonly regionLabel: _angular_core.InputSignal<string>;
1655
+ /** Label prefix for the numbered page buttons, e.g. "Page 3". */
1656
+ readonly pageLabel: _angular_core.InputSignal<string>;
1502
1657
  /** Total number of items. */
1503
1658
  readonly total: _angular_core.InputSignal<number>;
1504
1659
  /** Rows per page (0 disables paging). */
@@ -1506,10 +1661,11 @@ declare class StrctPagination {
1506
1661
  /** Current page (two-way). */
1507
1662
  readonly page: _angular_core.ModelSignal<number>;
1508
1663
  readonly pageCount: _angular_core.Signal<number>;
1664
+ constructor();
1509
1665
  protected readonly pages: _angular_core.Signal<PageToken[]>;
1510
1666
  go(target: number): void;
1511
1667
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctPagination, never>;
1512
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctPagination, "strct-pagination", never, { "prevLabel": { "alias": "prevLabel"; "required": false; "isSignal": true; }; "nextLabel": { "alias": "nextLabel"; "required": false; "isSignal": true; }; "regionLabel": { "alias": "regionLabel"; "required": false; "isSignal": true; }; "total": { "alias": "total"; "required": true; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "page": { "alias": "page"; "required": false; "isSignal": true; }; }, { "page": "pageChange"; }, never, never, true, never>;
1668
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctPagination, "strct-pagination", never, { "prevLabel": { "alias": "prevLabel"; "required": false; "isSignal": true; }; "nextLabel": { "alias": "nextLabel"; "required": false; "isSignal": true; }; "regionLabel": { "alias": "regionLabel"; "required": false; "isSignal": true; }; "pageLabel": { "alias": "pageLabel"; "required": false; "isSignal": true; }; "total": { "alias": "total"; "required": true; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "page": { "alias": "page"; "required": false; "isSignal": true; }; }, { "page": "pageChange"; }, never, never, true, never>;
1513
1669
  }
1514
1670
 
1515
1671
  /** A leaf entry under a {@link StrctMenuSection}. */
@@ -1713,7 +1869,9 @@ declare class StrctSearchbox implements ControlValueAccessor {
1713
1869
  /**
1714
1870
  * Click-to-copy chip with built-in feedback: an icon (or icon + label) button
1715
1871
  * that writes `text` to the clipboard and flips to a ✓ "Copied" state for a
1716
- * moment. The console workhorse for UUIDs, IPs, serials and snippets:
1872
+ * moment; a failed write (rejection or insecure context) shows a localized
1873
+ * error state instead. The console workhorse for UUIDs, IPs, serials and
1874
+ * snippets:
1717
1875
  *
1718
1876
  * <strct-copy text="172.16.75.100" />
1719
1877
  * <strct-copy [text]="host.id" label="Copy ID" />
@@ -1729,15 +1887,19 @@ declare class StrctCopy {
1729
1887
  /** Localizable strings. */
1730
1888
  readonly copyLabel: _angular_core.InputSignal<string>;
1731
1889
  readonly copiedLabel: _angular_core.InputSignal<string>;
1890
+ readonly failedLabel: _angular_core.InputSignal<string>;
1732
1891
  /** Emitted after a successful copy, with the copied text. */
1733
1892
  readonly copied: _angular_core.OutputEmitterRef<string>;
1734
1893
  protected readonly done: _angular_core.WritableSignal<boolean>;
1894
+ protected readonly error: _angular_core.WritableSignal<boolean>;
1735
1895
  private timer;
1736
1896
  constructor();
1737
1897
  /** Write `text` to the clipboard and show the ✓ feedback. */
1738
1898
  copy(): void;
1899
+ /** Surface a failed write (rejection or unavailable clipboard API). */
1900
+ private fail;
1739
1901
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctCopy, never>;
1740
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctCopy, "strct-copy", never, { "text": { "alias": "text"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "copyLabel": { "alias": "copyLabel"; "required": false; "isSignal": true; }; "copiedLabel": { "alias": "copiedLabel"; "required": false; "isSignal": true; }; }, { "copied": "copied"; }, never, never, true, never>;
1902
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctCopy, "strct-copy", never, { "text": { "alias": "text"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "copyLabel": { "alias": "copyLabel"; "required": false; "isSignal": true; }; "copiedLabel": { "alias": "copiedLabel"; "required": false; "isSignal": true; }; "failedLabel": { "alias": "failedLabel"; "required": false; "isSignal": true; }; }, { "copied": "copied"; }, never, never, true, never>;
1741
1903
  }
1742
1904
 
1743
1905
  /**
@@ -1774,9 +1936,11 @@ declare class StrctCode {
1774
1936
  /** Localizable labels for the collapse toggle. */
1775
1937
  readonly collapseLabel: _angular_core.InputSignal<string>;
1776
1938
  readonly expandLabel: _angular_core.InputSignal<string>;
1939
+ /** Fallback accessible label when neither `title` nor `language` is set. */
1940
+ readonly regionLabel: _angular_core.InputSignal<string>;
1777
1941
  protected readonly lineNos: _angular_core.Signal<number[]>;
1778
1942
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctCode, never>;
1779
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctCode, "strct-code", never, { "code": { "alias": "code"; "required": true; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "language": { "alias": "language"; "required": false; "isSignal": true; }; "copyable": { "alias": "copyable"; "required": false; "isSignal": true; }; "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; "lineNumbers": { "alias": "lineNumbers"; "required": false; "isSignal": true; }; "wrap": { "alias": "wrap"; "required": false; "isSignal": true; }; "maxHeight": { "alias": "maxHeight"; "required": false; "isSignal": true; }; "collapseLabel": { "alias": "collapseLabel"; "required": false; "isSignal": true; }; "expandLabel": { "alias": "expandLabel"; "required": false; "isSignal": true; }; }, { "collapsed": "collapsedChange"; }, never, never, true, never>;
1943
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctCode, "strct-code", never, { "code": { "alias": "code"; "required": true; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "language": { "alias": "language"; "required": false; "isSignal": true; }; "copyable": { "alias": "copyable"; "required": false; "isSignal": true; }; "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; "lineNumbers": { "alias": "lineNumbers"; "required": false; "isSignal": true; }; "wrap": { "alias": "wrap"; "required": false; "isSignal": true; }; "maxHeight": { "alias": "maxHeight"; "required": false; "isSignal": true; }; "collapseLabel": { "alias": "collapseLabel"; "required": false; "isSignal": true; }; "expandLabel": { "alias": "expandLabel"; "required": false; "isSignal": true; }; "regionLabel": { "alias": "regionLabel"; "required": false; "isSignal": true; }; }, { "collapsed": "collapsedChange"; }, never, never, true, never>;
1780
1944
  }
1781
1945
 
1782
1946
  /** One active filter chip in a {@link StrctFilterBar}. */
@@ -1814,6 +1978,11 @@ declare class StrctFilterBar {
1814
1978
  readonly removed: _angular_core.OutputEmitterRef<StrctFilterChip>;
1815
1979
  /** "Clear filters" was clicked. */
1816
1980
  readonly cleared: _angular_core.OutputEmitterRef<void>;
1981
+ private readonly host;
1982
+ private readonly injector;
1983
+ private readonly searchbox;
1984
+ /** Chip × clicked: announce, then re-home the focus the removal destroys. */
1985
+ protected removeChip(chip: StrctFilterChip, index: number): void;
1817
1986
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctFilterBar, never>;
1818
1987
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctFilterBar, "strct-filter-bar", never, { "query": { "alias": "query"; "required": false; "isSignal": true; }; "filters": { "alias": "filters"; "required": false; "isSignal": true; }; "count": { "alias": "count"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "countLabel": { "alias": "countLabel"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; "removeLabel": { "alias": "removeLabel"; "required": false; "isSignal": true; }; }, { "query": "queryChange"; "search": "search"; "removed": "removed"; "cleared": "cleared"; }, never, ["*"], true, never>;
1819
1988
  }
@@ -1847,9 +2016,11 @@ declare function strctValidationIcon(status: StrctValidationStatus): string;
1847
2016
  declare class StrctCellStatus {
1848
2017
  /** The validation state to render. */
1849
2018
  readonly state: _angular_core.InputSignal<StrctValidationState>;
2019
+ /** Accessible label for the 'checking' spinner (localizable). */
2020
+ readonly loadingLabel: _angular_core.InputSignal<string>;
1850
2021
  protected readonly icon: _angular_core.Signal<string>;
1851
2022
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctCellStatus, never>;
1852
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctCellStatus, "strct-cell-status, [strct-cell-status]", never, { "state": { "alias": "state"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
2023
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctCellStatus, "strct-cell-status, [strct-cell-status]", never, { "state": { "alias": "state"; "required": true; "isSignal": true; }; "loadingLabel": { "alias": "loadingLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1853
2024
  }
1854
2025
 
1855
2026
  /**
@@ -1914,7 +2085,9 @@ declare class StrctInput {
1914
2085
  /** Checkbox with custom box. Works with `[(ngModel)]` / reactive forms. */
1915
2086
  declare class StrctCheckbox implements ControlValueAccessor {
1916
2087
  readonly checked: _angular_core.ModelSignal<boolean>;
1917
- readonly isDisabled: _angular_core.ModelSignal<boolean>;
2088
+ /** Disabled state pushed by the forms API (setDisabledState). */
2089
+ private readonly cvaDisabled;
2090
+ readonly isDisabled: _angular_core.Signal<boolean>;
1918
2091
  /** Static disable; forms' setDisabledState also drives the disabled state. */
1919
2092
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
1920
2093
  /** Tri-state visual indicator for a parent / intermediate state. */
@@ -1923,25 +2096,25 @@ declare class StrctCheckbox implements ControlValueAccessor {
1923
2096
  readonly ariaLabel: _angular_core.InputSignal<string | null>;
1924
2097
  private onChange;
1925
2098
  protected onTouched: () => void;
1926
- constructor();
1927
2099
  onToggle(event: Event): void;
1928
2100
  writeValue(value: boolean): void;
1929
2101
  registerOnChange(fn: (value: boolean) => void): void;
1930
2102
  registerOnTouched(fn: () => void): void;
1931
2103
  setDisabledState(isDisabled: boolean): void;
1932
2104
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctCheckbox, never>;
1933
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctCheckbox, "strct-checkbox", never, { "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "isDisabled": { "alias": "isDisabled"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "indeterminate": { "alias": "indeterminate"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; "isDisabled": "isDisabledChange"; }, never, ["*"], true, never>;
2105
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctCheckbox, "strct-checkbox", never, { "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "indeterminate": { "alias": "indeterminate"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; }, never, ["*"], true, never>;
1934
2106
  }
1935
2107
 
1936
2108
  /** On/off switch. Works with `[(ngModel)]` / reactive forms. */
1937
2109
  declare class StrctToggle implements ControlValueAccessor {
1938
2110
  readonly checked: _angular_core.WritableSignal<boolean>;
1939
- readonly isDisabled: _angular_core.WritableSignal<boolean>;
2111
+ /** Disabled state pushed by the forms API (setDisabledState). */
2112
+ private readonly cvaDisabled;
2113
+ readonly isDisabled: _angular_core.Signal<boolean>;
1940
2114
  /** Static disable; forms' setDisabledState also drives the disabled state. */
1941
2115
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
1942
2116
  private onChange;
1943
2117
  protected onTouched: () => void;
1944
- constructor();
1945
2118
  onToggle(event: Event): void;
1946
2119
  writeValue(value: boolean): void;
1947
2120
  registerOnChange(fn: (value: boolean) => void): void;
@@ -2014,11 +2187,12 @@ declare class StrctSegmented implements ControlValueAccessor {
2014
2187
  /** Static disable; forms' setDisabledState also drives the disabled state. */
2015
2188
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
2016
2189
  readonly value: _angular_core.WritableSignal<unknown>;
2017
- readonly isDisabled: _angular_core.WritableSignal<boolean>;
2190
+ /** Disabled state pushed by the forms API (setDisabledState). */
2191
+ private readonly cvaDisabled;
2192
+ readonly isDisabled: _angular_core.Signal<boolean>;
2018
2193
  private readonly segs;
2019
2194
  private onChange;
2020
2195
  protected onTouched: () => void;
2021
- constructor();
2022
2196
  protected isSelected(opt: StrctSegmentedOption): boolean;
2023
2197
  /** Index of the currently selected (or first enabled) option for roving focus. */
2024
2198
  private readonly activeIndex;
@@ -2046,14 +2220,15 @@ declare class StrctRange implements ControlValueAccessor {
2046
2220
  readonly step: _angular_core.InputSignal<number>;
2047
2221
  /** Display the current numeric value. */
2048
2222
  readonly showValue: _angular_core.InputSignalWithTransform<boolean, unknown>;
2049
- /** Static disable flag. */
2223
+ /** Static disable; forms' setDisabledState also drives the disabled state. */
2050
2224
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
2051
2225
  readonly value: _angular_core.WritableSignal<number>;
2052
- readonly isDisabled: _angular_core.WritableSignal<boolean>;
2226
+ /** Disabled state pushed by the forms API (setDisabledState). */
2227
+ private readonly cvaDisabled;
2228
+ readonly isDisabled: _angular_core.Signal<boolean>;
2053
2229
  protected readonly fillPercent: _angular_core.Signal<number>;
2054
2230
  private onChange;
2055
2231
  protected onTouched: () => void;
2056
- constructor();
2057
2232
  onInput(event: Event): void;
2058
2233
  writeValue(value: number): void;
2059
2234
  registerOnChange(fn: (value: number) => void): void;
@@ -2074,6 +2249,14 @@ declare class StrctPassword implements ControlValueAccessor {
2074
2249
  readonly meter: _angular_core.InputSignalWithTransform<boolean, unknown>;
2075
2250
  /** Static disable flag. */
2076
2251
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
2252
+ /** Localized strength labels, weakest to strongest. */
2253
+ readonly strengthLabels: _angular_core.InputSignal<string[]>;
2254
+ /** aria-label of the reveal toggle when the password is hidden. */
2255
+ readonly showLabel: _angular_core.InputSignal<string>;
2256
+ /** aria-label of the reveal toggle when the password is visible. */
2257
+ readonly hideLabel: _angular_core.InputSignal<string>;
2258
+ /** Autocomplete hint; the default lets password managers work. */
2259
+ readonly autocomplete: _angular_core.InputSignal<string>;
2077
2260
  readonly value: _angular_core.WritableSignal<string>;
2078
2261
  readonly revealed: _angular_core.WritableSignal<boolean>;
2079
2262
  readonly isDisabled: _angular_core.WritableSignal<boolean>;
@@ -2090,7 +2273,7 @@ declare class StrctPassword implements ControlValueAccessor {
2090
2273
  registerOnTouched(fn: () => void): void;
2091
2274
  setDisabledState(isDisabled: boolean): void;
2092
2275
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctPassword, never>;
2093
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctPassword, "strct-password", never, { "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "meter": { "alias": "meter"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2276
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctPassword, "strct-password", never, { "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "meter": { "alias": "meter"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "strengthLabels": { "alias": "strengthLabels"; "required": false; "isSignal": true; }; "showLabel": { "alias": "showLabel"; "required": false; "isSignal": true; }; "hideLabel": { "alias": "hideLabel"; "required": false; "isSignal": true; }; "autocomplete": { "alias": "autocomplete"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2094
2277
  }
2095
2278
 
2096
2279
  /**
@@ -2104,6 +2287,12 @@ declare class StrctFile implements ControlValueAccessor {
2104
2287
  readonly accept: _angular_core.InputSignal<string>;
2105
2288
  /** Static disable flag. */
2106
2289
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
2290
+ /** Localized prompt text above the "browse" link. */
2291
+ readonly dropLabel: _angular_core.InputSignal<string>;
2292
+ /** Localized text of the "browse" link. */
2293
+ readonly browseLabel: _angular_core.InputSignal<string>;
2294
+ /** aria-label of the per-file remove button. */
2295
+ readonly removeLabel: _angular_core.InputSignal<string>;
2107
2296
  readonly files: _angular_core.WritableSignal<File[]>;
2108
2297
  readonly dragging: _angular_core.WritableSignal<boolean>;
2109
2298
  readonly isDisabled: _angular_core.WritableSignal<boolean>;
@@ -2115,12 +2304,14 @@ declare class StrctFile implements ControlValueAccessor {
2115
2304
  remove(file: File): void;
2116
2305
  protected humanSize(bytes: number): string;
2117
2306
  private setFiles;
2307
+ /** Keep only files matching `accept` (extension or mime pattern), like the native picker. */
2308
+ private filterAccepted;
2118
2309
  writeValue(value: File[]): void;
2119
2310
  registerOnChange(fn: (value: File[]) => void): void;
2120
2311
  registerOnTouched(fn: () => void): void;
2121
2312
  setDisabledState(isDisabled: boolean): void;
2122
2313
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctFile, never>;
2123
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctFile, "strct-file", never, { "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2314
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctFile, "strct-file", never, { "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "dropLabel": { "alias": "dropLabel"; "required": false; "isSignal": true; }; "browseLabel": { "alias": "browseLabel"; "required": false; "isSignal": true; }; "removeLabel": { "alias": "removeLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2124
2315
  }
2125
2316
 
2126
2317
  /** Star rating input. CVA value is the selected count (0–max). */
@@ -2129,21 +2320,28 @@ declare class StrctRating implements ControlValueAccessor {
2129
2320
  readonly max: _angular_core.InputSignal<number>;
2130
2321
  /** Size variant. */
2131
2322
  readonly size: _angular_core.InputSignal<number>;
2132
- /** Prevent user interaction. */
2323
+ /** Prevent user interaction. Stars stay focusable so AT users can read the value. */
2133
2324
  readonly readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
2325
+ /** Accessible name of the radiogroup. */
2326
+ readonly ariaLabel: _angular_core.InputSignal<string>;
2327
+ /** Accessible label for each star button; receives the star index (1-based) and max. */
2328
+ readonly starAriaLabel: _angular_core.InputSignal<(star: number, max: number) => string>;
2134
2329
  readonly value: _angular_core.WritableSignal<number>;
2135
2330
  readonly hover: _angular_core.WritableSignal<number>;
2136
2331
  readonly isDisabled: _angular_core.WritableSignal<boolean>;
2332
+ private readonly starButtons;
2137
2333
  protected stars(): number[];
2138
2334
  private onChange;
2139
2335
  private onTouched;
2140
2336
  pick(star: number): void;
2337
+ /** Arrow keys / Home / End move focus between stars (radiogroup pattern). */
2338
+ protected onKeydown(event: KeyboardEvent): void;
2141
2339
  writeValue(value: number): void;
2142
2340
  registerOnChange(fn: (value: number) => void): void;
2143
2341
  registerOnTouched(fn: () => void): void;
2144
2342
  setDisabledState(isDisabled: boolean): void;
2145
2343
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctRating, never>;
2146
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctRating, "strct-rating", never, { "max": { "alias": "max"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2344
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctRating, "strct-rating", never, { "max": { "alias": "max"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "starAriaLabel": { "alias": "starAriaLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2147
2345
  }
2148
2346
 
2149
2347
  /**
@@ -2155,7 +2353,7 @@ declare class StrctChips implements ControlValueAccessor {
2155
2353
  /** Placeholder text when empty. */
2156
2354
  readonly placeholder: _angular_core.InputSignal<string>;
2157
2355
  /** Allow duplicate tags. */
2158
- readonly allowDuplicates: _angular_core.InputSignal<boolean>;
2356
+ readonly allowDuplicates: _angular_core.InputSignalWithTransform<boolean, unknown>;
2159
2357
  readonly value: _angular_core.WritableSignal<string[]>;
2160
2358
  readonly draft: _angular_core.WritableSignal<string>;
2161
2359
  readonly isDisabled: _angular_core.WritableSignal<boolean>;
@@ -2163,7 +2361,7 @@ declare class StrctChips implements ControlValueAccessor {
2163
2361
  protected onTouched: () => void;
2164
2362
  onKeydown(event: KeyboardEvent): void;
2165
2363
  protected commitDraft(): void;
2166
- remove(chip: string): void;
2364
+ remove(index: number): void;
2167
2365
  private emit;
2168
2366
  writeValue(value: string[]): void;
2169
2367
  registerOnChange(fn: (value: string[]) => void): void;
@@ -2183,7 +2381,7 @@ declare class StrctInputOtp implements ControlValueAccessor {
2183
2381
  /** Number of OTP boxes. */
2184
2382
  readonly length: _angular_core.InputSignal<number>;
2185
2383
  /** Mask each box as a password dot. */
2186
- readonly masked: _angular_core.InputSignal<boolean>;
2384
+ readonly masked: _angular_core.InputSignalWithTransform<boolean, unknown>;
2187
2385
  /**
2188
2386
  * Focus box 0 on first render — the "second-factor step just appeared"
2189
2387
  * case, declaratively.
@@ -2256,6 +2454,8 @@ declare class StrctKnob implements ControlValueAccessor {
2256
2454
  private dragStartValue;
2257
2455
  private readonly onMove;
2258
2456
  private readonly onUp;
2457
+ constructor();
2458
+ private endDrag;
2259
2459
  protected onPointerDown(event: PointerEvent): void;
2260
2460
  protected onKeydown(event: KeyboardEvent): void;
2261
2461
  protected onWheel(event: WheelEvent): void;
@@ -2377,13 +2577,22 @@ declare class StrctCombobox implements ControlValueAccessor {
2377
2577
  readonly allowCustomValue: _angular_core.InputSignalWithTransform<boolean, unknown>;
2378
2578
  /** Verb prefix of the free-form row (localizable) — renders `Use "query"`. */
2379
2579
  readonly customText: _angular_core.InputSignal<string>;
2580
+ /** Static disable; forms' setDisabledState also drives the disabled state. */
2581
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
2582
+ /**
2583
+ * Value identity check — override to match object values coming from a form
2584
+ * (e.g. by id) instead of the default reference equality.
2585
+ */
2586
+ readonly compareWith: _angular_core.InputSignal<(a: unknown, b: unknown) => boolean>;
2380
2587
  readonly query: _angular_core.WritableSignal<string>;
2381
2588
  readonly value: _angular_core.WritableSignal<unknown>;
2382
2589
  /** Selection in `multiple` mode. */
2383
2590
  readonly values: _angular_core.WritableSignal<unknown[]>;
2384
2591
  readonly open: _angular_core.WritableSignal<boolean>;
2385
2592
  readonly activeIndex: _angular_core.WritableSignal<number>;
2386
- readonly isDisabled: _angular_core.WritableSignal<boolean>;
2593
+ /** Disabled state pushed by the forms API (setDisabledState). */
2594
+ private readonly cvaDisabled;
2595
+ readonly isDisabled: _angular_core.Signal<boolean>;
2387
2596
  /** True while the user is typing a filter that hasn't been committed yet. */
2388
2597
  private readonly dirty;
2389
2598
  protected readonly filtered: _angular_core.Signal<StrctOption[]>;
@@ -2439,7 +2648,7 @@ declare class StrctCombobox implements ControlValueAccessor {
2439
2648
  registerOnTouched(fn: () => void): void;
2440
2649
  setDisabledState(isDisabled: boolean): void;
2441
2650
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctCombobox, never>;
2442
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctCombobox, "strct-combobox", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; "removeLabel": { "alias": "removeLabel"; "required": false; "isSignal": true; }; "allowCustomValue": { "alias": "allowCustomValue"; "required": false; "isSignal": true; }; "customText": { "alias": "customText"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2651
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctCombobox, "strct-combobox", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; "removeLabel": { "alias": "removeLabel"; "required": false; "isSignal": true; }; "allowCustomValue": { "alias": "allowCustomValue"; "required": false; "isSignal": true; }; "customText": { "alias": "customText"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2443
2652
  }
2444
2653
 
2445
2654
  /**
@@ -2473,11 +2682,17 @@ declare class StrctSelect implements ControlValueAccessor {
2473
2682
  readonly emptyText: _angular_core.InputSignal<string>;
2474
2683
  /** Static disable flag (forms also drive it via setDisabledState). */
2475
2684
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
2685
+ /**
2686
+ * Value identity check — override to match object values coming from a form
2687
+ * (e.g. by id) instead of the default reference equality.
2688
+ */
2689
+ readonly compareWith: _angular_core.InputSignal<(a: unknown, b: unknown) => boolean>;
2476
2690
  readonly value: _angular_core.WritableSignal<unknown>;
2477
2691
  readonly open: _angular_core.WritableSignal<boolean>;
2478
2692
  readonly activeIndex: _angular_core.WritableSignal<number>;
2479
2693
  readonly isDisabled: _angular_core.WritableSignal<boolean>;
2480
2694
  protected readonly selectedOption: _angular_core.Signal<StrctOption | undefined>;
2695
+ protected isSelected(v: unknown): boolean;
2481
2696
  /** Typeahead buffer — clears half a second after the last keystroke. */
2482
2697
  private typed;
2483
2698
  private typedTimer;
@@ -2507,7 +2722,7 @@ declare class StrctSelect implements ControlValueAccessor {
2507
2722
  registerOnTouched(fn: () => void): void;
2508
2723
  setDisabledState(isDisabled: boolean): void;
2509
2724
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctSelect, never>;
2510
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctSelect, "strct-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "listLabel": { "alias": "listLabel"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2725
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctSelect, "strct-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "listLabel": { "alias": "listLabel"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2511
2726
  }
2512
2727
 
2513
2728
  interface DayCell {
@@ -2515,6 +2730,14 @@ interface DayCell {
2515
2730
  iso: string;
2516
2731
  inMonth: boolean;
2517
2732
  }
2733
+ /** Default month names, January first — the `monthNames` input default (also reused by strct-datetime-picker). */
2734
+ declare const STRCT_DP_MONTHS: string[];
2735
+ /** Default short weekday column labels, Sunday first — the `weekdayNames` input default. */
2736
+ declare const STRCT_DP_DOW: string[];
2737
+ /** Default full weekday names for accessible labels, Sunday first — the `weekdayNamesFull` input default. */
2738
+ declare const STRCT_DP_DOW_FULL: string[];
2739
+ /** Zero-pad to two digits ("4" → "04"). */
2740
+ declare const strctDpPad: (n: number) => string;
2518
2741
  /**
2519
2742
  * Calendar date picker. Value is an ISO `yyyy-mm-dd` string. CVA-compatible.
2520
2743
  * <strct-datepicker [(ngModel)]="date" />
@@ -2523,18 +2746,34 @@ declare class StrctDatepicker implements ControlValueAccessor {
2523
2746
  private readonly host;
2524
2747
  /** Placeholder text when empty. */
2525
2748
  readonly placeholder: _angular_core.InputSignal<string>;
2526
- protected readonly dow: string[];
2527
- protected readonly dowFull: string[];
2749
+ /** Month names, January first (localizable). */
2750
+ readonly monthNames: _angular_core.InputSignal<string[]>;
2751
+ /** Short weekday column labels, Sunday first (localizable). */
2752
+ readonly weekdayNames: _angular_core.InputSignal<string[]>;
2753
+ /** Full weekday names used in accessible labels, Sunday first (localizable). */
2754
+ readonly weekdayNamesFull: _angular_core.InputSignal<string[]>;
2755
+ /** First day of the week: 0 = Sunday, 1 = Monday, … 6 = Saturday. */
2756
+ readonly weekStart: _angular_core.InputSignal<number>;
2757
+ /** Accessible labels of the month navigation buttons (localizable). */
2758
+ readonly prevMonthLabel: _angular_core.InputSignal<string>;
2759
+ readonly nextMonthLabel: _angular_core.InputSignal<string>;
2528
2760
  protected readonly titleId: string;
2529
2761
  readonly value: _angular_core.WritableSignal<string>;
2530
2762
  readonly open: _angular_core.WritableSignal<boolean>;
2531
- readonly isDisabled: _angular_core.WritableSignal<boolean>;
2763
+ /** Static disable; forms' setDisabledState also drives the disabled state. */
2764
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
2765
+ /** Disabled state pushed by the forms API (setDisabledState). */
2766
+ private readonly cvaDisabled;
2767
+ readonly isDisabled: _angular_core.Signal<boolean>;
2532
2768
  /** Keyboard cursor within the open calendar. */
2533
2769
  readonly focusedIso: _angular_core.WritableSignal<string>;
2534
2770
  private readonly view;
2535
2771
  protected get today(): string;
2536
2772
  protected readonly monthLabel: _angular_core.Signal<string>;
2537
2773
  protected readonly displayLabel: _angular_core.Signal<string>;
2774
+ /** Weekday column labels rotated so `weekStart` leads. */
2775
+ protected readonly dow: _angular_core.Signal<string[]>;
2776
+ protected readonly dowFull: _angular_core.Signal<string[]>;
2538
2777
  protected readonly cells: _angular_core.Signal<DayCell[]>;
2539
2778
  /** The 42 cells chunked into ARIA grid rows (weeks). */
2540
2779
  protected readonly weeks: _angular_core.Signal<DayCell[][]>;
@@ -2547,21 +2786,21 @@ declare class StrctDatepicker implements ControlValueAccessor {
2547
2786
  pick(iso: string): void;
2548
2787
  constructor();
2549
2788
  onKeydown(event: KeyboardEvent): void;
2550
- /** Day-of-week (0–6) of the keyboard cursor. */
2551
- private focusedDow;
2789
+ /** Day-of-week of the keyboard cursor relative to `weekStart` (0–6). */
2790
+ private focusedWeekOffset;
2552
2791
  /** Close the panel and hand focus back to the input. */
2553
2792
  private close;
2554
2793
  private syncFocus;
2555
2794
  private shiftFocus;
2556
2795
  protected onDocClick(event: MouseEvent): void;
2557
- protected onEscape(): void;
2796
+ protected onEscape(event: Event): void;
2558
2797
  private startOfMonth;
2559
2798
  writeValue(value: string): void;
2560
2799
  registerOnChange(fn: (value: string) => void): void;
2561
2800
  registerOnTouched(fn: () => void): void;
2562
2801
  setDisabledState(isDisabled: boolean): void;
2563
2802
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctDatepicker, never>;
2564
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctDatepicker, "strct-datepicker", never, { "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2803
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctDatepicker, "strct-datepicker", never, { "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "monthNames": { "alias": "monthNames"; "required": false; "isSignal": true; }; "weekdayNames": { "alias": "weekdayNames"; "required": false; "isSignal": true; }; "weekdayNamesFull": { "alias": "weekdayNamesFull"; "required": false; "isSignal": true; }; "weekStart": { "alias": "weekStart"; "required": false; "isSignal": true; }; "prevMonthLabel": { "alias": "prevMonthLabel"; "required": false; "isSignal": true; }; "nextMonthLabel": { "alias": "nextMonthLabel"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2565
2804
  }
2566
2805
 
2567
2806
  /**
@@ -2575,22 +2814,28 @@ declare class StrctColorPicker implements ControlValueAccessor {
2575
2814
  readonly value: _angular_core.WritableSignal<string>;
2576
2815
  readonly draft: _angular_core.WritableSignal<string>;
2577
2816
  readonly open: _angular_core.WritableSignal<boolean>;
2578
- readonly isDisabled: _angular_core.WritableSignal<boolean>;
2817
+ /** Static disable; forms' setDisabledState also drives the disabled state. */
2818
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
2819
+ /** Disabled state pushed by the forms API (setDisabledState). */
2820
+ private readonly cvaDisabled;
2821
+ readonly isDisabled: _angular_core.Signal<boolean>;
2579
2822
  private onChange;
2580
2823
  private onTouched;
2824
+ /** Where focus was when the panel opened — restored on pick/Escape. */
2825
+ private lastFocused;
2581
2826
  toggle(): void;
2582
2827
  protected eq(color: string): boolean;
2583
2828
  pick(color: string): void;
2584
2829
  onHex(event: Event): void;
2585
2830
  private commit;
2586
2831
  protected onDocClick(event: MouseEvent): void;
2587
- protected onEscape(): void;
2832
+ protected onEscape(event: Event): void;
2588
2833
  writeValue(value: string): void;
2589
2834
  registerOnChange(fn: (value: string) => void): void;
2590
2835
  registerOnTouched(fn: () => void): void;
2591
2836
  setDisabledState(isDisabled: boolean): void;
2592
2837
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctColorPicker, never>;
2593
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctColorPicker, "strct-color-picker", never, { "swatches": { "alias": "swatches"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2838
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctColorPicker, "strct-color-picker", never, { "swatches": { "alias": "swatches"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2594
2839
  }
2595
2840
 
2596
2841
  /** One option in a cascade select. */
@@ -2599,55 +2844,102 @@ interface StrctCascadeOption {
2599
2844
  value?: unknown;
2600
2845
  children?: StrctCascadeOption[];
2601
2846
  }
2602
- /** DI token the nodes use to talk back to the host control (avoids a circular type). */
2847
+ /** DI token the columns use to talk back to the host control (avoids a circular type). */
2603
2848
  declare abstract class StrctCascadeHost {
2604
2849
  abstract pick(value: unknown): void;
2605
2850
  abstract isSelected(value: unknown): boolean;
2606
2851
  }
2607
2852
  /**
2608
- * One row in the cascade. Leaf rows select on click; group rows reveal a
2609
- * fly-out of their children on hover. Recurses to any depth.
2853
+ * One column of a cascade: a flat list of rows plus at most one open fly-out
2854
+ * column for the active group row. Recurses to any depth. Keyboard follows the
2855
+ * menu pattern (`context-menu/menu.ts`): roving tabindex, ArrowUp/Down rove,
2856
+ * ArrowRight opens a group's fly-out (and focuses its first row), ArrowLeft
2857
+ * backs out, Home/End jump, Enter/Space pick or open, Escape/Tab close.
2610
2858
  */
2611
- declare class StrctCascadeNode {
2859
+ declare class StrctCascadeColumn {
2612
2860
  private readonly host;
2613
- /** Option. */
2614
- readonly option: _angular_core.InputSignal<StrctCascadeOption>;
2615
- readonly open: _angular_core.WritableSignal<boolean>;
2616
- protected readonly hasChildren: _angular_core.Signal<boolean>;
2617
- protected readonly isLeafSelected: _angular_core.Signal<boolean>;
2618
- protected onClick(event: Event): void;
2619
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctCascadeNode, never>;
2620
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctCascadeNode, "strct-cascade-node", never, { "option": { "alias": "option"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
2861
+ private readonly el;
2862
+ /** Options shown in this column. */
2863
+ readonly items: _angular_core.InputSignal<StrctCascadeOption[]>;
2864
+ /** Rendered as a fly-out of a parent column (ArrowLeft asks the parent to close it). */
2865
+ readonly submenu: _angular_core.InputSignalWithTransform<boolean, unknown>;
2866
+ /** Focus the first row when the column appears (keyboard opens only). */
2867
+ readonly focusOnOpen: _angular_core.InputSignalWithTransform<boolean, unknown>;
2868
+ /** Emitted when the whole cascade should close (Escape/Tab at any depth). */
2869
+ readonly close: _angular_core.OutputEmitterRef<void>;
2870
+ /** ArrowLeft at a fly-out's top level — asks the parent to close the fly-out. */
2871
+ readonly back: _angular_core.OutputEmitterRef<void>;
2872
+ protected readonly activeIndex: _angular_core.WritableSignal<number>;
2873
+ protected readonly openSubIndex: _angular_core.WritableSignal<number | null>;
2874
+ /** Whether the fly-out being opened should take focus (keyboard opens only). */
2875
+ protected subFocusOnOpen: boolean;
2876
+ constructor();
2877
+ protected isLeafSelected(opt: StrctCascadeOption): boolean;
2878
+ protected focusItem(i: number): void;
2879
+ protected closeSub(): void;
2880
+ /** Open the active row's fly-out; keyboard opens move focus into it. */
2881
+ private openSub;
2882
+ private move;
2883
+ protected onHover(i: number): void;
2884
+ protected onLeave(i: number): void;
2885
+ protected onItemClick(opt: StrctCascadeOption, i: number, event: Event): void;
2886
+ protected onKeydown(event: KeyboardEvent): void;
2887
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctCascadeColumn, never>;
2888
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctCascadeColumn, "strct-cascade-column", never, { "items": { "alias": "items"; "required": true; "isSignal": true; }; "submenu": { "alias": "submenu"; "required": false; "isSignal": true; }; "focusOnOpen": { "alias": "focusOnOpen"; "required": false; "isSignal": true; }; }, { "close": "close"; "back": "back"; }, never, never, true, never>;
2621
2889
  }
2622
2890
  /**
2623
2891
  * Hierarchical single-select — pick a leaf from nested groups (e.g. a port
2624
2892
  * group under a virtual switch). CVA-compatible.
2625
2893
  * <strct-cascade-select [options]="switches" [(ngModel)]="portGroup" />
2894
+ *
2895
+ * Keyboard: ArrowDown/Enter/Space open from the trigger; inside the panel
2896
+ * arrows rove, ArrowRight opens a group's fly-out, ArrowLeft backs out,
2897
+ * Home/End jump, Enter/Space pick a leaf, Escape/Tab close. Focus returns to
2898
+ * the trigger on close.
2626
2899
  */
2627
2900
  declare class StrctCascadeSelect extends StrctCascadeHost implements ControlValueAccessor {
2628
2901
  private readonly elementRef;
2629
2902
  /** Available options. */
2630
2903
  readonly options: _angular_core.InputSignal<StrctCascadeOption[]>;
2631
- /** Placeholder text when empty. */
2904
+ /** Placeholder text when empty (localizable). */
2632
2905
  readonly placeholder: _angular_core.InputSignal<string>;
2906
+ /** Static disable; forms' setDisabledState also drives the disabled state. */
2907
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
2908
+ /**
2909
+ * Value identity check — override to match object values coming from a form
2910
+ * (e.g. by id) instead of the default reference equality.
2911
+ */
2912
+ readonly compareWith: _angular_core.InputSignal<(a: unknown, b: unknown) => boolean>;
2633
2913
  readonly value: _angular_core.WritableSignal<unknown>;
2634
2914
  readonly open: _angular_core.WritableSignal<boolean>;
2635
- readonly isDisabled: _angular_core.WritableSignal<boolean>;
2915
+ /** Disabled state pushed by the forms API (setDisabledState). */
2916
+ private readonly cvaDisabled;
2917
+ readonly isDisabled: _angular_core.Signal<boolean>;
2636
2918
  protected readonly selectedLabel: _angular_core.Signal<string>;
2919
+ /** Element focused before the panel opened — focus returns here on close. */
2920
+ private restoreTo;
2637
2921
  private onChange;
2638
2922
  private onTouched;
2639
2923
  toggle(): void;
2924
+ openPanel(): void;
2925
+ closePanel(): void;
2926
+ /**
2927
+ * ArrowDown/Enter/Space open the panel from the trigger. preventDefault so
2928
+ * Space doesn't scroll the page and Enter/Space don't also fire the native
2929
+ * button click (which would toggle the panel straight back shut).
2930
+ */
2931
+ protected onTriggerKeydown(event: KeyboardEvent): void;
2640
2932
  pick(value: unknown): void;
2641
2933
  isSelected(value: unknown): boolean;
2642
2934
  private findLabel;
2643
2935
  protected onDocClick(event: MouseEvent): void;
2644
- protected onEscape(): void;
2936
+ protected onEscape(event: Event): void;
2645
2937
  writeValue(value: unknown): void;
2646
2938
  registerOnChange(fn: (value: unknown) => void): void;
2647
2939
  registerOnTouched(fn: () => void): void;
2648
2940
  setDisabledState(isDisabled: boolean): void;
2649
2941
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctCascadeSelect, never>;
2650
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctCascadeSelect, "strct-cascade-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2942
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctCascadeSelect, "strct-cascade-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2651
2943
  }
2652
2944
 
2653
2945
  /** One row in a `StrctDescriptionList` when driven by the `items` input. */
@@ -2752,11 +3044,13 @@ declare class StrctTable {
2752
3044
  readonly emptyText: _angular_core.InputSignal<string>;
2753
3045
  /** Show skeleton rows while data is loading. */
2754
3046
  readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
3047
+ /** Accessible label for the scrollable region (localizable). */
3048
+ readonly label: _angular_core.InputSignal<string>;
2755
3049
  private readonly cellDefs;
2756
3050
  private readonly cellMap;
2757
3051
  protected cellTemplate(key: string): TemplateRef<StrctCellContext> | null;
2758
3052
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctTable, never>;
2759
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctTable, "strct-table", never, { "columns": { "alias": "columns"; "required": true; "isSignal": true; }; "rows": { "alias": "rows"; "required": true; "isSignal": true; }; "striped": { "alias": "striped"; "required": false; "isSignal": true; }; "hover": { "alias": "hover"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; }, {}, ["cellDefs"], never, true, never>;
3053
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctTable, "strct-table", never, { "columns": { "alias": "columns"; "required": true; "isSignal": true; }; "rows": { "alias": "rows"; "required": true; "isSignal": true; }; "striped": { "alias": "striped"; "required": false; "isSignal": true; }; "hover": { "alias": "hover"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, {}, ["cellDefs"], never, true, never>;
2760
3054
  }
2761
3055
 
2762
3056
  /** Every user-visible / assistive string in the grid, overridable for i18n. */
@@ -2765,7 +3059,12 @@ interface StrctDatagridLabels {
2765
3059
  rows: string;
2766
3060
  selected: string;
2767
3061
  selectAll: string;
3062
+ /** Base row-checkbox label; superseded by {@link selectRowFor}, which
3063
+ * appends the row's identifier. Kept for existing overrides. */
2768
3064
  selectRow: string;
3065
+ /** Row-checkbox label factory: receives the row's id (`rowId`) or its
3066
+ * 1-based index, so every row's checkbox gets a distinct name. */
3067
+ selectRowFor: (id: string) => string;
2769
3068
  openDetail: string;
2770
3069
  toggleDetail: string;
2771
3070
  closeDetail: string;
@@ -2924,6 +3223,7 @@ declare class StrctDatagrid {
2924
3223
  selected: string;
2925
3224
  selectAll: string;
2926
3225
  selectRow: string;
3226
+ selectRowFor: (id: string) => string;
2927
3227
  openDetail: string;
2928
3228
  toggleDetail: string;
2929
3229
  closeDetail: string;
@@ -3003,6 +3303,12 @@ declare class StrctDatagrid {
3003
3303
  * hierarchically with indent + carets; sorting applies per sibling level;
3004
3304
  * an active filter shows matches with their ancestors, force-expanded.
3005
3305
  * Not combinable with `groupBy` or `lazy`.
3306
+ *
3307
+ * The table claims `role="treegrid"` and honors the row-level core of the
3308
+ * treegrid keyboard contract: rows carry a roving tabindex, ArrowUp/Down
3309
+ * move focus between rows, ArrowRight expands a collapsed parent row and
3310
+ * ArrowLeft collapses an expanded one. There is no cell-level navigation —
3311
+ * Tab walks the interactive elements inside each row as usual.
3006
3312
  */
3007
3313
  readonly childrenKey: _angular_core.InputSignal<string | null>;
3008
3314
  /** Emitted when the selection changes. */
@@ -3071,21 +3377,39 @@ declare class StrctDatagrid {
3071
3377
  protected readonly displayItems: _angular_core.Signal<DgItem[]>;
3072
3378
  protected itemKey(it: DgItem): unknown;
3073
3379
  protected readonly filterOpenKey: _angular_core.WritableSignal<string | null>;
3380
+ /** The filter button that opened the panel — focus returns here on close. */
3381
+ private filterTrigger;
3074
3382
  protected toggleFilterPanel(key: string, event: Event): void;
3383
+ private closeFilterPanel;
3075
3384
  protected hasFilter(key: string): boolean;
3076
3385
  protected textFilter(key: string): string;
3077
3386
  protected setTextFilter(key: string, value: string): void;
3078
3387
  protected optionChecked(key: string, opt: unknown): boolean;
3079
3388
  protected toggleFilterOption(key: string, opt: unknown): void;
3080
3389
  protected clearFilter(key: string): void;
3081
- protected onDocClickFilter(event: MouseEvent): void;
3082
- protected onEscapeFilter(): void;
3390
+ protected onDocClickOverlays(event: MouseEvent): void;
3391
+ /** Escape closes the topmost transient surface and hands focus back to its
3392
+ * trigger; stopPropagation keeps a host modal / drawer from also closing. */
3393
+ protected onEscapeOverlays(event: Event): void;
3083
3394
  private readonly expandedTree;
3084
3395
  protected treeDepth(row: StrctRow): number;
3085
3396
  protected treeHasChildren(row: StrctRow): boolean;
3086
3397
  protected treeExpanded(row: StrctRow): boolean;
3087
3398
  /** Expand / collapse one tree row. */
3088
3399
  toggleTreeRow(row: StrctRow): void;
3400
+ /**
3401
+ * Treegrid keyboard contract (row-level core; there is deliberately no
3402
+ * cell-level navigation — Tab still walks the interactive elements inside
3403
+ * each row): ↑/↓ move focus between rows via a roving tabindex, → expands
3404
+ * a collapsed parent row, ← collapses an expanded one.
3405
+ */
3406
+ /** Roving-tabindex target (row key); defaults to the first rendered row. */
3407
+ private readonly activeTreeRow;
3408
+ protected treeRowTabindex(row: StrctRow): number;
3409
+ protected onTreeRowKeydown(row: StrctRow, event: KeyboardEvent): void;
3410
+ /** Move the roving tabindex to the row at `idx` and focus its element once
3411
+ * the new tabindex has rendered. */
3412
+ private focusTreeRow;
3089
3413
  private readonly hostRef;
3090
3414
  protected readonly editing: _angular_core.WritableSignal<{
3091
3415
  rowKey: unknown;
@@ -3139,6 +3463,10 @@ declare class StrctDatagrid {
3139
3463
  protected isSticky(col: StrctDatagridColumn): boolean;
3140
3464
  /** The last frozen column carries the edge shadow. */
3141
3465
  protected readonly lastStickyKey: _angular_core.Signal<string | null>;
3466
+ /** The rows the select-all checkbox operates on: what the user can actually
3467
+ * see — the current page, or every row under the expanded groups (group
3468
+ * mode bypasses paging, so `paged()` would silently under-select). */
3469
+ private readonly selectionRows;
3142
3470
  protected readonly allPageSelected: _angular_core.Signal<boolean>;
3143
3471
  protected readonly somePageSelected: _angular_core.Signal<boolean>;
3144
3472
  /** Resolve a row's stable identity (defaults to the row object itself). */
@@ -3178,15 +3506,27 @@ declare class StrctDatagrid {
3178
3506
  protected sortIcon(key: string): string;
3179
3507
  protected ariaSort(key: string): 'ascending' | 'descending' | 'none';
3180
3508
  protected onHeaderSpace(event: Event, key: string): void;
3509
+ /** The footer button that opened the column chooser — focus returns here. */
3510
+ private chooserTrigger;
3511
+ protected toggleChooser(event: MouseEvent): void;
3512
+ protected closeChooser(restore?: boolean): void;
3181
3513
  toggleColumn(key: string, visible: boolean): void;
3514
+ /** Distinct aria label per row checkbox: the base label + this row's
3515
+ * identifier (its `rowId` value, falling back to the 1-based row index). */
3516
+ protected selectRowLabel(row: StrctRow): string;
3517
+ private rowIdentifier;
3182
3518
  protected isSelected(row: StrctRow): boolean;
3183
3519
  protected isExpanded(row: StrctRow): boolean;
3184
3520
  toggleExpand(row: StrctRow): void;
3185
3521
  toggleRow(row: StrctRow): void;
3186
3522
  toggleAll(): void;
3187
3523
  clearSelection(): void;
3188
- /** Emit the current row objects whose id is selected (resolved against the
3189
- * latest data, so consumers always get fresh references). */
3524
+ /** Last known row object per selected id — selections made on one page stay
3525
+ * in the payload when the data set no longer contains them (lazy paging),
3526
+ * so `selectionChange` and `selectedCount` never disagree. */
3527
+ private readonly selectedRowCache;
3528
+ /** Emit every selected row: fresh objects from the latest data where
3529
+ * available, the last known snapshot otherwise (off-page lazy rows). */
3190
3530
  private commitSelection;
3191
3531
  private compare;
3192
3532
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctDatagrid, never>;
@@ -3202,7 +3542,7 @@ declare class StrctTimeline {
3202
3542
  }
3203
3543
  /** A timeline entry: a node on the rail plus a title and projected body. */
3204
3544
  declare class StrctTimelineItem {
3205
- /** Dialog title. */
3545
+ /** Title shown at the top of the entry. */
3206
3546
  readonly title: _angular_core.InputSignal<string>;
3207
3547
  /** State. */
3208
3548
  readonly state: _angular_core.InputSignal<StrctTimelineState>;
@@ -3239,12 +3579,14 @@ declare class StrctSparkline {
3239
3579
  readonly width: _angular_core.InputSignal<number>;
3240
3580
  /** Height in pixels. */
3241
3581
  readonly height: _angular_core.InputSignal<number>;
3582
+ /** Accessible name for the chart (role="img"). */
3583
+ readonly ariaLabel: _angular_core.InputSignal<string>;
3242
3584
  protected readonly color: _angular_core.Signal<string>;
3243
3585
  private readonly points;
3244
3586
  protected readonly linePoints: _angular_core.Signal<string>;
3245
3587
  protected readonly areaPoints: _angular_core.Signal<string>;
3246
3588
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctSparkline, never>;
3247
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctSparkline, "strct-sparkline", never, { "data": { "alias": "data"; "required": true; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "area": { "alias": "area"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
3589
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctSparkline, "strct-sparkline", never, { "data": { "alias": "data"; "required": true; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "area": { "alias": "area"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
3248
3590
  }
3249
3591
 
3250
3592
  /** Chart rendering types (line, area, bar). */
@@ -3314,6 +3656,20 @@ interface StrctChartThreshold {
3314
3656
  /** Dashed line; default true. */
3315
3657
  dashed?: boolean;
3316
3658
  }
3659
+ /** Facts handed to `summaryFormat` to build the role="img" aria summary. */
3660
+ interface StrctChartSummaryInfo {
3661
+ /** Series count (multi) or data point count (single). */
3662
+ count: number;
3663
+ /** Per-series label + formatted latest value (multi only). */
3664
+ series?: {
3665
+ label: string;
3666
+ latest: string;
3667
+ }[];
3668
+ /** Formatted min / max / latest values (single-series only). */
3669
+ min?: string;
3670
+ max?: string;
3671
+ latest?: string;
3672
+ }
3317
3673
  interface Pt {
3318
3674
  x: number;
3319
3675
  y: number;
@@ -3438,6 +3794,13 @@ declare class StrctChart {
3438
3794
  readonly gapText: _angular_core.InputSignal<string>;
3439
3795
  /** Accessible label of the reset-zoom chip (localizable). */
3440
3796
  readonly resetLabel: _angular_core.InputSignal<string>;
3797
+ /** Live-mode tooltip text for the most recent point (localizable). */
3798
+ readonly nowLabel: _angular_core.InputSignal<string>;
3799
+ /**
3800
+ * Factory for the role="img" aria summary (localizable); receives the
3801
+ * computed facts. When null, a default English summary is generated.
3802
+ */
3803
+ readonly summaryFormat: _angular_core.InputSignal<((info: StrctChartSummaryInfo) => string) | null>;
3441
3804
  /** Emits the hovered point index (or null on leave) — wire cross-chart sync with it. */
3442
3805
  readonly hoverIndex: _angular_core.OutputEmitterRef<number | null>;
3443
3806
  /** Emits the brushed [startIndex, endIndex] (inclusive), or null when cleared. */
@@ -3516,6 +3879,7 @@ declare class StrctChart {
3516
3879
  w: number;
3517
3880
  h: number;
3518
3881
  }[]>;
3882
+ /** Horizontal gridlines — one per y tick, so they line up with the axis labels. */
3519
3883
  protected readonly gridY: _angular_core.Signal<number[]>;
3520
3884
  private fmtAxis;
3521
3885
  protected readonly yAxisTicks: _angular_core.Signal<{
@@ -3562,11 +3926,11 @@ declare class StrctChart {
3562
3926
  protected readonly absDelta: _angular_core.Signal<number>;
3563
3927
  /** Second tooltip line: "Xs ago" while live, else the x label. */
3564
3928
  protected readonly hoverMeta: _angular_core.Signal<string>;
3565
- /** Per-series value at the hovered index (multi-series tooltip; bands as `avg (min–max)`). */
3929
+ /** Per-series value at the hovered index (multi-series tooltip; bands as `avg (min–max)`).
3930
+ * Gap slots stay listed with `gapText`, like the single-series gap tip. */
3566
3931
  protected readonly hoverRows: _angular_core.Signal<{
3567
3932
  label: string;
3568
3933
  color: string;
3569
- value: number | null;
3570
3934
  text: string;
3571
3935
  }[]>;
3572
3936
  /** Per-series hover dots (multi-series). */
@@ -3622,7 +3986,7 @@ declare class StrctChart {
3622
3986
  /** The chart as a PNG data URL at the given scale (default 2×). */
3623
3987
  toPNG(scale?: number): Promise<string>;
3624
3988
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctChart, never>;
3625
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctChart, "strct-chart", never, { "data": { "alias": "data"; "required": false; "isSignal": true; }; "series": { "alias": "series"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "curve": { "alias": "curve"; "required": false; "isSignal": true; }; "area": { "alias": "area"; "required": false; "isSignal": true; }; "glow": { "alias": "glow"; "required": false; "isSignal": true; }; "live": { "alias": "live"; "required": false; "isSignal": true; }; "interval": { "alias": "interval"; "required": false; "isSignal": true; }; "interactive": { "alias": "interactive"; "required": false; "isSignal": true; }; "strokeWidth": { "alias": "strokeWidth"; "required": false; "isSignal": true; }; "grid": { "alias": "grid"; "required": false; "isSignal": true; }; "dots": { "alias": "dots"; "required": false; "isSignal": true; }; "legend": { "alias": "legend"; "required": false; "isSignal": true; }; "labels": { "alias": "labels"; "required": false; "isSignal": true; }; "xTicks": { "alias": "xTicks"; "required": false; "isSignal": true; }; "xFormat": { "alias": "xFormat"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "yAxis": { "alias": "yAxis"; "required": false; "isSignal": true; }; "yTicks": { "alias": "yTicks"; "required": false; "isSignal": true; }; "axisFormat": { "alias": "axisFormat"; "required": false; "isSignal": true; }; "thresholds": { "alias": "thresholds"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "agoFormat": { "alias": "agoFormat"; "required": false; "isSignal": true; }; "valueFormat": { "alias": "valueFormat"; "required": false; "isSignal": true; }; "annotations": { "alias": "annotations"; "required": false; "isSignal": true; }; "activeIndex": { "alias": "activeIndex"; "required": false; "isSignal": true; }; "brush": { "alias": "brush"; "required": false; "isSignal": true; }; "zoom": { "alias": "zoom"; "required": false; "isSignal": true; }; "stacked": { "alias": "stacked"; "required": false; "isSignal": true; }; "scale": { "alias": "scale"; "required": false; "isSignal": true; }; "times": { "alias": "times"; "required": false; "isSignal": true; }; "gapText": { "alias": "gapText"; "required": false; "isSignal": true; }; "resetLabel": { "alias": "resetLabel"; "required": false; "isSignal": true; }; }, { "hoverIndex": "hoverIndex"; "brushChange": "brushChange"; }, never, never, true, never>;
3989
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctChart, "strct-chart", never, { "data": { "alias": "data"; "required": false; "isSignal": true; }; "series": { "alias": "series"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "curve": { "alias": "curve"; "required": false; "isSignal": true; }; "area": { "alias": "area"; "required": false; "isSignal": true; }; "glow": { "alias": "glow"; "required": false; "isSignal": true; }; "live": { "alias": "live"; "required": false; "isSignal": true; }; "interval": { "alias": "interval"; "required": false; "isSignal": true; }; "interactive": { "alias": "interactive"; "required": false; "isSignal": true; }; "strokeWidth": { "alias": "strokeWidth"; "required": false; "isSignal": true; }; "grid": { "alias": "grid"; "required": false; "isSignal": true; }; "dots": { "alias": "dots"; "required": false; "isSignal": true; }; "legend": { "alias": "legend"; "required": false; "isSignal": true; }; "labels": { "alias": "labels"; "required": false; "isSignal": true; }; "xTicks": { "alias": "xTicks"; "required": false; "isSignal": true; }; "xFormat": { "alias": "xFormat"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "yAxis": { "alias": "yAxis"; "required": false; "isSignal": true; }; "yTicks": { "alias": "yTicks"; "required": false; "isSignal": true; }; "axisFormat": { "alias": "axisFormat"; "required": false; "isSignal": true; }; "thresholds": { "alias": "thresholds"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "agoFormat": { "alias": "agoFormat"; "required": false; "isSignal": true; }; "valueFormat": { "alias": "valueFormat"; "required": false; "isSignal": true; }; "annotations": { "alias": "annotations"; "required": false; "isSignal": true; }; "activeIndex": { "alias": "activeIndex"; "required": false; "isSignal": true; }; "brush": { "alias": "brush"; "required": false; "isSignal": true; }; "zoom": { "alias": "zoom"; "required": false; "isSignal": true; }; "stacked": { "alias": "stacked"; "required": false; "isSignal": true; }; "scale": { "alias": "scale"; "required": false; "isSignal": true; }; "times": { "alias": "times"; "required": false; "isSignal": true; }; "gapText": { "alias": "gapText"; "required": false; "isSignal": true; }; "resetLabel": { "alias": "resetLabel"; "required": false; "isSignal": true; }; "nowLabel": { "alias": "nowLabel"; "required": false; "isSignal": true; }; "summaryFormat": { "alias": "summaryFormat"; "required": false; "isSignal": true; }; }, { "hoverIndex": "hoverIndex"; "brushChange": "brushChange"; }, never, never, true, never>;
3626
3990
  }
3627
3991
 
3628
3992
  /** A single weighted slice of a donut chart. */
@@ -3699,6 +4063,8 @@ declare class StrctGauge {
3699
4063
  readonly thresholds: _angular_core.InputSignal<StrctThresholds | null>;
3700
4064
  /** Label text. */
3701
4065
  readonly label: _angular_core.InputSignal<string>;
4066
+ /** Accessible name for the gauge (role="meter"). */
4067
+ readonly ariaLabel: _angular_core.InputSignal<string>;
3702
4068
  /** Size variant. */
3703
4069
  readonly size: _angular_core.InputSignal<number>;
3704
4070
  /** Stroke thickness in pixels. */
@@ -3713,7 +4079,7 @@ declare class StrctGauge {
3713
4079
  protected readonly trackDash: _angular_core.Signal<string>;
3714
4080
  protected readonly valueDash: _angular_core.Signal<string>;
3715
4081
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctGauge, never>;
3716
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctGauge, "strct-gauge", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "thresholds": { "alias": "thresholds"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "thickness": { "alias": "thickness"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
4082
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctGauge, "strct-gauge", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "thresholds": { "alias": "thresholds"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "thickness": { "alias": "thickness"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
3717
4083
  }
3718
4084
 
3719
4085
  /** One endpoint in a `StrctFlow`. */
@@ -3798,18 +4164,27 @@ declare class StrctMetricTile {
3798
4164
  readonly delta: _angular_core.InputSignal<number | null>;
3799
4165
  /** Suffix for the delta number. */
3800
4166
  readonly deltaSuffix: _angular_core.InputSignal<string>;
4167
+ /**
4168
+ * Accessible text for the delta (rendered visually-hidden next to the number);
4169
+ * receives the signed delta and the suffix.
4170
+ */
4171
+ readonly deltaAriaLabel: _angular_core.InputSignal<(delta: number, suffix: string) => string>;
3801
4172
  /** Treat a positive delta as bad (e.g. error rate, latency). */
3802
4173
  readonly invertDelta: _angular_core.InputSignalWithTransform<boolean, unknown>;
4174
+ /** Skeleton placeholder + aria-busy while the metric loads. */
4175
+ readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
3803
4176
  /** Small sub-text under the value (e.g. "of 256 GB"). */
3804
4177
  readonly caption: _angular_core.InputSignal<string>;
3805
4178
  /** Sparkline series; empty hides the chart. */
3806
4179
  readonly data: _angular_core.InputSignal<number[]>;
3807
4180
  protected readonly hasDelta: _angular_core.Signal<boolean>;
3808
4181
  protected readonly absDelta: _angular_core.Signal<number>;
4182
+ protected readonly deltaIcon: _angular_core.Signal<"minus" | "arrowUp" | "arrowDown">;
4183
+ protected readonly deltaText: _angular_core.Signal<string>;
3809
4184
  protected readonly deltaTone: _angular_core.Signal<"flat" | "up" | "down">;
3810
4185
  protected readonly sparkStatus: _angular_core.Signal<StrctChartStatus>;
3811
4186
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctMetricTile, never>;
3812
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctMetricTile, "strct-metric-tile", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; "unit": { "alias": "unit"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "delta": { "alias": "delta"; "required": false; "isSignal": true; }; "deltaSuffix": { "alias": "deltaSuffix"; "required": false; "isSignal": true; }; "invertDelta": { "alias": "invertDelta"; "required": false; "isSignal": true; }; "caption": { "alias": "caption"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
4187
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctMetricTile, "strct-metric-tile", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; "unit": { "alias": "unit"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "delta": { "alias": "delta"; "required": false; "isSignal": true; }; "deltaSuffix": { "alias": "deltaSuffix"; "required": false; "isSignal": true; }; "deltaAriaLabel": { "alias": "deltaAriaLabel"; "required": false; "isSignal": true; }; "invertDelta": { "alias": "invertDelta"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "caption": { "alias": "caption"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
3813
4188
  }
3814
4189
 
3815
4190
  /**
@@ -3837,10 +4212,16 @@ declare class StrctHero {
3837
4212
  readonly heading: _angular_core.InputSignal<string>;
3838
4213
  /** Tighter padding for secondary placements. */
3839
4214
  readonly dense: _angular_core.InputSignalWithTransform<boolean, unknown>;
4215
+ /**
4216
+ * Opt into a polite live region (role="status") for banners whose content
4217
+ * updates after load; static banners should leave this off. Critical heroes
4218
+ * are always role="alert" regardless.
4219
+ */
4220
+ readonly live: _angular_core.InputSignalWithTransform<boolean, unknown>;
3840
4221
  protected readonly headingId: string;
3841
4222
  protected readonly resolvedIcon: _angular_core.Signal<string>;
3842
4223
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctHero, never>;
3843
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctHero, "strct-hero", never, { "status": { "alias": "status"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "heading": { "alias": "heading"; "required": true; "isSignal": true; }; "dense": { "alias": "dense"; "required": false; "isSignal": true; }; }, {}, never, ["*", "[strctHeroMeta]", "[strctHeroActions]"], true, never>;
4224
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctHero, "strct-hero", never, { "status": { "alias": "status"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "heading": { "alias": "heading"; "required": true; "isSignal": true; }; "dense": { "alias": "dense"; "required": false; "isSignal": true; }; "live": { "alias": "live"; "required": false; "isSignal": true; }; }, {}, never, ["*", "[strctHeroMeta]", "[strctHeroActions]"], true, never>;
3844
4225
  }
3845
4226
 
3846
4227
  /** Alert visual types. */
@@ -3867,10 +4248,11 @@ type StrctTooltipPosition = 'top' | 'bottom' | 'left' | 'right';
3867
4248
  * never clipped by an ancestor's `overflow`.
3868
4249
  * <button strct-button strctTooltip="More info">?</button>
3869
4250
  */
3870
- declare class StrctTooltip {
4251
+ declare class StrctTooltip implements OnDestroy {
3871
4252
  private readonly host;
3872
4253
  private readonly renderer;
3873
4254
  private readonly doc;
4255
+ private readonly bubbleId;
3874
4256
  private bubble;
3875
4257
  /** Tooltip text. */
3876
4258
  readonly strctTooltip: _angular_core.InputSignal<string>;
@@ -3878,6 +4260,9 @@ declare class StrctTooltip {
3878
4260
  readonly tooltipPosition: _angular_core.InputSignal<StrctTooltipPosition>;
3879
4261
  protected show(): void;
3880
4262
  protected hide(): void;
4263
+ protected onEscape(event: Event): void;
4264
+ protected onScroll(): void;
4265
+ ngOnDestroy(): void;
3881
4266
  private place;
3882
4267
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctTooltip, never>;
3883
4268
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<StrctTooltip, "[strctTooltip]", never, { "strctTooltip": { "alias": "strctTooltip"; "required": true; "isSignal": true; }; "tooltipPosition": { "alias": "tooltipPosition"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
@@ -3897,14 +4282,30 @@ declare class StrctSignpost {
3897
4282
  private readonly host;
3898
4283
  /** Popover placement relative to the trigger. */
3899
4284
  readonly position: _angular_core.InputSignal<StrctSignpostPosition>;
4285
+ /** Accessible name of the signpost dialog (localizable). */
4286
+ readonly ariaLabel: _angular_core.InputSignal<string>;
3900
4287
  readonly open: _angular_core.WritableSignal<boolean>;
4288
+ /** Where focus was when the popover opened — restored on Escape. */
4289
+ private lastFocused;
3901
4290
  toggle(): void;
3902
- close(): void;
4291
+ close(restore?: boolean): void;
3903
4292
  protected overlayPlacement(): StrctOverlayPlacement;
3904
4293
  protected onDocClick(event: MouseEvent): void;
3905
- protected onEscape(): void;
4294
+ protected onEscape(event: Event): void;
3906
4295
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctSignpost, never>;
3907
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctSignpost, "strct-signpost", never, { "position": { "alias": "position"; "required": false; "isSignal": true; }; }, {}, never, ["[strctSignpostTrigger]", "*"], true, never>;
4296
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctSignpost, "strct-signpost", never, { "position": { "alias": "position"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, {}, never, ["[strctSignpostTrigger]", "*"], true, never>;
4297
+ }
4298
+ /**
4299
+ * Marks (and upgrades) the signpost's trigger element. The attribute alone is
4300
+ * enough for content projection; importing the directive additionally wires
4301
+ * the toggle and `aria-haspopup` / `aria-expanded` onto the real button.
4302
+ * Put it on a native `<button>`: Enter/Space then fire a single click —
4303
+ * no keydown handlers, no double-toggle, one tab stop.
4304
+ */
4305
+ declare class StrctSignpostTrigger {
4306
+ protected readonly sp: StrctSignpost | null;
4307
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctSignpostTrigger, never>;
4308
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<StrctSignpostTrigger, "[strctSignpostTrigger]", never, {}, {}, never, never, true, never>;
3908
4309
  }
3909
4310
 
3910
4311
  /** Toast visual types. */
@@ -3921,7 +4322,27 @@ interface StrctToast {
3921
4322
  interface StrctToastOptions {
3922
4323
  type?: StrctToastType;
3923
4324
  duration?: number;
4325
+ /** Optional bold lead-in; kept in the history entry shown by the notification center. */
4326
+ title?: string;
3924
4327
  }
4328
+ /**
4329
+ * A persistent notification entry. Every shown toast is also recorded here
4330
+ * (capped ring buffer) so `<strct-notification-center>` can offer a history
4331
+ * view — toasts stay transient, the center is the persistent view. Shares the
4332
+ * toast's `id`, so callers can correlate the two.
4333
+ */
4334
+ interface StrctNotification {
4335
+ id: number;
4336
+ type: StrctToastType;
4337
+ /** Bold lead-in; '' when the toast had no title. */
4338
+ title: string;
4339
+ message: string;
4340
+ /** Epoch ms when the notification was recorded. */
4341
+ timestamp: number;
4342
+ read: boolean;
4343
+ }
4344
+ /** History ring-buffer capacity: only the newest entries survive a burst. */
4345
+ declare const STRCT_NOTIFICATION_HISTORY_LIMIT = 50;
3925
4346
  /**
3926
4347
  * Queues transient notifications. Render `<strct-toast-outlet />` once near the
3927
4348
  * app root, then call from anywhere:
@@ -3930,25 +4351,51 @@ interface StrctToastOptions {
3930
4351
  declare class StrctToastService {
3931
4352
  private counter;
3932
4353
  private readonly _toasts;
4354
+ private readonly _history;
4355
+ private readonly timers;
3933
4356
  readonly toasts: _angular_core.Signal<StrctToast[]>;
4357
+ /** Persistent entries, oldest → newest, capped at STRCT_NOTIFICATION_HISTORY_LIMIT. */
4358
+ readonly history: _angular_core.Signal<StrctNotification[]>;
4359
+ /** Unread history entries — drives the notification-center badge. */
4360
+ readonly unreadCount: _angular_core.Signal<number>;
3934
4361
  show(message: string, options?: StrctToastOptions): number;
3935
4362
  info(message: string, duration?: number): number;
3936
4363
  success(message: string, duration?: number): number;
3937
4364
  warning(message: string, duration?: number): number;
3938
4365
  critical(message: string, duration?: number): number;
4366
+ /**
4367
+ * Pause the auto-dismiss countdown (WCAG 2.2.1), e.g. while the toast is
4368
+ * hovered or focus is inside it.
4369
+ */
4370
+ pause(id: number): void;
4371
+ /** Resume the auto-dismiss countdown; it restarts from the full duration. */
4372
+ resume(id: number): void;
3939
4373
  dismiss(id: number): void;
3940
4374
  clear(): void;
4375
+ /** Flag one history entry as read (id is the one `show` returned). */
4376
+ markRead(id: number): void;
4377
+ /** Flag every history entry as read — empties the center's unread badge. */
4378
+ markAllRead(): void;
4379
+ /** Drop the whole history (transient toasts are not affected). */
4380
+ clearHistory(): void;
4381
+ private startTimer;
3941
4382
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctToastService, never>;
3942
4383
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<StrctToastService>;
3943
4384
  }
3944
- /** Renders the toast stack. Place once, typically just inside the app shell. */
4385
+ /**
4386
+ * Renders the toast stack, capped at the newest 5 toasts so a burst cannot
4387
+ * grow off-viewport. Place once, typically just inside the app shell.
4388
+ */
3945
4389
  declare class StrctToastOutlet {
3946
4390
  /** Accessible name of the notifications region (localizable). */
3947
4391
  readonly regionLabel: _angular_core.InputSignal<string>;
4392
+ /** Accessible label of the dismiss button (localizable). */
4393
+ readonly dismissLabel: _angular_core.InputSignal<string>;
3948
4394
  protected readonly service: StrctToastService;
4395
+ protected readonly toasts: _angular_core.Signal<StrctToast[]>;
3949
4396
  protected icon(type: StrctToastType): string;
3950
4397
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctToastOutlet, never>;
3951
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctToastOutlet, "strct-toast-outlet", never, { "regionLabel": { "alias": "regionLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
4398
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctToastOutlet, "strct-toast-outlet", never, { "regionLabel": { "alias": "regionLabel"; "required": false; "isSignal": true; }; "dismissLabel": { "alias": "dismissLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
3952
4399
  }
3953
4400
 
3954
4401
  /** Preset zero/permission/error states with a sensible icon + tone. */
@@ -4078,7 +4525,10 @@ declare class StrctTimeRangePicker {
4078
4525
  protected readonly draftFrom: _angular_core.WritableSignal<string>;
4079
4526
  protected readonly draftTo: _angular_core.WritableSignal<string>;
4080
4527
  protected readonly draftError: _angular_core.Signal<boolean>;
4528
+ /** Apply stays off until both drafts parse to valid, ordered dates. */
4529
+ protected readonly applyDisabled: _angular_core.Signal<boolean>;
4081
4530
  protected readonly triggerLabel: _angular_core.Signal<string>;
4531
+ constructor();
4082
4532
  protected pickPreset(p: StrctTimeRangePreset): void;
4083
4533
  protected applyAbsolute(): boolean;
4084
4534
  /** Re-resolve a preset range against "now" — call from your refresh tick. */
@@ -4117,7 +4567,16 @@ interface RenderLine {
4117
4567
  * resumes it — the Grafana/Loki convention.
4118
4568
  * - **ANSI SGR colors** (16-color + bold) parsed into safe spans — no
4119
4569
  * innerHTML — and severity tinting from `StrctLogLine.level` or, for plain
4120
- * strings, auto-detected ERROR/WARN/INFO/DEBUG tokens.
4570
+ * strings, auto-detected ERROR/WARN/INFO/DEBUG tokens. Non-SGR CSI
4571
+ * sequences (erase-in-line, cursor moves) are stripped before parsing.
4572
+ * - **Wrap mode disables virtualization**: wrapped lines have variable
4573
+ * height, which fixed-height windowing cannot compute. While wrapping is
4574
+ * active the viewer renders all lines and sizes itself from content. Past
4575
+ * `WRAP_CAP` lines wrapping falls back to nowrap (virtualization stays
4576
+ * correct) and the wrap button exposes `wrapLimitNote` as its title.
4577
+ * - **`role="log"`** announces streamed lines (implicit `aria-live="polite"`)
4578
+ * and virtualization removes off-screen lines from the a11y tree. For
4579
+ * follow-heavy streams set `[live]="false"` to force `aria-live="off"`.
4121
4580
  */
4122
4581
  declare class StrctLogViewer {
4123
4582
  /** Log lines — plain strings or `{ text, level }` objects. */
@@ -4126,14 +4585,19 @@ declare class StrctLogViewer {
4126
4585
  readonly height: _angular_core.InputSignal<number>;
4127
4586
  /** Follow the tail as new lines arrive (two-way; pauses on scroll-up). */
4128
4587
  readonly follow: _angular_core.ModelSignal<boolean>;
4129
- /** Soft-wrap long lines instead of horizontal scrolling (two-way). */
4588
+ /** Soft-wrap long lines instead of horizontal scrolling (two-way). Disables
4589
+ * virtualization; past `WRAP_CAP` lines it falls back to nowrap. */
4130
4590
  readonly wrapMode: _angular_core.ModelSignal<boolean>;
4591
+ /** Announce streamed lines (role="log" implies aria-live="polite"). Set
4592
+ * false on follow-heavy streams to force `aria-live="off"`. */
4593
+ readonly live: _angular_core.InputSignalWithTransform<boolean, unknown>;
4131
4594
  /** Auto-detect ERROR/WARN/INFO/DEBUG tokens on plain-string lines. */
4132
4595
  readonly autoLevel: _angular_core.InputSignalWithTransform<boolean, unknown>;
4133
4596
  /** Localizable strings. */
4134
4597
  readonly title: _angular_core.InputSignal<string>;
4135
4598
  readonly followLabel: _angular_core.InputSignal<string>;
4136
4599
  readonly wrapLabel: _angular_core.InputSignal<string>;
4600
+ readonly wrapLimitNote: _angular_core.InputSignal<string>;
4137
4601
  readonly linesLabel: _angular_core.InputSignal<string>;
4138
4602
  readonly emptyLabel: _angular_core.InputSignal<string>;
4139
4603
  private readonly scroller;
@@ -4141,7 +4605,15 @@ declare class StrctLogViewer {
4141
4605
  private suppressScrollEvent;
4142
4606
  private static readonly LINE_H;
4143
4607
  private static readonly OVERSCAN;
4608
+ /** Max line count for which wrap mode renders all lines unvirtualized. */
4609
+ private static readonly WRAP_CAP;
4144
4610
  protected readonly normalized: _angular_core.Signal<StrctLogLine[]>;
4611
+ /** Wrapping requested but over the cap — falls back to nowrap. */
4612
+ protected readonly wrapCapped: _angular_core.Signal<boolean>;
4613
+ /** Wrapping actually applied: variable-height lines, virtualization off. */
4614
+ protected readonly wrapActive: _angular_core.Signal<boolean>;
4615
+ /** Fixed-height windowing is only valid while lines cannot wrap. */
4616
+ protected readonly virtualized: _angular_core.Signal<boolean>;
4145
4617
  protected readonly totalHeight: _angular_core.Signal<number>;
4146
4618
  private readonly windowStart;
4147
4619
  protected readonly offsetY: _angular_core.Signal<number>;
@@ -4150,9 +4622,10 @@ declare class StrctLogViewer {
4150
4622
  protected onScroll(): void;
4151
4623
  protected toggleFollow(): void;
4152
4624
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctLogViewer, never>;
4153
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctLogViewer, "strct-log-viewer", never, { "lines": { "alias": "lines"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "follow": { "alias": "follow"; "required": false; "isSignal": true; }; "wrapMode": { "alias": "wrapMode"; "required": false; "isSignal": true; }; "autoLevel": { "alias": "autoLevel"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "followLabel": { "alias": "followLabel"; "required": false; "isSignal": true; }; "wrapLabel": { "alias": "wrapLabel"; "required": false; "isSignal": true; }; "linesLabel": { "alias": "linesLabel"; "required": false; "isSignal": true; }; "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; }, { "follow": "followChange"; "wrapMode": "wrapModeChange"; }, never, never, true, never>;
4625
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctLogViewer, "strct-log-viewer", never, { "lines": { "alias": "lines"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "follow": { "alias": "follow"; "required": false; "isSignal": true; }; "wrapMode": { "alias": "wrapMode"; "required": false; "isSignal": true; }; "live": { "alias": "live"; "required": false; "isSignal": true; }; "autoLevel": { "alias": "autoLevel"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "followLabel": { "alias": "followLabel"; "required": false; "isSignal": true; }; "wrapLabel": { "alias": "wrapLabel"; "required": false; "isSignal": true; }; "wrapLimitNote": { "alias": "wrapLimitNote"; "required": false; "isSignal": true; }; "linesLabel": { "alias": "linesLabel"; "required": false; "isSignal": true; }; "emptyLabel": { "alias": "emptyLabel"; "required": false; "isSignal": true; }; }, { "follow": "followChange"; "wrapMode": "wrapModeChange"; }, never, never, true, never>;
4154
4626
  }
4155
- /** Parse ANSI SGR sequences into class-tagged segments (16-color + bold). */
4627
+ /** Parse ANSI SGR sequences into class-tagged segments (16-color + bold).
4628
+ * Non-SGR CSI sequences (ESC[K, cursor moves, …) are stripped first. */
4156
4629
  declare function parseAnsi(text: string): LogSegment[];
4157
4630
 
4158
4631
  /** One row of a computed line diff. */
@@ -4224,7 +4697,9 @@ declare class StrctDiff {
4224
4697
  protected readonly splitRows: _angular_core.Signal<AnySplitRow[]>;
4225
4698
  /** Group rows into visible chunks and collapsible unchanged runs. */
4226
4699
  private readonly chunks;
4227
- protected expand(startIndex: number): void;
4700
+ constructor();
4701
+ protected isExpanded(startIndex: number): boolean;
4702
+ protected toggle(startIndex: number): void;
4228
4703
  protected sign(type: string): string;
4229
4704
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctDiff, never>;
4230
4705
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctDiff, "strct-diff", never, { "before": { "alias": "before"; "required": true; "isSignal": true; }; "after": { "alias": "after"; "required": true; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "context": { "alias": "context"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "language": { "alias": "language"; "required": false; "isSignal": true; }; "beforeLabel": { "alias": "beforeLabel"; "required": false; "isSignal": true; }; "afterLabel": { "alias": "afterLabel"; "required": false; "isSignal": true; }; "copyable": { "alias": "copyable"; "required": false; "isSignal": true; }; "copyAfterLabel": { "alias": "copyAfterLabel"; "required": false; "isSignal": true; }; "unchangedLabel": { "alias": "unchangedLabel"; "required": false; "isSignal": true; }; "maxHeight": { "alias": "maxHeight"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
@@ -4250,18 +4725,22 @@ declare class StrctSplitter {
4250
4725
  readonly min: _angular_core.InputSignal<number>;
4251
4726
  readonly max: _angular_core.InputSignal<number>;
4252
4727
  /** Stack panes vertically (gutter drags up/down). */
4253
- readonly vertical: _angular_core.InputSignal<boolean>;
4728
+ readonly vertical: _angular_core.InputSignalWithTransform<boolean, unknown>;
4254
4729
  /** Accessible name of the separator (localizable). */
4255
4730
  readonly gutterLabel: _angular_core.InputSignal<string>;
4256
4731
  /** Keyboard nudge step in percent. */
4257
4732
  readonly step: _angular_core.InputSignal<number>;
4258
4733
  protected readonly clamped: _angular_core.Signal<number>;
4259
- protected dragging: boolean;
4734
+ protected readonly dragging: _angular_core.WritableSignal<boolean>;
4260
4735
  private moveHandler;
4261
4736
  private upHandler;
4262
- protected onDragStart(event: MouseEvent): void;
4737
+ constructor();
4738
+ protected onDragStart(event: PointerEvent): void;
4263
4739
  private onDragMove;
4264
4740
  private onDragEnd;
4741
+ private removeDragListeners;
4742
+ /** Document direction — pointer coordinates and arrow keys are physical, panes are logical. */
4743
+ private isRtl;
4265
4744
  protected onKeydown(event: KeyboardEvent): void;
4266
4745
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctSplitter, never>;
4267
4746
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctSplitter, "strct-splitter", never, { "split": { "alias": "split"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "vertical": { "alias": "vertical"; "required": false; "isSignal": true; }; "gutterLabel": { "alias": "gutterLabel"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; }, { "split": "splitChange"; }, never, ["[strctPaneStart]", "[strctPaneEnd]"], true, never>;
@@ -4385,11 +4864,14 @@ interface StrctTourStep {
4385
4864
  * <strct-tour [(open)]="tourOpen" [steps]="steps" (finished)="done()" />
4386
4865
  *
4387
4866
  * Each step spotlights its `target` selector with a ring cut out of a dimmed
4388
- * backdrop and anchors a card next to it. Arrows / buttons step, Escape
4389
- * closes, and the card is a labeled dialog. Purely DOM-driven: targets are
4390
- * looked up when the step shows, so it works over any page.
4867
+ * backdrop and anchors a card next to it. Arrows (mirrored in RTL) / buttons
4868
+ * step, Home/End jump to the ends, Escape closes, and the card is a labeled
4869
+ * dialog: focus moves into it (Tab is trapped) and returns to the trigger on
4870
+ * close. Purely DOM-driven: targets are looked up when the step shows, so it
4871
+ * works over any page.
4391
4872
  */
4392
4873
  declare class StrctTour {
4874
+ private readonly elementRef;
4393
4875
  /** Whether the tour is showing (two-way). */
4394
4876
  readonly open: _angular_core.ModelSignal<boolean>;
4395
4877
  /** The steps, in order. */
@@ -4405,6 +4887,9 @@ declare class StrctTour {
4405
4887
  protected readonly index: _angular_core.WritableSignal<number>;
4406
4888
  /** Bumped on open/step/resize to re-measure the target. */
4407
4889
  private readonly measureTick;
4890
+ protected readonly titleId: string;
4891
+ /** Element that had focus before the tour opened, restored on close. */
4892
+ private previousActive;
4408
4893
  protected readonly current: _angular_core.Signal<StrctTourStep>;
4409
4894
  protected readonly spot: _angular_core.Signal<{
4410
4895
  top: number;
@@ -4420,8 +4905,22 @@ declare class StrctTour {
4420
4905
  protected next(): void;
4421
4906
  protected prev(): void;
4422
4907
  protected close(): void;
4908
+ /** Wrap Tab focus within the card. */
4909
+ protected onTab(event: Event): void;
4910
+ /** Escape closes; stopPropagation so a host modal/drawer does not also close. */
4911
+ protected onEscapeKey(event: Event): void;
4912
+ /**
4913
+ * Arrow keys step through the tour, mirrored under RTL. No shared direction
4914
+ * helper exists (other components handle RTL in CSS only), so read the
4915
+ * card's computed direction here.
4916
+ */
4917
+ protected onArrow(event: Event, dir: 'left' | 'right'): void;
4918
+ /** Home/End jump to the first/last step. */
4919
+ protected onHomeEnd(event: Event, last: boolean): void;
4423
4920
  private scrollToTarget;
4424
- protected onEscape(): void;
4921
+ private card;
4922
+ /** Move focus to the step's primary (Next/Done) action once the card has rendered. */
4923
+ private focusNextButton;
4425
4924
  protected onReflow(): void;
4426
4925
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctTour, never>;
4427
4926
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctTour, "strct-tour", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "steps": { "alias": "steps"; "required": true; "isSignal": true; }; "nextLabel": { "alias": "nextLabel"; "required": false; "isSignal": true; }; "backLabel": { "alias": "backLabel"; "required": false; "isSignal": true; }; "skipLabel": { "alias": "skipLabel"; "required": false; "isSignal": true; }; "doneLabel": { "alias": "doneLabel"; "required": false; "isSignal": true; }; }, { "open": "openChange"; "finished": "finished"; "dismissed": "dismissed"; }, never, never, true, never>;
@@ -4439,9 +4938,11 @@ interface StrctMenubarItem {
4439
4938
  *
4440
4939
  * <strct-menubar [menus]="menus" (picked)="run($event)" />
4441
4940
  *
4442
- * Click (or Enter/Down) opens a menu; Left/Right move across the bar and,
4443
- * while open, switch the open menu (the APG menubar convention). Escape and
4444
- * outside click close. `(picked)` carries `{ menu, item }`.
4941
+ * Click (or Enter/Down) opens a menu and focus moves into it; Left/Right move
4942
+ * across the bar and, while open, switch the open menu (the APG menubar
4943
+ * convention). Up/Down (+Home/End) rove the open menu, Right/Left enter and
4944
+ * leave an item's one-level `children` submenu. Escape and outside click
4945
+ * close, returning focus to the bar. `(picked)` carries `{ menu, item }`.
4445
4946
  */
4446
4947
  declare class StrctMenubar {
4447
4948
  private readonly host;
@@ -4456,11 +4957,24 @@ declare class StrctMenubar {
4456
4957
  }>;
4457
4958
  protected readonly openId: _angular_core.WritableSignal<string | null>;
4458
4959
  protected readonly focusIdx: _angular_core.WritableSignal<number>;
4960
+ /** Index of the item whose one-level submenu is open. */
4961
+ protected readonly subIdx: _angular_core.WritableSignal<number | null>;
4962
+ /** Top-level button that opened the menu — focus returns here on close. */
4963
+ private trigger;
4459
4964
  protected toggleMenu(id: string, i: number): void;
4965
+ protected onItemClick(menu: StrctMenubarItem, item: StrctMenuItem, i: number): void;
4966
+ protected onItemHover(item: StrctMenuItem, i: number): void;
4460
4967
  protected pick(menu: StrctMenubarItem, item: StrctMenuItem): void;
4461
4968
  protected onTopKey(event: KeyboardEvent, i: number): void;
4969
+ protected onMenuKey(event: KeyboardEvent, menu: StrctMenubarItem): void;
4970
+ /** Switch the open menu to the next/previous top-level entry; focus follows. */
4971
+ private switchTop;
4972
+ private closeMenu;
4973
+ private topButtons;
4974
+ /** Enabled item buttons of the open menu — either its items or the open submenu's. */
4975
+ private navButtons;
4462
4976
  protected onDocClick(event: MouseEvent): void;
4463
- protected onEscape(): void;
4977
+ protected onEscape(event: Event): void;
4464
4978
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctMenubar, never>;
4465
4979
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctMenubar, "strct-menubar", never, { "menus": { "alias": "menus"; "required": true; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "picked": "picked"; }, never, never, true, never>;
4466
4980
  }
@@ -4477,7 +4991,8 @@ declare class StrctMenubar {
4477
4991
  */
4478
4992
  declare class StrctAnnouncer implements OnDestroy {
4479
4993
  private regions;
4480
- private clearTimer;
4994
+ private clearTimers;
4995
+ private readonly isBrowser;
4481
4996
  announce(message: string, politeness?: 'polite' | 'assertive'): void;
4482
4997
  private regionFor;
4483
4998
  ngOnDestroy(): void;
@@ -4487,7 +5002,7 @@ declare class StrctAnnouncer implements OnDestroy {
4487
5002
 
4488
5003
  /** A registered application hotkey. */
4489
5004
  interface StrctHotkey {
4490
- /** Combo like `'ctrl+k'`, `'meta+shift+p'`, `'?'` — `mod` = Ctrl/⌘. */
5005
+ /** Combo like `'ctrl+k'`, `'meta+shift+p'`, `'shift+?'` — `mod` = Ctrl/⌘. */
4491
5006
  combo: string;
4492
5007
  /** Human description shown in the help overlay. */
4493
5008
  description: string;
@@ -4504,7 +5019,7 @@ interface StrctHotkey {
4504
5019
  * { combo: 'mod+k', description: 'Open command palette', group: 'Global',
4505
5020
  * handler: () => this.palette.open() }); }
4506
5021
  *
4507
- * Combos: `'a'`, `'?'`, `'ctrl+k'`, `'meta+shift+p'`, `'mod+k'` (mod = Ctrl/⌘).
5022
+ * Combos: `'a'`, `'shift+?'`, `'ctrl+k'`, `'meta+shift+p'`, `'mod+k'` (mod = Ctrl/⌘).
4508
5023
  * Plain-key combos are suppressed while typing in inputs / textareas /
4509
5024
  * contenteditable; modifier combos always fire. Pair with
4510
5025
  * `<strct-hotkeys-help/>` for the ⌘/ ("?") cheatsheet overlay.
@@ -4524,26 +5039,31 @@ declare class StrctHotkeysService implements OnDestroy {
4524
5039
  }
4525
5040
  /**
4526
5041
  * The hotkey cheatsheet overlay. Mount once near the app root; it registers
4527
- * `?` itself and lists everything in the service, grouped:
5042
+ * `shift+?` (typed as `?`) itself and lists everything in the service, grouped:
4528
5043
  *
4529
5044
  * <strct-hotkeys-help />
4530
5045
  */
4531
5046
  declare class StrctHotkeysHelp {
4532
5047
  private readonly service;
5048
+ private readonly host;
4533
5049
  /** Overlay visibility (two-way; `?` toggles it too). */
4534
5050
  readonly open: _angular_core.ModelSignal<boolean>;
4535
5051
  /** Localizable strings. */
4536
5052
  readonly title: _angular_core.InputSignal<string>;
4537
5053
  readonly emptyText: _angular_core.InputSignal<string>;
5054
+ /** Accessible label of the × close button (localizable). */
5055
+ readonly closeLabel: _angular_core.InputSignal<string>;
5056
+ /** Element that had focus before the overlay opened, restored on close. */
5057
+ private previousActive;
4538
5058
  protected readonly grouped: _angular_core.Signal<{
4539
5059
  name: string;
4540
5060
  keys: StrctHotkey[];
4541
5061
  }[]>;
4542
5062
  constructor();
4543
- protected onEscape(): void;
5063
+ protected onEscape(event: Event): void;
4544
5064
  protected parts(combo: string): string[];
4545
5065
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctHotkeysHelp, never>;
4546
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctHotkeysHelp, "strct-hotkeys-help", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, never, true, never>;
5066
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctHotkeysHelp, "strct-hotkeys-help", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "closeLabel": { "alias": "closeLabel"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, never, true, never>;
4547
5067
  }
4548
5068
 
4549
5069
  /** A completed reorder: move the item at `from` to `to` in your array. */
@@ -4567,20 +5087,43 @@ interface StrctReorderEvent {
4567
5087
  * Items are HTML5-draggable; keyboard reorder is Alt+ArrowUp / Alt+ArrowDown
4568
5088
  * on the focused item (items get `tabindex="0"` unless they already manage
4569
5089
  * focus). Indexes are positions among the `strctReorderItem` siblings.
5090
+ * Completed moves are announced in a live region (see `announcement`) and
5091
+ * items reference the sr-only `instructions` via `aria-describedby`.
4570
5092
  */
4571
- declare class StrctReorder {
5093
+ declare class StrctReorder implements OnDestroy {
4572
5094
  private readonly host;
5095
+ private readonly renderer;
5096
+ private readonly doc;
5097
+ private readonly announcer;
4573
5098
  /** Emits when a drag or keyboard move completes. */
4574
5099
  readonly reordered: _angular_core.OutputEmitterRef<StrctReorderEvent>;
4575
5100
  /** Disable all reordering (display-only mode). */
4576
- readonly reorderDisabled: _angular_core.InputSignal<boolean>;
5101
+ readonly reorderDisabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
5102
+ /**
5103
+ * Keyboard instructions (localizable), rendered sr-only and referenced by
5104
+ * every item's `aria-describedby`. Set to '' to opt out.
5105
+ */
5106
+ readonly instructions: _angular_core.InputSignal<string>;
5107
+ /**
5108
+ * Builds the live-region announcement after a move (localizable):
5109
+ * (moved item's text, new 1-based position, item count).
5110
+ */
5111
+ readonly announcement: _angular_core.InputSignal<(label: string, position: number, total: number) => string>;
4577
5112
  readonly dragIndex: _angular_core.WritableSignal<number | null>;
4578
5113
  readonly overIndex: _angular_core.WritableSignal<number | null>;
5114
+ /** Id of the sr-only instructions element the items point to. */
5115
+ readonly instructionsId: string;
5116
+ private hint;
5117
+ constructor();
4579
5118
  items(): HTMLElement[];
4580
5119
  indexOf(el: HTMLElement): number;
4581
5120
  commit(from: number, to: number): void;
5121
+ protected onContainerDragOver(event: DragEvent): void;
5122
+ protected onContainerDrop(event: DragEvent): void;
5123
+ protected onDragLeave(event: DragEvent): void;
5124
+ ngOnDestroy(): void;
4582
5125
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctReorder, never>;
4583
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<StrctReorder, "[strctReorder]", never, { "reorderDisabled": { "alias": "reorderDisabled"; "required": false; "isSignal": true; }; }, { "reordered": "reordered"; }, never, never, true, never>;
5126
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<StrctReorder, "[strctReorder]", never, { "reorderDisabled": { "alias": "reorderDisabled"; "required": false; "isSignal": true; }; "instructions": { "alias": "instructions"; "required": false; "isSignal": true; }; "announcement": { "alias": "announcement"; "required": false; "isSignal": true; }; }, { "reordered": "reordered"; }, never, never, true, never>;
4584
5127
  }
4585
5128
  /** One draggable row inside a `[strctReorder]` container. */
4586
5129
  declare class StrctReorderItem {
@@ -4590,7 +5133,7 @@ declare class StrctReorderItem {
4590
5133
  protected hostTabindex(): number | null;
4591
5134
  protected isDragging(): boolean;
4592
5135
  protected isOver(): boolean;
4593
- private index;
5136
+ protected index(): number;
4594
5137
  protected onDragStart(event: DragEvent): void;
4595
5138
  protected onDragOver(event: DragEvent): void;
4596
5139
  protected onDrop(event: DragEvent): void;
@@ -4600,5 +5143,633 @@ declare class StrctReorderItem {
4600
5143
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<StrctReorderItem, "[strctReorderItem]", never, {}, {}, never, never, true, never>;
4601
5144
  }
4602
5145
 
4603
- export { STRCT_ICONS, STRCT_ICON_GROUPS, STRCT_ICON_NAMES, STRCT_MASKS, STRCT_PALETTES, STRCT_RAW_ICONS, STRCT_TIME_RANGE_PRESETS, STRCT_WIZARD_DEFAULTS, StrctAccordion, StrctAccordionPanel, StrctAlert, StrctAnnouncer, StrctAvatar, StrctBadge, StrctBreadcrumb, StrctBreadcrumbItem, StrctButton, StrctButtonGroup, StrctBytesPipe, StrctCard, StrctCardBlock, StrctCardFooter, StrctCardHeader, StrctCascadeHost, StrctCascadeNode, StrctCascadeSelect, StrctCellDef, StrctCellStatus, StrctChart, StrctCheckbox, StrctChips, StrctCode, StrctColorPicker, StrctCombobox, StrctCommandPalette, StrctContextMenu, StrctContextMenuTrigger, StrctCopy, StrctDatagrid, StrctDatagridActionBar, StrctDatepicker, StrctDesc, StrctDescriptionList, StrctDiff, StrctDivider, StrctDonut, StrctDrawer, StrctDrawerFooter, StrctDropdown, StrctDropdownDivider, StrctDropdownItem, StrctDropdownTrigger, StrctDurationPipe, StrctEmptyState, StrctField, StrctFile, StrctFilterBar, StrctFlow, StrctFooter, StrctGauge, StrctHeader, StrctHero, StrctHotkeysHelp, StrctHotkeysService, StrctIcon, StrctInput, StrctInputMask, StrctInputOtp, StrctKbd, StrctKnob, StrctLogViewer, StrctLogin, StrctMenuPanel, StrctMenuService, StrctMenubar, StrctMetricTile, StrctModal, StrctNav, StrctNavItem, StrctOverlay, StrctPageHeader, StrctPageHeaderActions, StrctPageHeaderCrumbs, StrctPagination, StrctPassword, StrctProgress, StrctRadio, StrctRadioGroup, StrctRail, StrctRange, StrctRatePipe, StrctRating, StrctReorder, StrctReorderItem, StrctRowDetailDef, StrctSearchbox, StrctSectionMenu, StrctSegmented, StrctSelect, StrctShell, StrctShellService, StrctSiPipe, StrctSignpost, StrctSkeleton, StrctSparkline, StrctSpeedDial, StrctSpinner, StrctSplitButton, StrctSplitter, StrctStack, StrctStackItem, StrctStep, StrctSubmenu, StrctTab, StrctTable, StrctTabs, StrctTag, StrctThemeService, StrctThemeSwitcher, StrctTimeRangePicker, StrctTimeline, StrctTimelineItem, StrctToastOutlet, StrctToastService, StrctToggle, StrctTooltip, StrctTour, StrctTransfer, StrctTree, StrctTreeNode, StrctVerticalNav, StrctWatermark, StrctWizard, StrctWizardAside, parseAnsi, provideStrctWizardDefaults, registerStrctIcon, strctComputeDiff, strctFormatBytes, strctFormatDuration, strctFormatRate, strctFormatSi, strctValidationIcon, strctValidationTone };
4604
- export type { StrctAlertType, StrctAvatarSize, StrctAvatarStatus, StrctBadgeStatus, StrctButtonSize, StrctButtonVariant, StrctCascadeOption, StrctCellContext, StrctChartAnnotation, StrctChartColor, StrctChartCurve, StrctChartSeries, StrctChartSlot, StrctChartStatus, StrctChartThreshold, StrctChartType, StrctColumn, StrctCommandItem, StrctDatagridColumn, StrctDatagridColumnState, StrctDatagridFilters, StrctDatagridLabels, StrctDatagridLazyState, StrctDescAlign, StrctDescItem, StrctDiffRow, StrctDonutSegment, StrctDrawerSide, StrctDrawerSize, StrctEmptyVariant, StrctFilterChip, StrctFlowDirection, StrctFlowNode, StrctFlowOrientation, StrctHotkey, StrctIconBadge, StrctIconName, StrctKnobStatus, StrctLogLine, StrctMenuItem, StrctMenuLink, StrctMenuOpenOptions, StrctMenuSection, StrctMenubarItem, StrctMetricStatus, StrctModalSize, StrctMode, StrctOption, StrctOverlayPlacement, StrctPalette, StrctPaletteInfo, StrctProgressStatus, StrctRailItem, StrctRailStatus, StrctReorderEvent, StrctRow, StrctRowId, StrctSegmentedOption, StrctSegmentedSize, StrctSignpostPosition, StrctSpeedDialDirection, StrctSpinnerSize, StrctStatus, StrctTagStatus, StrctThresholds, StrctTimeRange, StrctTimeRangePreset, StrctTimelineState, StrctToast, StrctToastOptions, StrctToastType, StrctTooltipPosition, StrctTourStep, StrctTransferItem, StrctTreeMenuEvent, StrctTreeNodeData, StrctTreeNodeMenuFn, StrctValidationState, StrctValidationStatus, StrctWizardDefaults };
5146
+ /**
5147
+ * Shared focus-lifecycle helpers for transient overlay surfaces (tooltip,
5148
+ * drawer, menus, popovers …): remember the trigger before opening, move
5149
+ * focus in on open, cycle Tab inside, and hand focus back on close.
5150
+ * Modeled on the modal's local implementation (`modal/modal.ts`).
5151
+ */
5152
+ /** Elements considered tabbable inside an overlay, queried in DOM order. */
5153
+ declare const FOCUSABLE_SELECTOR = "a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"])";
5154
+ /** Currently focused element, if it is an HTMLElement (remember the trigger before opening). */
5155
+ declare function saveFocusedElement(): HTMLElement | null;
5156
+ /** Focus `el` again if it is still in the document; null-safe. */
5157
+ declare function restoreFocus(el: HTMLElement | null | undefined): void;
5158
+ /**
5159
+ * Focus the first tabbable descendant of `container`.
5160
+ * Returns whether something was focused; with nothing tabbable the container
5161
+ * itself is NOT focused — the caller decides the fallback.
5162
+ */
5163
+ declare function focusFirstIn(container: HTMLElement): boolean;
5164
+ /**
5165
+ * Tab trap for modal-ish overlays: cycle Tab/Shift+Tab within the
5166
+ * container's tabbable descendants, wrapping at both ends (preventDefault
5167
+ * when it wraps). Wire it to the container's `keydown.tab` /
5168
+ * `keydown.shift.tab` events.
5169
+ */
5170
+ declare function keepTabInside(event: KeyboardEvent, container: HTMLElement): void;
5171
+
5172
+ /** Acquire a scroll lock: hides body overflow on the first acquisition. */
5173
+ declare function lockBodyScroll(doc: Document): void;
5174
+ /** Release a scroll lock: restores the saved body overflow on the last release. */
5175
+ declare function unlockBodyScroll(doc: Document): void;
5176
+
5177
+ /** Dot sizes: `sm` for dense rows (tables, menus), `md` standalone. */
5178
+ type StrctStatusDotSize = 'sm' | 'md';
5179
+ /**
5180
+ * Presence/state dot that never relies on colour alone: the tone is painted by
5181
+ * a pure-CSS dot while the state is also rendered as visually-hidden text, so
5182
+ * screen readers (and colour-blind users copying text) get "Warning", not just
5183
+ * a yellow circle. Use it inside avatars, menu rows, metric tiles — anywhere a
5184
+ * bare coloured dot would otherwise carry meaning.
5185
+ *
5186
+ * <strct-status-dot status="success" />
5187
+ * <strct-status-dot status="critical" size="sm" label="Node unreachable" />
5188
+ */
5189
+ declare class StrctStatusDot {
5190
+ /** Status tone (canonical vocabulary: OK = 'success', info = 'accent'). */
5191
+ readonly status: _angular_core.InputSignal<StrctStatus>;
5192
+ /**
5193
+ * Accessible text describing the state (localizable). Empty falls back to a
5194
+ * per-status default ("OK", "Warning", …) so the dot is never color-only.
5195
+ */
5196
+ readonly label: _angular_core.InputSignal<string>;
5197
+ /** Dot size: `sm` for dense rows, `md` standalone. */
5198
+ readonly size: _angular_core.InputSignal<StrctStatusDotSize>;
5199
+ protected readonly text: _angular_core.Signal<string>;
5200
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctStatusDot, never>;
5201
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctStatusDot, "strct-status-dot", never, { "status": { "alias": "status"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
5202
+ }
5203
+
5204
+ /**
5205
+ * Numeric stepper input: − / + buttons flanking a text field. The value is
5206
+ * `number | null` (null = empty); typing is free-form (intermediate states
5207
+ * like "-" are kept), committed values clamp to `min`/`max` on blur, and the
5208
+ * buttons + keyboard always clamp immediately.
5209
+ *
5210
+ * <strct-number [min]="0" [max]="64" [step]="4" [(ngModel)]="vcpus" />
5211
+ *
5212
+ * Keyboard on the field: ArrowUp/Down ±step, PageUp/Down ±10×step,
5213
+ * Home/End jump to min/max. The field exposes `role="spinbutton"` with
5214
+ * aria-valuemin/max/now so assistive tech announces it as a number control.
5215
+ */
5216
+ declare class StrctNumber implements ControlValueAccessor {
5217
+ /** Minimum allowed value; null = unbounded. */
5218
+ readonly min: _angular_core.InputSignal<number | null>;
5219
+ /** Maximum allowed value; null = unbounded. */
5220
+ readonly max: _angular_core.InputSignal<number | null>;
5221
+ /** Step increment for buttons and Arrow keys (PageUp/Down use 10×). */
5222
+ readonly step: _angular_core.InputSignal<number>;
5223
+ /** Placeholder text when empty. */
5224
+ readonly placeholder: _angular_core.InputSignal<string>;
5225
+ /** Accessible label of the + button (localizable). */
5226
+ readonly incrementLabel: _angular_core.InputSignal<string>;
5227
+ /** Accessible label of the − button (localizable). */
5228
+ readonly decrementLabel: _angular_core.InputSignal<string>;
5229
+ /** Static disable; forms' setDisabledState also drives the disabled state. */
5230
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
5231
+ readonly value: _angular_core.WritableSignal<number | null>;
5232
+ /** Raw field text — may hold an unparseable intermediate state while typing. */
5233
+ protected readonly text: _angular_core.WritableSignal<string>;
5234
+ /** Disabled state pushed by the forms API (setDisabledState). */
5235
+ private readonly cvaDisabled;
5236
+ readonly isDisabled: _angular_core.Signal<boolean>;
5237
+ /** At/below min (or min unset → never) — greys out the − button. */
5238
+ protected readonly atMin: _angular_core.Signal<boolean>;
5239
+ /** At/above max (or max unset → never) — greys out the + button. */
5240
+ protected readonly atMax: _angular_core.Signal<boolean>;
5241
+ private onChange;
5242
+ protected onTouched: () => void;
5243
+ protected onInput(event: Event): void;
5244
+ protected onKeydown(event: KeyboardEvent): void;
5245
+ /** Commit the pending text on blur: parse, clamp, restore on garbage. */
5246
+ protected onBlur(): void;
5247
+ /** Button / keyboard step: an empty field first lands on min (or 0). */
5248
+ protected stepBy(dir: 1 | -1, factor?: number): void;
5249
+ private commitTo;
5250
+ private clamp;
5251
+ /** Trim float dust from step arithmetic (0.1 + 0.2), not a grid snap. */
5252
+ private snap;
5253
+ writeValue(value: number | null): void;
5254
+ registerOnChange(fn: (value: number | null) => void): void;
5255
+ registerOnTouched(fn: () => void): void;
5256
+ setDisabledState(isDisabled: boolean): void;
5257
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctNumber, never>;
5258
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctNumber, "strct-number", never, { "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "incrementLabel": { "alias": "incrementLabel"; "required": false; "isSignal": true; }; "decrementLabel": { "alias": "decrementLabel"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
5259
+ }
5260
+
5261
+ /**
5262
+ * A generic anchored overlay panel for arbitrary projected content — the
5263
+ * public primitive behind menus, signposts and rich pickers:
5264
+ * <strct-popover placement="bottom-end" ariaLabel="More actions">
5265
+ * <button strct-button strctPopoverTrigger>Actions</button>
5266
+ * <p>Any content — text, lists or controls…</p>
5267
+ * </strct-popover>
5268
+ *
5269
+ * `open` is two-way, so the panel can also be driven from the outside:
5270
+ * <strct-popover [(open)]="show">…</strct-popover>
5271
+ *
5272
+ * Positioning, edge-flip and scroll/resize tracking come from StrctOverlay;
5273
+ * the panel is `position: fixed`, so it escapes ancestor overflow clipping.
5274
+ */
5275
+ declare class StrctPopover {
5276
+ private readonly host;
5277
+ private readonly panelRef;
5278
+ /** Whether the panel is open (two-way). */
5279
+ readonly open: _angular_core.ModelSignal<boolean>;
5280
+ /** Panel placement relative to the trigger; edge-flip is automatic. */
5281
+ readonly placement: _angular_core.InputSignal<StrctOverlayPlacement>;
5282
+ /** Accessible name of the popover dialog (localizable). */
5283
+ readonly ariaLabel: _angular_core.InputSignal<string>;
5284
+ /**
5285
+ * Modal-ish usage: move focus into the panel on open, trap Tab inside and
5286
+ * hand focus back to the trigger on close. Off by default — a plain popover
5287
+ * never steals focus and Tab moves on freely.
5288
+ */
5289
+ readonly trap: _angular_core.InputSignalWithTransform<boolean, unknown>;
5290
+ /** Where focus was when the panel opened — restored on Escape / trap close. */
5291
+ private lastFocused;
5292
+ constructor();
5293
+ toggle(): void;
5294
+ close(restore?: boolean): void;
5295
+ /** Wrap Tab within the panel in trap mode; a no-op otherwise. */
5296
+ protected onTab(event: Event): void;
5297
+ protected onDocClick(event: MouseEvent): void;
5298
+ protected onEscape(event: Event): void;
5299
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctPopover, never>;
5300
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctPopover, "strct-popover", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "placement": { "alias": "placement"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "trap": { "alias": "trap"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["[strctPopoverTrigger]", "*"], true, never>;
5301
+ }
5302
+ /**
5303
+ * Marks (and upgrades) the popover's trigger element. The attribute alone is
5304
+ * enough for content projection; importing the directive additionally wires
5305
+ * the toggle and `aria-haspopup` / `aria-expanded` onto the real button.
5306
+ * Put it on a native `<button>`: Enter/Space then fire a single click —
5307
+ * no keydown handlers, no double-toggle, one tab stop.
5308
+ */
5309
+ declare class StrctPopoverTrigger {
5310
+ protected readonly popover: StrctPopover | null;
5311
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctPopoverTrigger, never>;
5312
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<StrctPopoverTrigger, "[strctPopoverTrigger]", never, {}, {}, never, never, true, never>;
5313
+ }
5314
+
5315
+ /** Confirm-dialog tone: `critical` styles the confirm button as destructive. */
5316
+ type StrctConfirmTone = 'default' | 'critical';
5317
+ /** Options passed when asking for confirmation. */
5318
+ interface StrctConfirmOptions {
5319
+ /** Dialog title. */
5320
+ title: string;
5321
+ /** Body text spelling out the consequences. */
5322
+ message: string;
5323
+ /** Confirm button label — falls back to the outlet's `confirmLabel`. */
5324
+ confirmLabel?: string;
5325
+ /** Cancel button label — falls back to the outlet's `cancelLabel`. */
5326
+ cancelLabel?: string;
5327
+ /** `critical` renders the confirm button in the destructive tone. */
5328
+ tone?: StrctConfirmTone;
5329
+ }
5330
+ /** A pending confirmation, with its promise resolver attached. */
5331
+ interface StrctConfirmRequest extends StrctConfirmOptions {
5332
+ resolve: (ok: boolean) => void;
5333
+ }
5334
+ /**
5335
+ * Promise-based confirmation for destructive actions. Render
5336
+ * `<strct-confirm-outlet />` once near the app root, then await from anywhere:
5337
+ * if (await inject(StrctConfirmService).confirm({ title: 'Delete row?', message: '…', tone: 'critical' })) { … }
5338
+ */
5339
+ declare class StrctConfirmService {
5340
+ private readonly _active;
5341
+ /** The confirmation currently on screen, if any. */
5342
+ readonly active: _angular_core.Signal<StrctConfirmRequest | null>;
5343
+ /**
5344
+ * Ask the user to confirm; resolves `true` on confirm, `false` on cancel,
5345
+ * the X, Escape or a backdrop click. One dialog at a time — a new call
5346
+ * cancels (resolves `false`) the pending one.
5347
+ */
5348
+ confirm(options: StrctConfirmOptions): Promise<boolean>;
5349
+ /** Resolve the pending confirmation and close the dialog. */
5350
+ settle(result: boolean): void;
5351
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctConfirmService, never>;
5352
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<StrctConfirmService>;
5353
+ }
5354
+ /**
5355
+ * Renders the active confirmation as a small strct-modal (focus trap, Escape /
5356
+ * backdrop dismissal and focus restore included). Place once, typically just
5357
+ * inside the app shell. The default labels are inputs, so an app can localize
5358
+ * every confirm() call in one place.
5359
+ */
5360
+ declare class StrctConfirmOutlet {
5361
+ /** Default confirm button label (localizable). */
5362
+ readonly confirmLabel: _angular_core.InputSignal<string>;
5363
+ /** Default cancel button label (localizable). */
5364
+ readonly cancelLabel: _angular_core.InputSignal<string>;
5365
+ /** Accessible label of the X close button (localizable). */
5366
+ readonly closeLabel: _angular_core.InputSignal<string>;
5367
+ protected readonly service: StrctConfirmService;
5368
+ protected readonly req: _angular_core.Signal<StrctConfirmRequest | null>;
5369
+ private readonly host;
5370
+ /** The request the safe-default focus was already applied for. */
5371
+ private focusedFor;
5372
+ constructor();
5373
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctConfirmOutlet, never>;
5374
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctConfirmOutlet, "strct-confirm-outlet", never, { "confirmLabel": { "alias": "confirmLabel"; "required": false; "isSignal": true; }; "cancelLabel": { "alias": "cancelLabel"; "required": false; "isSignal": true; }; "closeLabel": { "alias": "closeLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
5375
+ }
5376
+
5377
+ /**
5378
+ * Tree picker in a dropdown: a trigger button wearing the shared
5379
+ * `.strct-control` look opens an overlay panel hosting the data-driven
5380
+ * `<strct-tree>`. CVA-compatible single-select of a node key (`id`, falling
5381
+ * back to `label` — the same key the tree uses for `expandedIds`); the
5382
+ * trigger shows the selected node's full label path (`Parent / Child`).
5383
+ *
5384
+ * <strct-tree-select [nodes]="tree" [(ngModel)]="nodeId" clearable />
5385
+ *
5386
+ * Keyboard: ArrowDown/Enter/Space open from the trigger; inside the panel the
5387
+ * tree's own ARIA pattern applies (arrows rove, Right/Left expand/collapse,
5388
+ * typeahead jumps, Enter picks). Escape closes (stopPropagation, so a host
5389
+ * modal/drawer stays open); focus returns to the trigger on close.
5390
+ */
5391
+ declare class StrctTreeSelect implements ControlValueAccessor {
5392
+ private readonly host;
5393
+ /** Root nodes rendered by the embedded `<strct-tree>` (data-driven mode). */
5394
+ readonly nodes: _angular_core.InputSignal<StrctTreeNodeData[]>;
5395
+ /** Placeholder text when empty (localizable). */
5396
+ readonly placeholder: _angular_core.InputSignal<string>;
5397
+ /** Show an × that resets the selection. */
5398
+ readonly clearable: _angular_core.InputSignalWithTransform<boolean, unknown>;
5399
+ /** Text shown when `nodes` is empty (localizable). */
5400
+ readonly emptyText: _angular_core.InputSignal<string>;
5401
+ /** Accessible label of the × clear button (localizable). */
5402
+ readonly clearLabel: _angular_core.InputSignal<string>;
5403
+ /** Static disable; forms' setDisabledState also drives the disabled state. */
5404
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
5405
+ readonly value: _angular_core.WritableSignal<string | null>;
5406
+ readonly open: _angular_core.WritableSignal<boolean>;
5407
+ /**
5408
+ * Expansion state handed to the tree (controlled). Seeded with the selected
5409
+ * node's ancestors on open so the current pick is visible; afterwards owned
5410
+ * by the tree through the two-way binding.
5411
+ */
5412
+ readonly expandedIds: _angular_core.WritableSignal<string[] | null>;
5413
+ /** Disabled state pushed by the forms API (setDisabledState). */
5414
+ private readonly cvaDisabled;
5415
+ readonly isDisabled: _angular_core.Signal<boolean>;
5416
+ /** Element focused before the panel opened — focus returns here on close. */
5417
+ private restoreTo;
5418
+ private onChange;
5419
+ private onTouched;
5420
+ /** Stable key for a node: its `id`, or the `label` as a fallback (tree idiom). */
5421
+ private keyOf;
5422
+ /** The tree data with `active` flagged on the selected node (highlight + focus target). */
5423
+ protected readonly displayNodes: _angular_core.Signal<StrctTreeNodeData[]>;
5424
+ /** Full label path of the selected node, joined with ` / ` ("Parent / Child"). */
5425
+ protected readonly selectedLabel: _angular_core.Signal<string>;
5426
+ protected readonly showClear: _angular_core.Signal<boolean>;
5427
+ /** Chain of nodes from a root down to the node with key `v` (null when absent). */
5428
+ private findPath;
5429
+ toggle(): void;
5430
+ openPanel(): void;
5431
+ closePanel(): void;
5432
+ /**
5433
+ * ArrowDown/Enter/Space open the panel from the trigger. preventDefault so
5434
+ * Space doesn't scroll the page and Enter/Space don't also fire the native
5435
+ * button click (which would toggle the panel straight back shut).
5436
+ */
5437
+ protected onTriggerKeydown(event: KeyboardEvent): void;
5438
+ /** Escape inside the panel (the tree's rows don't handle it themselves). */
5439
+ protected onPanelKeydown(event: KeyboardEvent): void;
5440
+ /** Commit a node pick: its key becomes the value and the panel closes. */
5441
+ pick(node: StrctTreeNodeData): void;
5442
+ protected clear(event: Event): void;
5443
+ protected onDocClick(event: MouseEvent): void;
5444
+ protected onEscape(event: Event): void;
5445
+ writeValue(value: string | null): void;
5446
+ registerOnChange(fn: (value: string | null) => void): void;
5447
+ registerOnTouched(fn: () => void): void;
5448
+ setDisabledState(isDisabled: boolean): void;
5449
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctTreeSelect, never>;
5450
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctTreeSelect, "strct-tree-select", never, { "nodes": { "alias": "nodes"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
5451
+ }
5452
+
5453
+ /**
5454
+ * Date + time in one control — a thin composition over the existing
5455
+ * `<strct-datepicker>` (calendar, keyboard grid, focus lifecycle and Escape
5456
+ * handling included) plus hour/minute selects, sharing one `.strct-control`
5457
+ * field skin. The value is an ISO local datetime string `YYYY-MM-DDTHH:mm`;
5458
+ * CVA-compatible.
5459
+ *
5460
+ * <strct-datetime-picker [(ngModel)]="stamp" [minuteStep]="15" />
5461
+ *
5462
+ * The calendar localization inputs (`monthNames`, `weekdayNames`,
5463
+ * `weekdayNamesFull`, `weekStart`, `prevMonthLabel`, `nextMonthLabel`) are
5464
+ * passed straight through to the embedded datepicker. Picking a time before a
5465
+ * date keeps the value empty until a date is picked.
5466
+ */
5467
+ declare class StrctDatetimePicker implements ControlValueAccessor {
5468
+ /** Placeholder text of the date input when empty (localizable). */
5469
+ readonly placeholder: _angular_core.InputSignal<string>;
5470
+ /** Minute granularity of the minute select (1 = every minute). */
5471
+ readonly minuteStep: _angular_core.InputSignal<number>;
5472
+ /** Calendar localization — passed straight through to the embedded datepicker. */
5473
+ readonly monthNames: _angular_core.InputSignal<string[]>;
5474
+ readonly weekdayNames: _angular_core.InputSignal<string[]>;
5475
+ readonly weekdayNamesFull: _angular_core.InputSignal<string[]>;
5476
+ /** First day of the week: 0 = Sunday, 1 = Monday, … 6 = Saturday. */
5477
+ readonly weekStart: _angular_core.InputSignal<number>;
5478
+ readonly prevMonthLabel: _angular_core.InputSignal<string>;
5479
+ readonly nextMonthLabel: _angular_core.InputSignal<string>;
5480
+ /** Accessible labels of the time selects (localizable). */
5481
+ readonly hourLabel: _angular_core.InputSignal<string>;
5482
+ readonly minuteLabel: _angular_core.InputSignal<string>;
5483
+ /** Static disable; forms' setDisabledState also drives the disabled state. */
5484
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
5485
+ /** The composed ISO value (`YYYY-MM-DDTHH:mm`, '' when no date is picked). */
5486
+ readonly value: _angular_core.WritableSignal<string>;
5487
+ /** Date part, two-way bound into the embedded datepicker. */
5488
+ readonly date: _angular_core.WritableSignal<string>;
5489
+ /** Time parts (zero-padded). */
5490
+ readonly hour: _angular_core.WritableSignal<string>;
5491
+ readonly minute: _angular_core.WritableSignal<string>;
5492
+ /** Disabled state pushed by the forms API (setDisabledState). */
5493
+ private readonly cvaDisabled;
5494
+ readonly isDisabled: _angular_core.Signal<boolean>;
5495
+ protected readonly hours: string[];
5496
+ /** Minute options at `minuteStep` granularity; an off-step written-in value stays selectable. */
5497
+ protected readonly minutes: _angular_core.Signal<string[]>;
5498
+ private onChange;
5499
+ private onTouched;
5500
+ /** A user pick in the embedded calendar (ngModelChange is view→model only). */
5501
+ protected onDatePicked(): void;
5502
+ protected onHourChange(event: Event): void;
5503
+ protected onMinuteChange(event: Event): void;
5504
+ /** Compose date + time into the ISO value and report it through the CVA. */
5505
+ private commit;
5506
+ writeValue(value: string | null): void;
5507
+ registerOnChange(fn: (value: string) => void): void;
5508
+ registerOnTouched(fn: () => void): void;
5509
+ setDisabledState(isDisabled: boolean): void;
5510
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctDatetimePicker, never>;
5511
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctDatetimePicker, "strct-datetime-picker", never, { "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "minuteStep": { "alias": "minuteStep"; "required": false; "isSignal": true; }; "monthNames": { "alias": "monthNames"; "required": false; "isSignal": true; }; "weekdayNames": { "alias": "weekdayNames"; "required": false; "isSignal": true; }; "weekdayNamesFull": { "alias": "weekdayNamesFull"; "required": false; "isSignal": true; }; "weekStart": { "alias": "weekStart"; "required": false; "isSignal": true; }; "prevMonthLabel": { "alias": "prevMonthLabel"; "required": false; "isSignal": true; }; "nextMonthLabel": { "alias": "nextMonthLabel"; "required": false; "isSignal": true; }; "hourLabel": { "alias": "hourLabel"; "required": false; "isSignal": true; }; "minuteLabel": { "alias": "minuteLabel"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
5512
+ }
5513
+
5514
+ /**
5515
+ * Action bar for datagrid/card tops — left-aligned projected actions with an
5516
+ * optional selection summary and clear-selection affordance:
5517
+ *
5518
+ * <strct-toolbar [selectionCount]="sel.size" (cleared)="sel.clear()">
5519
+ * <button type="button">Restart</button>
5520
+ * <strct-toolbar-spacer />
5521
+ * <button type="button">Add VM</button>
5522
+ * </strct-toolbar>
5523
+ *
5524
+ * `role="toolbar"` with APG keyboard support: ArrowLeft/ArrowRight (Up/Down
5525
+ * when `orientation` is 'vertical', mirrored in RTL) rove focus across the
5526
+ * projected controls, Home/End jump to the first/last. `selectionCount > 0`
5527
+ * prepends a "N selected" chip (label built by the localizable
5528
+ * `selectionLabel` factory) with a × button that emits `(cleared)`.
5529
+ * `strct-toolbar-spacer` pushes following actions to the far end.
5530
+ */
5531
+ declare class StrctToolbar {
5532
+ private readonly host;
5533
+ /** Accessible name of the toolbar (localizable). */
5534
+ readonly ariaLabel: _angular_core.InputSignal<string>;
5535
+ /** Roving axis: horizontal bars use Left/Right, vertical use Up/Down. */
5536
+ readonly orientation: _angular_core.InputSignal<"horizontal" | "vertical">;
5537
+ /** Number of selected rows/items; > 0 shows the selection chip + clear ×. */
5538
+ readonly selectionCount: _angular_core.InputSignal<number>;
5539
+ /** Subtle bottom divider — the classic "actions above the grid" look. */
5540
+ readonly divided: _angular_core.InputSignalWithTransform<boolean, unknown>;
5541
+ /** Builds the selection-chip label from the count (localizable). */
5542
+ readonly selectionLabel: _angular_core.InputSignal<(n: number) => string>;
5543
+ /** Accessible label of the × clear-selection button (localizable). */
5544
+ readonly clearLabel: _angular_core.InputSignal<string>;
5545
+ /** The × was pressed — clear your selection state. */
5546
+ readonly cleared: _angular_core.OutputEmitterRef<void>;
5547
+ /** APG toolbar roving across the projected (enabled, tabbable) controls. */
5548
+ protected onKeydown(event: KeyboardEvent): void;
5549
+ /** Tabbable controls inside the bar, in DOM order. */
5550
+ private items;
5551
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctToolbar, never>;
5552
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctToolbar, "strct-toolbar", never, { "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "selectionCount": { "alias": "selectionCount"; "required": false; "isSignal": true; }; "divided": { "alias": "divided"; "required": false; "isSignal": true; }; "selectionLabel": { "alias": "selectionLabel"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; }, { "cleared": "cleared"; }, never, ["*"], true, never>;
5553
+ }
5554
+ /**
5555
+ * Flex spacer for `strct-toolbar` — pushes the actions after it to the far
5556
+ * (inline-end) side of the bar.
5557
+ */
5558
+ declare class StrctToolbarSpacer {
5559
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctToolbarSpacer, never>;
5560
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctToolbarSpacer, "strct-toolbar-spacer", never, {}, {}, never, never, true, never>;
5561
+ }
5562
+
5563
+ /**
5564
+ * Click-to-edit text: display mode shows the value (or a muted localizable
5565
+ * `placeholder` when empty) with a pencil edit affordance that appears on
5566
+ * hover/focus; activating either swaps in an input. Enter commits, Escape
5567
+ * cancels (propagation stopped so an enclosing dialog stays open), blur
5568
+ * commits. The committed value is announced in a live region via
5569
+ * `StrctAnnouncer` (label built by the localizable `announcement` factory).
5570
+ *
5571
+ * <strct-inline-edit [(ngModel)]="vm.name" />
5572
+ *
5573
+ * A ControlValueAccessor over `string`; `disabled` (attribute) and the forms
5574
+ * API's `setDisabledState` both lock it into display mode.
5575
+ */
5576
+ declare class StrctInlineEdit implements ControlValueAccessor {
5577
+ private readonly host;
5578
+ private readonly announcer;
5579
+ /** Static disable; forms' setDisabledState also drives the disabled state. */
5580
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
5581
+ /** Disabled state pushed by the forms API (setDisabledState). */
5582
+ private readonly cvaDisabled;
5583
+ readonly isDisabled: _angular_core.Signal<boolean>;
5584
+ /** Shown (muted) when the value is empty (localizable). */
5585
+ readonly placeholder: _angular_core.InputSignal<string>;
5586
+ /** Accessible label of the pencil edit button and the input (localizable). */
5587
+ readonly editLabel: _angular_core.InputSignal<string>;
5588
+ /** Builds the live-region announcement after a commit (localizable). */
5589
+ readonly announcement: _angular_core.InputSignal<(value: string) => string>;
5590
+ /** Committed value — the CVA model. */
5591
+ readonly value: _angular_core.WritableSignal<string>;
5592
+ /** In-progress text while editing. */
5593
+ protected readonly draft: _angular_core.WritableSignal<string>;
5594
+ protected readonly editing: _angular_core.WritableSignal<boolean>;
5595
+ private onChange;
5596
+ private onTouched;
5597
+ /** Swap display mode for the input; the current value seeds the draft. */
5598
+ protected startEdit(): void;
5599
+ /** Enter commits; Escape cancels (and must not bubble to dialogs/menus). */
5600
+ protected onInputKey(event: KeyboardEvent): void;
5601
+ /** Commit the draft — Enter or blur. No-op once edit mode was left. */
5602
+ protected commit(): void;
5603
+ /** After leaving edit mode, focus lands back on the display value button. */
5604
+ private restoreDisplayFocus;
5605
+ private inputEl;
5606
+ writeValue(value: string | null): void;
5607
+ registerOnChange(fn: (value: string) => void): void;
5608
+ registerOnTouched(fn: () => void): void;
5609
+ setDisabledState(isDisabled: boolean): void;
5610
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctInlineEdit, never>;
5611
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctInlineEdit, "strct-inline-edit", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "editLabel": { "alias": "editLabel"; "required": false; "isSignal": true; }; "announcement": { "alias": "announcement"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
5612
+ }
5613
+
5614
+ /**
5615
+ * Bell button with an unread badge that opens an anchored panel listing the
5616
+ * recent notifications recorded by `StrctToastService` — every shown toast is
5617
+ * kept in a capped history, so the center is the persistent view of what the
5618
+ * toasts announced transiently:
5619
+ * <strct-notification-center (activated)="open($event)" />
5620
+ *
5621
+ * Clicking an entry marks it read and emits it through `activated` (wire it to
5622
+ * navigation); "mark all read" / "clear all" act on the shared history. Focus
5623
+ * moves into the panel on open, Escape closes with stopPropagation (a host
5624
+ * modal must not close too), and focus returns to the bell on close.
5625
+ */
5626
+ declare class StrctNotificationCenter {
5627
+ private readonly host;
5628
+ private readonly service;
5629
+ /** Panel heading and dialog accessible name (localizable). */
5630
+ readonly title: _angular_core.InputSignal<string>;
5631
+ /** Header button that clears the whole history (localizable). */
5632
+ readonly clearLabel: _angular_core.InputSignal<string>;
5633
+ /** Header button that flags every entry as read (localizable). */
5634
+ readonly markAllReadLabel: _angular_core.InputSignal<string>;
5635
+ /** Shown when the history is empty (localizable). */
5636
+ readonly emptyText: _angular_core.InputSignal<string>;
5637
+ /** Maximum entries rendered in the panel (the newest ones). */
5638
+ readonly maxItems: _angular_core.InputSignal<number>;
5639
+ /**
5640
+ * Factory for the bell's aria-label (localizable); receives the unread
5641
+ * count. When null, a default English label is generated.
5642
+ */
5643
+ readonly bellLabelFormat: _angular_core.InputSignal<((unread: number) => string) | null>;
5644
+ /**
5645
+ * Formatter for an entry's timestamp (localizable). When null, the locale's
5646
+ * short time is shown.
5647
+ */
5648
+ readonly timeFormat: _angular_core.InputSignal<((timestamp: number) => string) | null>;
5649
+ /** Emits the clicked entry (also marked read); the panel closes. */
5650
+ readonly activated: _angular_core.OutputEmitterRef<StrctNotification>;
5651
+ readonly open: _angular_core.WritableSignal<boolean>;
5652
+ protected readonly unread: _angular_core.Signal<number>;
5653
+ protected readonly hasHistory: _angular_core.Signal<boolean>;
5654
+ /** Newest first, capped to `maxItems`. */
5655
+ protected readonly items: _angular_core.Signal<StrctNotification[]>;
5656
+ protected readonly badgeText: _angular_core.Signal<string>;
5657
+ protected readonly bellAria: _angular_core.Signal<string>;
5658
+ private readonly panelEl;
5659
+ /** Element focused before opening — focus returns here on close. */
5660
+ private restoreTo;
5661
+ toggle(): void;
5662
+ close(restore?: boolean): void;
5663
+ /** Pick an entry: mark read, emit, close like a menu selection. */
5664
+ protected activate(n: StrctNotification): void;
5665
+ protected markAllRead(): void;
5666
+ protected clearAll(): void;
5667
+ protected icon(type: StrctToastType): string;
5668
+ protected timeText(n: StrctNotification): string;
5669
+ protected onPanelKeydown(event: KeyboardEvent): void;
5670
+ protected onDocClick(event: MouseEvent): void;
5671
+ /** Fallback for focus landing outside the panel; in-panel Escape stops first. */
5672
+ protected onEscape(event: Event): void;
5673
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctNotificationCenter, never>;
5674
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctNotificationCenter, "strct-notification-center", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; "markAllReadLabel": { "alias": "markAllReadLabel"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "maxItems": { "alias": "maxItems"; "required": false; "isSignal": true; }; "bellLabelFormat": { "alias": "bellLabelFormat"; "required": false; "isSignal": true; }; "timeFormat": { "alias": "timeFormat"; "required": false; "isSignal": true; }; }, { "activated": "activated"; }, never, never, true, never>;
5675
+ }
5676
+
5677
+ /** One density value at a row × column intersection. */
5678
+ interface StrctHeatmapCell {
5679
+ row: string;
5680
+ col: string;
5681
+ value: number;
5682
+ }
5683
+ /** Facts handed to `summaryFormat` to build the role="img" aria summary. */
5684
+ interface StrctHeatmapSummaryInfo {
5685
+ /** Grid dimensions. */
5686
+ rows: number;
5687
+ cols: number;
5688
+ /** Observed value range (after clamping to the effective `max`). */
5689
+ min: number;
5690
+ max: number;
5691
+ }
5692
+ interface CellRender {
5693
+ key: string;
5694
+ x: number;
5695
+ y: number;
5696
+ w: number;
5697
+ h: number;
5698
+ fill: string;
5699
+ /** Native tooltip; null for a missing (no-data) cell. */
5700
+ tip: string | null;
5701
+ }
5702
+ interface LabelRender {
5703
+ text: string;
5704
+ x: number;
5705
+ y: number;
5706
+ }
5707
+ /**
5708
+ * SVG grid heatmap for density data (host × hour, queue × weekday …).
5709
+ * <strct-heatmap [data]="cells" [rows]="hosts" [cols]="hours" />
5710
+ *
5711
+ * Each cell's fill is a single-hue intensity ramp — `color-mix` between the
5712
+ * status token and the surface — so the scale stays readable under
5713
+ * color-vision deficiency (luminance, not hue, carries the value). Rows and
5714
+ * columns follow the explicit `rows`/`cols` arrays when given, else first-seen
5715
+ * order in `data`; entries outside an explicit ordering are ignored, and
5716
+ * intersections without data render as empty cells. The SVG is measured (1:1
5717
+ * viewBox) so cells stay crisp at any width; hover a cell for its value.
5718
+ */
5719
+ declare class StrctHeatmap {
5720
+ /** Density values; a missing row × col intersection renders as an empty cell. */
5721
+ readonly data: _angular_core.InputSignal<StrctHeatmapCell[]>;
5722
+ /** Explicit row order (top → bottom). Absent: first-seen order in `data`. */
5723
+ readonly rows: _angular_core.InputSignal<string[] | null>;
5724
+ /** Explicit column order (left → right). Absent: first-seen order in `data`. */
5725
+ readonly cols: _angular_core.InputSignal<string[] | null>;
5726
+ /** Scale ceiling — the value that maps to full intensity. Auto (data max) when null. */
5727
+ readonly max: _angular_core.InputSignal<number | null>;
5728
+ /** Base color of the intensity ramp. */
5729
+ readonly status: _angular_core.InputSignal<StrctChartStatus>;
5730
+ /** Shown when there is no data (localizable). */
5731
+ readonly emptyText: _angular_core.InputSignal<string>;
5732
+ /** Accessible name of the chart, leading the role="img" summary (localizable). */
5733
+ readonly ariaLabel: _angular_core.InputSignal<string>;
5734
+ /**
5735
+ * Factory for the role="img" aria summary (localizable); receives the
5736
+ * computed facts. When null, a default English summary is generated.
5737
+ */
5738
+ readonly summaryFormat: _angular_core.InputSignal<((info: StrctHeatmapSummaryInfo) => string) | null>;
5739
+ /** Cell height in pixels (widths flex to the measured container). */
5740
+ readonly cellHeight: _angular_core.InputSignal<number>;
5741
+ /** Gap between cells in pixels. */
5742
+ readonly gap: _angular_core.InputSignal<number>;
5743
+ /** Left gutter width for the row labels in pixels. */
5744
+ readonly rowLabelWidth: _angular_core.InputSignal<number>;
5745
+ /** Measured pixel width → 1:1 viewBox so cells stay crisp at any size. */
5746
+ protected readonly width: _angular_core.WritableSignal<number>;
5747
+ private readonly host;
5748
+ constructor();
5749
+ protected readonly rowOrder: _angular_core.Signal<string[]>;
5750
+ protected readonly colOrder: _angular_core.Signal<string[]>;
5751
+ protected readonly isEmpty: _angular_core.Signal<boolean>;
5752
+ /** Last write wins when a row × col pair appears twice. */
5753
+ private readonly valueMap;
5754
+ /** Effective scale ceiling: explicit `max`, else the data's own maximum. */
5755
+ protected readonly maxVal: _angular_core.Signal<number>;
5756
+ private readonly color;
5757
+ /** Cell width: the plot flexes to the measured container width. */
5758
+ private readonly cellW;
5759
+ protected readonly height: _angular_core.Signal<number>;
5760
+ protected readonly cells: _angular_core.Signal<CellRender[]>;
5761
+ protected readonly rowLabels: _angular_core.Signal<LabelRender[]>;
5762
+ protected readonly colLabels: _angular_core.Signal<LabelRender[]>;
5763
+ /** Screen-reader summary of the whole grid (role="img" name). */
5764
+ protected readonly aria: _angular_core.Signal<string>;
5765
+ /**
5766
+ * Intensity ramp: 8% of the status hue for the smallest non-zero value up
5767
+ * to 100% at the ceiling; zero stays on the empty-cell surface.
5768
+ */
5769
+ private fillFor;
5770
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StrctHeatmap, never>;
5771
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<StrctHeatmap, "strct-heatmap", never, { "data": { "alias": "data"; "required": false; "isSignal": true; }; "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "cols": { "alias": "cols"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "summaryFormat": { "alias": "summaryFormat"; "required": false; "isSignal": true; }; "cellHeight": { "alias": "cellHeight"; "required": false; "isSignal": true; }; "gap": { "alias": "gap"; "required": false; "isSignal": true; }; "rowLabelWidth": { "alias": "rowLabelWidth"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
5772
+ }
5773
+
5774
+ export { FOCUSABLE_SELECTOR, STRCT_DP_DOW, STRCT_DP_DOW_FULL, STRCT_DP_MONTHS, STRCT_ICONS, STRCT_ICON_GROUPS, STRCT_ICON_NAMES, STRCT_MASKS, STRCT_NOTIFICATION_HISTORY_LIMIT, STRCT_PALETTES, STRCT_RAW_ICONS, STRCT_TIME_RANGE_PRESETS, STRCT_WIZARD_DEFAULTS, StrctAccordion, StrctAccordionPanel, StrctAlert, StrctAnnouncer, StrctAvatar, StrctBadge, StrctBreadcrumb, StrctBreadcrumbItem, StrctButton, StrctButtonGroup, StrctBytesPipe, StrctCard, StrctCardBlock, StrctCardFooter, StrctCardHeader, StrctCascadeColumn, StrctCascadeHost, StrctCascadeSelect, StrctCellDef, StrctCellStatus, StrctChart, StrctCheckbox, StrctChips, StrctCode, StrctColorPicker, StrctCombobox, StrctCommandPalette, StrctConfirmOutlet, StrctConfirmService, StrctContextMenu, StrctContextMenuTrigger, StrctCopy, StrctDatagrid, StrctDatagridActionBar, StrctDatepicker, StrctDatetimePicker, StrctDesc, StrctDescriptionList, StrctDiff, StrctDivider, StrctDonut, StrctDrawer, StrctDrawerFooter, StrctDropdown, StrctDropdownDivider, StrctDropdownItem, StrctDropdownTrigger, StrctDurationPipe, StrctEmptyState, StrctField, StrctFile, StrctFilterBar, StrctFlow, StrctFooter, StrctGauge, StrctHeader, StrctHeatmap, StrctHero, StrctHotkeysHelp, StrctHotkeysService, StrctIcon, StrctInlineEdit, StrctInput, StrctInputMask, StrctInputOtp, StrctKbd, StrctKnob, StrctLogViewer, StrctLogin, StrctMenuPanel, StrctMenuService, StrctMenubar, StrctMetricTile, StrctModal, StrctNav, StrctNavItem, StrctNotificationCenter, StrctNumber, StrctOverlay, StrctPageHeader, StrctPageHeaderActions, StrctPageHeaderCrumbs, StrctPagination, StrctPassword, StrctPopover, StrctPopoverTrigger, StrctProgress, StrctRadio, StrctRadioGroup, StrctRail, StrctRange, StrctRatePipe, StrctRating, StrctReorder, StrctReorderItem, StrctRowDetailDef, StrctSearchbox, StrctSectionMenu, StrctSegmented, StrctSelect, StrctShell, StrctShellService, StrctSiPipe, StrctSignpost, StrctSignpostTrigger, StrctSkeleton, StrctSparkline, StrctSpeedDial, StrctSpinner, StrctSplitButton, StrctSplitter, StrctStack, StrctStackItem, StrctStatusDot, StrctStep, StrctSubmenu, StrctTab, StrctTable, StrctTabs, StrctTag, StrctThemeService, StrctThemeSwitcher, StrctTimeRangePicker, StrctTimeline, StrctTimelineItem, StrctToastOutlet, StrctToastService, StrctToggle, StrctToolbar, StrctToolbarSpacer, StrctTooltip, StrctTour, StrctTransfer, StrctTree, StrctTreeNode, StrctTreeSelect, StrctVerticalNav, StrctWatermark, StrctWizard, StrctWizardAside, focusFirstIn, keepTabInside, lockBodyScroll, parseAnsi, provideStrctWizardDefaults, registerStrctIcon, restoreFocus, saveFocusedElement, strctComputeDiff, strctDpPad, strctFormatBytes, strctFormatDuration, strctFormatRate, strctFormatSi, strctValidationIcon, strctValidationTone, unlockBodyScroll };
5775
+ export type { StrctAlertType, StrctAvatarSize, StrctAvatarStatus, StrctBadgeStatus, StrctButtonSize, StrctButtonVariant, StrctCascadeOption, StrctCellContext, StrctChartAnnotation, StrctChartColor, StrctChartCurve, StrctChartSeries, StrctChartSlot, StrctChartStatus, StrctChartSummaryInfo, StrctChartThreshold, StrctChartType, StrctColumn, StrctCommandItem, StrctConfirmOptions, StrctConfirmTone, StrctDatagridColumn, StrctDatagridColumnState, StrctDatagridFilters, StrctDatagridLabels, StrctDatagridLazyState, StrctDescAlign, StrctDescItem, StrctDiffRow, StrctDonutSegment, StrctDrawerSide, StrctDrawerSize, StrctEmptyVariant, StrctFilterChip, StrctFlowDirection, StrctFlowNode, StrctFlowOrientation, StrctHeatmapCell, StrctHeatmapSummaryInfo, StrctHotkey, StrctIconBadge, StrctIconName, StrctKnobStatus, StrctLogLine, StrctMenuItem, StrctMenuLink, StrctMenuOpenOptions, StrctMenuSection, StrctMenubarItem, StrctMetricStatus, StrctModalSize, StrctMode, StrctNotification, StrctOption, StrctOverlayPlacement, StrctPalette, StrctPaletteInfo, StrctProgressStatus, StrctRailItem, StrctRailStatus, StrctReorderEvent, StrctRow, StrctRowId, StrctSegmentedOption, StrctSegmentedSize, StrctSignpostPosition, StrctSpeedDialDirection, StrctSpinnerSize, StrctStatus, StrctStatusDotSize, StrctTagStatus, StrctThresholds, StrctTimeRange, StrctTimeRangePreset, StrctTimelineState, StrctToast, StrctToastOptions, StrctToastType, StrctTooltipPosition, StrctTourStep, StrctTransferItem, StrctTreeMenuEvent, StrctTreeNodeData, StrctTreeNodeMenuFn, StrctValidationState, StrctValidationStatus, StrctWizardDefaults };