@forgeroute/ui 0.4.0 → 0.4.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.
@@ -887,6 +887,11 @@ export declare function formatTime(value: string | null | undefined): string;
887
887
  export interface SelectOption<V extends string | number = string> {
888
888
  value: V;
889
889
  label: string;
890
+ /**
891
+ * Optional longer explanation of this choice. The select shows the SELECTED option's description under the field (linked with
892
+ * `aria-describedby`) and sets it as the option's `title` tooltip where the browser shows one. Options without it are unchanged.
893
+ */
894
+ description?: string;
890
895
  }
891
896
  export declare class SelectComponent implements ControlValueAccessor, Validator, UiFieldValidity {
892
897
  readonly label: import("@angular/core").InputSignal<string>;
@@ -901,13 +906,17 @@ export declare class SelectComponent implements ControlValueAccessor, Validator,
901
906
  readonly error: import("@angular/core").InputSignal<string>;
902
907
  /** Reveal the built-in error messages now (e.g. after a failed Save click), without waiting for blur. */
903
908
  readonly showErrors: import("@angular/core").InputSignal<boolean>;
904
- readonly size: import("@angular/core").InputSignal<"default" | "sm">;
909
+ readonly size: import("@angular/core").InputSignal<"sm" | "default">;
905
910
  readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
906
911
  private readonly _cvaDisabled;
907
912
  protected readonly disabled: import("@angular/core").Signal<boolean>;
908
913
  protected readonly _value: import("@angular/core").WritableSignal<string>;
909
914
  /** Index of the first option matching the written / chosen value, or -1 (so only ONE option is selected even with duplicate keys). */
910
915
  protected readonly _selectedIndex: import("@angular/core").Signal<number>;
916
+ /** The selected option's `description` ('' when none is selected or it has none); hidden while an error shows. */
917
+ protected readonly _selectedDescription: import("@angular/core").Signal<string>;
918
+ /** ids of the texts that describe the select: the error / hint, then the selected option's description. */
919
+ protected readonly _describedBy: import("@angular/core").Signal<string>;
911
920
  private readonly _reveal;
912
921
  private readonly _issue;
913
922
  /** True while the value breaks a built-in rule or the host passed an `[error]`. */
@@ -1121,6 +1130,12 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
1121
1130
  readonly pageSize: import("@angular/core").InputSignal<number>;
1122
1131
  readonly tableLabel: import("@angular/core").InputSignal<string>;
1123
1132
  readonly emptyMessage: import("@angular/core").InputSignal<string>;
1133
+ /**
1134
+ * Text of the retry button in the failed-load state (desktop table and phone cards). Plain text.
1135
+ * Empty / blank keeps the error state's own default ("Try again").
1136
+ */
1137
+ readonly retryLabel: import("@angular/core").InputSignal<string>;
1138
+ protected readonly _retryLabel: Signal<string>;
1124
1139
  readonly lockedColumn: import("@angular/core").InputSignal<string>;
1125
1140
  readonly savedViews: import("@angular/core").InputSignal<SavedView[]>;
1126
1141
  /**
@@ -1131,6 +1146,14 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
1131
1146
  readonly page: import("@angular/core").InputSignal<string>;
1132
1147
  /** Show column config + saved views toolbar. Defaults true. Set false to hide both. */
1133
1148
  readonly showToolbar: import("@angular/core").InputSignal<boolean>;
1149
+ /**
1150
+ * Show the search box above the table. Defaults true. Set false for small fixed tables where searching is meaningless
1151
+ * (a handful of summary rows). Quick-filter tabs and the toolbar are unaffected; when the search box, the tabs and the
1152
+ * toolbar are all off, the header row above the table is not rendered at all.
1153
+ */
1154
+ readonly showSearch: import("@angular/core").InputSignal<boolean>;
1155
+ /** False when the header row would be empty (no search box, no toolbar, no quick-filter tabs). */
1156
+ protected readonly _showHeader: Signal<boolean>;
1134
1157
  /** Optional endpoint that returns Record<string,number> counts per quick-filter value. */
1135
1158
  readonly countsEndpoint: import("@angular/core").InputSignal<string>;
1136
1159
  /**
@@ -1447,6 +1470,13 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
1447
1470
  activeValues: string[];
1448
1471
  };
1449
1472
  }[]>;
1473
+ /**
1474
+ * The sort buttons / icons and the column-filter icons only show while there is something to sort or filter: not after a failed
1475
+ * load, and not when the table is empty because nothing exists or only a search / quick tab matched nothing (clear the search to
1476
+ * get back). Once the user has used a column header control (a column filter or a sort is active) the controls stay, even with
1477
+ * zero rows, so they can change or clear it. Headers are plain labels otherwise.
1478
+ */
1479
+ protected readonly _showColumnControls: Signal<boolean>;
1450
1480
  protected readonly _hasPhoneControls: Signal<boolean>;
1451
1481
  /** Phone sort select → sets the sort directly (same state, page reset and load as the header's onSort). */
1452
1482
  protected onPhoneSort(value: string): void;
@@ -1561,6 +1591,11 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
1561
1591
  "required": false;
1562
1592
  "isSignal": true;
1563
1593
  };
1594
+ "retryLabel": {
1595
+ "alias": "retryLabel";
1596
+ "required": false;
1597
+ "isSignal": true;
1598
+ };
1564
1599
  "lockedColumn": {
1565
1600
  "alias": "lockedColumn";
1566
1601
  "required": false;
@@ -1581,6 +1616,11 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
1581
1616
  "required": false;
1582
1617
  "isSignal": true;
1583
1618
  };
1619
+ "showSearch": {
1620
+ "alias": "showSearch";
1621
+ "required": false;
1622
+ "isSignal": true;
1623
+ };
1584
1624
  "countsEndpoint": {
1585
1625
  "alias": "countsEndpoint";
1586
1626
  "required": false;
@@ -2090,7 +2130,7 @@ export declare class AudioPlayerComponent {
2090
2130
  /** Accessible name of the player. */
2091
2131
  readonly ariaLabel: import("@angular/core").InputSignal<string>;
2092
2132
  /** How much to load before play: 'metadata' (default), 'auto' or 'none'. */
2093
- readonly preload: import("@angular/core").InputSignal<"none" | "auto" | "metadata">;
2133
+ readonly preload: import("@angular/core").InputSignal<"none" | "metadata" | "auto">;
2094
2134
  /** Fires when the browser can't load or decode the source. */
2095
2135
  readonly playbackError: import("@angular/core").OutputEmitterRef<void>;
2096
2136
  protected readonly failed: import("@angular/core").WritableSignal<boolean>;
@@ -2117,11 +2157,27 @@ export declare class AudioPlayerComponent {
2117
2157
  "playbackError": "playbackError";
2118
2158
  }, never, never, true, never>;
2119
2159
  }
2160
+ /**
2161
+ * Shimmering placeholder for content that is loading.
2162
+ *
2163
+ * By default it is purely decorative (hidden from assistive tech), like before. Give ONE skeleton - or the wrapper of a group of them - an
2164
+ * `ariaLabel` to announce the loading state: the host then becomes a polite live region (`role="status"`, `aria-live="polite"`,
2165
+ * `aria-busy="true"`, named by the label) and is no longer hidden. Remove the skeleton (or the label) when the content has loaded.
2166
+ *
2167
+ * <ui-skeleton [height]="44" ariaLabel="Loading submissions" />
2168
+ * <div role="status" aria-label="Loading report"> <ui-skeleton /> <ui-skeleton /> </div> <!-- decorative skeletons inside a labelled wrapper -->
2169
+ *
2170
+ * Do not label every skeleton of a group: each labelled skeleton is its own live region and would be announced separately.
2171
+ */
2120
2172
  export declare class SkeletonComponent {
2121
2173
  readonly height: import("@angular/core").InputSignal<number>;
2122
2174
  readonly width: import("@angular/core").InputSignal<string>;
2123
2175
  readonly radius: import("@angular/core").InputSignal<number>;
2124
2176
  readonly mb: import("@angular/core").InputSignal<number>;
2177
+ /** Accessible name that turns the skeleton into a polite status region ("Loading ..."). Empty (default) = decorative, hidden from assistive tech. */
2178
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
2179
+ /** The trimmed label ('' = none). */
2180
+ label(): string;
2125
2181
  static ɵfac: i0.ɵɵFactoryDeclaration<SkeletonComponent, never>;
2126
2182
  static ɵcmp: i0.ɵɵComponentDeclaration<SkeletonComponent, "ui-skeleton", never, {
2127
2183
  "height": {
@@ -2144,6 +2200,11 @@ export declare class SkeletonComponent {
2144
2200
  "required": false;
2145
2201
  "isSignal": true;
2146
2202
  };
2203
+ "ariaLabel": {
2204
+ "alias": "ariaLabel";
2205
+ "required": false;
2206
+ "isSignal": true;
2207
+ };
2147
2208
  }, {}, never, never, true, never>;
2148
2209
  }
2149
2210
  /**
@@ -2950,7 +3011,7 @@ export declare class PhoneNumberPickerComponent {
2950
3011
  protected readonly modeCtl: FormControl<string>;
2951
3012
  protected readonly zipCtl: FormControl<string>;
2952
3013
  protected readonly areaCtl: FormControl<string>;
2953
- protected readonly step: import("@angular/core").WritableSignal<1 | 2 | 3>;
3014
+ protected readonly step: import("@angular/core").WritableSignal<2 | 1 | 3>;
2954
3015
  protected readonly mode: import("@angular/core").WritableSignal<PhoneNumberSearchMode>;
2955
3016
  private readonly _zip;
2956
3017
  private readonly _area;
@@ -3081,8 +3142,8 @@ export declare class ButtonComponent {
3081
3142
  protected readonly _rel: import("@angular/core").Signal<string | null>;
3082
3143
  readonly color: import("@angular/core").InputSignal<string | undefined>;
3083
3144
  readonly active: import("@angular/core").InputSignal<boolean>;
3084
- readonly size: import("@angular/core").InputSignal<"sm" | "md" | "xs" | "lg">;
3085
- readonly type: import("@angular/core").InputSignal<"reset" | "submit" | "button">;
3145
+ readonly size: import("@angular/core").InputSignal<"sm" | "md" | "lg" | "xs">;
3146
+ readonly type: import("@angular/core").InputSignal<"button" | "submit" | "reset">;
3086
3147
  readonly disabled: import("@angular/core").InputSignal<boolean>;
3087
3148
  readonly loading: import("@angular/core").InputSignal<boolean>;
3088
3149
  readonly fullWidth: import("@angular/core").InputSignal<boolean>;
@@ -6013,7 +6074,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
6013
6074
  * `search`, `text`, `none`). Empty (default) = the browser's default for the field, except `type="tel"`, which keeps `tel`.
6014
6075
  * It only picks the keyboard; it does not restrict what can be typed or pasted.
6015
6076
  */
6016
- readonly inputmode: import("@angular/core").InputSignal<"" | "none" | "text" | "search" | "email" | "tel" | "url" | "decimal" | "numeric">;
6077
+ readonly inputmode: import("@angular/core").InputSignal<"" | "none" | "text" | "email" | "tel" | "search" | "url" | "decimal" | "numeric">;
6017
6078
  readonly readonly: import("@angular/core").InputSignal<boolean>;
6018
6079
  readonly hint: import("@angular/core").InputSignal<string>;
6019
6080
  readonly error: import("@angular/core").InputSignal<string>;
@@ -7026,6 +7087,8 @@ export interface DropdownItem {
7026
7087
  label: string;
7027
7088
  value: string;
7028
7089
  count?: number;
7090
+ /** Greyed-out, not selectable and skipped by keyboard navigation. */
7091
+ disabled?: boolean;
7029
7092
  }
7030
7093
  export declare class DropdownComponent {
7031
7094
  readonly label: import("@angular/core").InputSignal<string>;
@@ -7036,16 +7099,54 @@ export declare class DropdownComponent {
7036
7099
  readonly activeValue: import("@angular/core").InputSignal<string>;
7037
7100
  readonly variant: import("@angular/core").InputSignal<"badge" | "button">;
7038
7101
  readonly menuWidth: import("@angular/core").InputSignal<string>;
7102
+ /**
7103
+ * Accessible name. Set it when the trigger has no meaningful visible text. Applied as `aria-label` on the
7104
+ * trigger and on the menu; when empty (default) no `aria-label` is rendered, the trigger is named by its
7105
+ * visible label and the menu by `aria-labelledby` pointing at the trigger. Surrounding whitespace is trimmed.
7106
+ */
7107
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
7039
7108
  readonly itemClick: import("@angular/core").OutputEmitterRef<DropdownItem>;
7040
7109
  protected readonly open: import("@angular/core").WritableSignal<boolean>;
7041
7110
  protected readonly loading: import("@angular/core").WritableSignal<boolean>;
7042
7111
  private readonly _loaded;
7043
7112
  private readonly _id;
7113
+ private readonly _host;
7114
+ private readonly _cdr;
7115
+ private _pendingFocus;
7116
+ private _typeahead;
7117
+ private _typeaheadTimer;
7118
+ private _destroyed;
7119
+ protected readonly triggerId: string;
7120
+ protected readonly menuId: string;
7121
+ protected readonly _ariaLabel: import("@angular/core").Signal<string | null>;
7044
7122
  protected readonly displayItems: import("@angular/core").Signal<DropdownItem[]>;
7045
7123
  constructor();
7046
7124
  toggle(event: Event): void;
7047
7125
  select(item: DropdownItem): void;
7048
7126
  close(): void;
7127
+ /**
7128
+ * Keyboard contract (WAI-ARIA menu button).
7129
+ * Trigger: Enter / Space toggle (opening focuses the first item), ArrowDown opens + first item,
7130
+ * ArrowUp opens + last item, ArrowDown/ArrowUp while open move into the menu, Tab closes (focus moves on naturally).
7131
+ */
7132
+ protected onTriggerKeydown(event: KeyboardEvent): void;
7133
+ /** Firefox fires the button click on Space keyup even when keydown was prevented. */
7134
+ protected onTriggerKeyup(event: KeyboardEvent): void;
7135
+ /**
7136
+ * Menu keys (focus on an item): ArrowDown / ArrowUp move with wrap, Home / End jump to first / last,
7137
+ * Enter / Space activate the focused item (native button click), Tab / Shift+Tab close and let focus move on from the trigger,
7138
+ * printable characters jump to the next item whose label starts with the typed text (typeahead, reset after 500 ms).
7139
+ * Disabled items are skipped. Other keys are ignored. Escape is handled on the host.
7140
+ */
7141
+ protected onMenuKeydown(event: KeyboardEvent): void;
7142
+ protected onEscape(event: Event): void;
7143
+ private _setOpen;
7144
+ private _openAndFocus;
7145
+ /** Renders the menu synchronously, then focuses the pending first / last enabled item. */
7146
+ private _focusPending;
7147
+ private _typeaheadFocus;
7148
+ private _enabledItems;
7149
+ private _focusTrigger;
7049
7150
  static ɵfac: i0.ɵɵFactoryDeclaration<DropdownComponent, never>;
7050
7151
  static ɵcmp: i0.ɵɵComponentDeclaration<DropdownComponent, "ui-dropdown", never, {
7051
7152
  "label": {
@@ -7083,6 +7184,11 @@ export declare class DropdownComponent {
7083
7184
  "required": false;
7084
7185
  "isSignal": true;
7085
7186
  };
7187
+ "ariaLabel": {
7188
+ "alias": "ariaLabel";
7189
+ "required": false;
7190
+ "isSignal": true;
7191
+ };
7086
7192
  }, {
7087
7193
  "itemClick": "itemClick";
7088
7194
  }, never, never, true, never>;
@@ -7105,7 +7211,7 @@ export declare class FormSectionComponent {
7105
7211
  }, {}, never, ["*"], true, never>;
7106
7212
  }
7107
7213
  export declare class FormRowComponent {
7108
- readonly cols: import("@angular/core").InputSignal<1 | 2 | 3>;
7214
+ readonly cols: import("@angular/core").InputSignal<2 | 1 | 3>;
7109
7215
  static ɵfac: i0.ɵɵFactoryDeclaration<FormRowComponent, never>;
7110
7216
  static ɵcmp: i0.ɵɵComponentDeclaration<FormRowComponent, "ui-form-row", never, {
7111
7217
  "cols": {
@@ -7524,6 +7630,12 @@ export declare class ListComponent<T = unknown> {
7524
7630
  * The row has no list role of its own: put `role="list"` on the host container and `role="listitem"` on each `ui-bar-row`
7525
7631
  * (or wrap them in `ui-list`). The label names the inner progressbar (`aria-labelledby`) and `valueText`
7526
7632
  * (default: the count plus the share) is its `aria-valuetext`.
7633
+ *
7634
+ * Out-of-range input: only the BAR is clamped, never the text the user reads. The fill is always 0-100% of the track:
7635
+ * `value` below 0, NaN, -Infinity or not a number (string, null, undefined) draws no fill; `value` above `max`
7636
+ * (including +Infinity) fills 100%; `max` of 0, negative, NaN, +/-Infinity or not a number draws an empty bar. The progressbar's
7637
+ * `aria-valuenow` is clamped to [0, max] and `aria-valuemax` is 0 for an invalid max. The count text keeps the real `value`
7638
+ * (formatted; a non-finite or non-number value reads "0"), and `count` / `share` / `valueText` are shown and announced as given.
7527
7639
  * Layout: `minmax(0, 12rem) 1fr auto`; at 480px and below the label sits above the bar with the count at the end of the label line.
7528
7640
  */
7529
7641
  export declare class BarRowComponent {
@@ -7531,7 +7643,7 @@ export declare class BarRowComponent {
7531
7643
  readonly label: import("@angular/core").InputSignal<string>;
7532
7644
  /** This row's amount. */
7533
7645
  readonly value: import("@angular/core").InputSignal<number>;
7534
- /** The amount that fills the bar (e.g. the largest category's count). 0 / NaN / negative draws an empty bar. */
7646
+ /** The amount that fills the bar (e.g. the largest category's count). 0 / NaN / negative / infinite / not a number draws an empty bar. */
7535
7647
  readonly max: import("@angular/core").InputSignal<number>;
7536
7648
  /** Fixed bar colour. Default blue; never follows completion. */
7537
7649
  readonly variant: import("@angular/core").InputSignal<ProgressBarVariant>;
@@ -7545,6 +7657,10 @@ export declare class BarRowComponent {
7545
7657
  readonly locale: import("@angular/core").InputSignal<string>;
7546
7658
  /** Unique id tying the label to the progressbar. */
7547
7659
  protected readonly labelId: string;
7660
+ /** `value` made safe for the bar: anything that is not a real number becomes 0 (the bar clamps the rest to 0..max). */
7661
+ protected readonly barValue: import("@angular/core").Signal<number>;
7662
+ /** `max` made safe for the bar: only a finite number above 0 counts, everything else is 0 (empty bar). */
7663
+ protected readonly barMax: import("@angular/core").Signal<number>;
7548
7664
  protected readonly countText: import("@angular/core").Signal<string>;
7549
7665
  protected readonly effectiveValueText: import("@angular/core").Signal<string>;
7550
7666
  static ɵfac: i0.ɵɵFactoryDeclaration<BarRowComponent, never>;
@@ -8296,6 +8412,9 @@ export type KpiCardValueColor = 'default' | 'green' | 'blue';
8296
8412
  * role="button", focusable (tabindex 0, visible focus ring), and Enter / Space fire the host's (click). Give it an
8297
8413
  * accessible name with [attr.aria-label] when the label alone isn't enough (e.g. "Net Commission: $12.5K — show details").
8298
8414
  *
8415
+ * Optional background: `background="#fef2f2"` fills the card with any CSS colour (default white), e.g. a soft red for money going out; the
8416
+ * text keeps its own colours, so pick a light shade.
8417
+ *
8299
8418
  * Optional ring: `[progress]="67"` (+ `progressMax`, `progressVariant`, `progressSize`) draws a ui-progress-ring beside the label; extra lines
8300
8419
  * (a pace badge, a projection…) go in an element with the `kpi-footer` attribute.
8301
8420
  *
@@ -8315,6 +8434,8 @@ export declare class KpiCardComponent {
8315
8434
  readonly highlight: import("@angular/core").InputSignal<boolean>;
8316
8435
  readonly clickable: import("@angular/core").InputSignal<boolean>;
8317
8436
  readonly valueColor: import("@angular/core").InputSignal<KpiCardValueColor>;
8437
+ /** Card background as any CSS colour (`#fef2f2`, `var(--surface)` …). Empty (default) = white. The text colours do not change, so use a light shade. */
8438
+ readonly background: import("@angular/core").InputSignal<string>;
8318
8439
  /** Completed amount shown as a `ui-progress-ring` beside the label. `null` (default) = no ring. */
8319
8440
  readonly progress: import("@angular/core").InputSignal<number | null>;
8320
8441
  /** Total for `progress` (default 100, so `progress` is a percentage). */
@@ -8374,6 +8495,11 @@ export declare class KpiCardComponent {
8374
8495
  "required": false;
8375
8496
  "isSignal": true;
8376
8497
  };
8498
+ "background": {
8499
+ "alias": "background";
8500
+ "required": false;
8501
+ "isSignal": true;
8502
+ };
8377
8503
  "progress": {
8378
8504
  "alias": "progress";
8379
8505
  "required": false;
@@ -8411,6 +8537,167 @@ export declare class KpiCardComponent {
8411
8537
  };
8412
8538
  }, {}, never, ["[kpi-footer]"], true, never>;
8413
8539
  }
8540
+ interface StateView {
8541
+ id: string;
8542
+ name: string;
8543
+ path: string;
8544
+ value: number;
8545
+ /** "12 pickups" (or just "12"). */
8546
+ valueText: string;
8547
+ /** "Texas, 12 pickups": the accessible name, the tooltip text and the hidden-list entry. */
8548
+ label: string;
8549
+ fill: string;
8550
+ }
8551
+ /**
8552
+ * US choropleth map: the 50 states plus Washington, DC, each coloured from `colorLow` (value 0) to `colorHigh` (the largest
8553
+ * value) by its number in `data`.
8554
+ *
8555
+ * Interaction and accessibility
8556
+ * - Every state is a button (`role="button"`, name "Texas, 12 pickups", `aria-pressed` for the selected one). The group has a
8557
+ * single tab stop (roving tabindex: last focused state, else the selected one, else Alabama); arrow keys,
8558
+ * Home and End move between states in alphabetical order, Enter / Space emit `stateClick` with the abbreviation.
8559
+ * - The tooltip (state name + value) shows on hover AND on keyboard focus; it is real text, `aria-hidden` because the
8560
+ * state's accessible name already says the same. Colour is never the only signal: values are in names, tooltip and the
8561
+ * visually hidden list of all states.
8562
+ * - A selected state gets an orange outline and the others are dimmed; the focus ring is drawn as an overlay outline
8563
+ * (works the same in Chrome, Edge, Firefox and Safari) and only for keyboard focus.
8564
+ * - `prefers-reduced-motion` turns the transitions off. Strokes use `vector-effect: non-scaling-stroke`, so outlines keep
8565
+ * their pixel width when `focusState` zooms in.
8566
+ *
8567
+ * Known limitation: the very small states (CT, DC, DE, HI, MA, MD, NH, NJ, RI, VT) are tiny touch targets on a phone. They
8568
+ * are reachable by keyboard and screen reader like any other; set `showSmallStateButtons` for a row of 44px buttons for them.
8569
+ * Territories are not on the map.
8570
+ */
8571
+ export declare class UsStateMapComponent {
8572
+ /** State abbreviation -> value. Keys are case-insensitive; unknown keys are ignored; numbers and numeric strings (`'5'`) are read as numbers, anything else (negative, NaN, Infinity, text, booleans, null) counts as 0; repeated keys (`tx` and `TX`) are added up. */
8573
+ readonly data: import("@angular/core").InputSignal<Record<string, number>>;
8574
+ /** Abbreviation of the selected state (orange outline, the others are dimmed). Unknown / null = none. */
8575
+ readonly selectedState: import("@angular/core").InputSignal<string | null>;
8576
+ /** Abbreviation of a state to zoom the map to (bounding box plus 15% padding). Unknown / null = the whole map. */
8577
+ readonly focusState: import("@angular/core").InputSignal<string | null>;
8578
+ /** Unit for one, e.g. "pickup": "Texas, 1 pickup". Empty = just the number. */
8579
+ readonly unitSingular: import("@angular/core").InputSignal<string>;
8580
+ /** Unit for other counts, e.g. "pickups". Empty = the singular text is used for every count. */
8581
+ readonly unitPlural: import("@angular/core").InputSignal<string>;
8582
+ /** Colour of a value of 0 (CSS hex or rgb()). Invalid values fall back to #e5e7eb. */
8583
+ readonly colorLow: import("@angular/core").InputSignal<string>;
8584
+ /** Colour of the largest value (CSS hex or rgb()). Invalid values fall back to #1e40af. */
8585
+ readonly colorHigh: import("@angular/core").InputSignal<string>;
8586
+ /** Shows the colour scale (0 to the largest value). */
8587
+ readonly showLegend: import("@angular/core").InputSignal<boolean>;
8588
+ /** Shows a row of buttons for the very small states (touch friendly, 44px). Off by default. */
8589
+ readonly showSmallStateButtons: import("@angular/core").InputSignal<boolean>;
8590
+ /** Accessible name of the whole map. */
8591
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
8592
+ /** CSS maximum width of the map (it always shrinks to its container). */
8593
+ readonly maxWidth: import("@angular/core").InputSignal<string>;
8594
+ /** Optional CSS height of the map, e.g. "420px". Empty = follows the width (aspect ratio of the map). */
8595
+ readonly height: import("@angular/core").InputSignal<string>;
8596
+ /** Emits the state's abbreviation (upper case) on click, tap, Enter or Space. */
8597
+ readonly stateClick: import("@angular/core").OutputEmitterRef<string>;
8598
+ private readonly host;
8599
+ /** True between a pointer press and the click that follows: a mouse / touch focus must not draw the keyboard ring. */
8600
+ protected pointerDown: boolean;
8601
+ private readonly hoveredId;
8602
+ private readonly focusedId;
8603
+ private readonly lastFocusedId;
8604
+ private readonly ringVisible;
8605
+ protected readonly tipPos: import("@angular/core").WritableSignal<{
8606
+ x: number;
8607
+ y: number;
8608
+ } | null>;
8609
+ private readonly low;
8610
+ private readonly high;
8611
+ private readonly values;
8612
+ private readonly max;
8613
+ private unit;
8614
+ private valueText;
8615
+ protected readonly views: import("@angular/core").Signal<StateView[]>;
8616
+ protected readonly smallViews: import("@angular/core").Signal<StateView[]>;
8617
+ protected readonly selectedId: import("@angular/core").Signal<string | null>;
8618
+ protected readonly selectedView: import("@angular/core").Signal<StateView | null>;
8619
+ protected readonly focusRingView: import("@angular/core").Signal<StateView | null>;
8620
+ protected readonly viewBox: import("@angular/core").Signal<string>;
8621
+ /** The one state in the tab order: last focused, else selected, else the first. */
8622
+ protected readonly tabStop: import("@angular/core").Signal<string>;
8623
+ protected readonly tip: import("@angular/core").Signal<StateView | null>;
8624
+ protected readonly gradient: import("@angular/core").Signal<string>;
8625
+ protected readonly maxText: import("@angular/core").Signal<string>;
8626
+ protected readonly legendLabel: import("@angular/core").Signal<string>;
8627
+ protected opacityOf(id: string): string | null;
8628
+ protected onHover(ev: PointerEvent, id: string): void;
8629
+ protected onLeave(id: string): void;
8630
+ protected clearHover(): void;
8631
+ protected onClick(id: string): void;
8632
+ protected onFocus(id: string): void;
8633
+ protected onBlur(id: string): void;
8634
+ protected onKey(ev: KeyboardEvent, id: string): void;
8635
+ static ɵfac: i0.ɵɵFactoryDeclaration<UsStateMapComponent, never>;
8636
+ static ɵcmp: i0.ɵɵComponentDeclaration<UsStateMapComponent, "ui-us-state-map", never, {
8637
+ "data": {
8638
+ "alias": "data";
8639
+ "required": false;
8640
+ "isSignal": true;
8641
+ };
8642
+ "selectedState": {
8643
+ "alias": "selectedState";
8644
+ "required": false;
8645
+ "isSignal": true;
8646
+ };
8647
+ "focusState": {
8648
+ "alias": "focusState";
8649
+ "required": false;
8650
+ "isSignal": true;
8651
+ };
8652
+ "unitSingular": {
8653
+ "alias": "unitSingular";
8654
+ "required": false;
8655
+ "isSignal": true;
8656
+ };
8657
+ "unitPlural": {
8658
+ "alias": "unitPlural";
8659
+ "required": false;
8660
+ "isSignal": true;
8661
+ };
8662
+ "colorLow": {
8663
+ "alias": "colorLow";
8664
+ "required": false;
8665
+ "isSignal": true;
8666
+ };
8667
+ "colorHigh": {
8668
+ "alias": "colorHigh";
8669
+ "required": false;
8670
+ "isSignal": true;
8671
+ };
8672
+ "showLegend": {
8673
+ "alias": "showLegend";
8674
+ "required": false;
8675
+ "isSignal": true;
8676
+ };
8677
+ "showSmallStateButtons": {
8678
+ "alias": "showSmallStateButtons";
8679
+ "required": false;
8680
+ "isSignal": true;
8681
+ };
8682
+ "ariaLabel": {
8683
+ "alias": "ariaLabel";
8684
+ "required": false;
8685
+ "isSignal": true;
8686
+ };
8687
+ "maxWidth": {
8688
+ "alias": "maxWidth";
8689
+ "required": false;
8690
+ "isSignal": true;
8691
+ };
8692
+ "height": {
8693
+ "alias": "height";
8694
+ "required": false;
8695
+ "isSignal": true;
8696
+ };
8697
+ }, {
8698
+ "stateClick": "stateClick";
8699
+ }, never, never, true, never>;
8700
+ }
8414
8701
  export type DatePreset = 'today' | '7days' | '30days' | 'month' | 'quarter' | 'ytd' | 'all' | 'custom';
8415
8702
  export interface DateRange {
8416
8703
  preset: DatePreset;
@@ -8848,6 +9135,7 @@ export declare class RadioMatrixComponent implements ControlValueAccessor, Valid
8848
9135
  * Header (all optional - set `[showHeader]="false"` and the card is just the body):
8849
9136
  * - `title` / `subtitle`: the bold uppercase title and the grey line under it.
8850
9137
  * - `titleId`: an id for the title text, which also names the card for assistive tech (aria-labelledby).
9138
+ * - `ariaLabel`: the card's accessible name when the header does not provide one (`[showHeader]="false"`, or a header with no title). A visible title always wins; `titleId` still names the card by aria-labelledby.
8851
9139
  * - `<div card-header-leading>`: something before the title block, such as a logo or an icon.
8852
9140
  * - `<ng-container card-header>`: your own header content, shown under the title (or instead of it when no title is set).
8853
9141
  * - `<ng-container card-header-action>`: buttons or links on the right side of the header.
@@ -8863,6 +9151,7 @@ export declare class RadioMatrixComponent implements ControlValueAccessor, Valid
8863
9151
  * <ui-detail-card title="COMMUNICATIONS" subtitle="All calls, texts, and emails"> ...body... </ui-detail-card>
8864
9152
  * <ui-detail-card title="CONTACT INFO" [showEdit]="true" (editClick)="openEdit()"> ... </ui-detail-card>
8865
9153
  * <ui-detail-card [showHeader]="false"> ...body only... </ui-detail-card>
9154
+ * <ui-detail-card [showHeader]="false" ariaLabel="Report filters"> ...body only, but named for assistive tech... </ui-detail-card>
8866
9155
  * <ui-detail-card [collapsible]="false">
8867
9156
  * <div card-header>Any markup</div>
8868
9157
  * <ui-button card-header-action size="xs" variant="secondary">Add</ui-button>
@@ -8873,9 +9162,11 @@ export declare class DetailCardComponent {
8873
9162
  /** Bold uppercase title. Empty = no title text. */
8874
9163
  readonly title: import("@angular/core").InputSignal<string>;
8875
9164
  /** 1-6 makes the title a real heading for screen readers (role=heading, aria-level); null keeps it plain text. */
8876
- readonly headingLevel: import("@angular/core").InputSignal<1 | 2 | 3 | 4 | 5 | 6 | null>;
9165
+ readonly headingLevel: import("@angular/core").InputSignal<2 | 1 | 5 | 3 | 6 | 4 | null>;
8877
9166
  /** Optional id for the title text; the card is then labelled by it. Without it the title is the card's aria-label. */
8878
9167
  readonly titleId: import("@angular/core").InputSignal<string>;
9168
+ /** Accessible name of the card when the header gives none (no header, or no title). A visible title wins; blank = no name. */
9169
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
8879
9170
  /** Grey line under the title. */
8880
9171
  readonly subtitle: import("@angular/core").InputSignal<string>;
8881
9172
  /** Card background as any CSS colour (`#f8fafc`, `var(--surface)` …). Empty = white. */
@@ -8892,6 +9183,8 @@ export declare class DetailCardComponent {
8892
9183
  readonly showEdit: import("@angular/core").InputSignal<boolean>;
8893
9184
  readonly editLabel: import("@angular/core").InputSignal<string>;
8894
9185
  readonly editClick: import("@angular/core").OutputEmitterRef<void>;
9186
+ /** The group's aria-label: the visible title (unless `titleId` names the card instead), else `ariaLabel`, else none. */
9187
+ groupLabel(): string | null;
8895
9188
  /** The body is open unless the card has a header that is collapsible and was collapsed. */
8896
9189
  isOpen(): boolean;
8897
9190
  toggle(): void;
@@ -8914,6 +9207,11 @@ export declare class DetailCardComponent {
8914
9207
  "required": false;
8915
9208
  "isSignal": true;
8916
9209
  };
9210
+ "ariaLabel": {
9211
+ "alias": "ariaLabel";
9212
+ "required": false;
9213
+ "isSignal": true;
9214
+ };
8917
9215
  "subtitle": {
8918
9216
  "alias": "subtitle";
8919
9217
  "required": false;
@@ -9246,8 +9544,12 @@ export declare class ColorInputComponent implements ControlValueAccessor, Valida
9246
9544
  * - `iconColor`: colour of the icon (default blue #2563eb).
9247
9545
  * - `iconBackground`: colour of the tile behind the icon (default white when a `background` is set, otherwise light grey #f1f5f9).
9248
9546
  * - `bordered`: 1px #e2e8f0 border and 10px radius (default false).
9249
- * - `size`: 'md' (default; 1rem title, 28px tile) or 'sm' (0.875rem title, 24px tile).
9250
- * Padding is built in (14px 18px; 12px 14px at 480px and narrower) - there is no padding input.
9547
+ * - `size`: the visual size only (the semantic heading `level` is independent of it). Anything else becomes 'md'.
9548
+ * 'sm' 0.875rem (14px) title, 0.75rem description, 24px tile, 14px icon; padding 14px 18px (12px 14px at 480px and narrower)
9549
+ * 'md' (default) 1rem (16px) title, 0.8125rem description, 28px tile, 16px icon; padding 14px 18px (12px 14px at 480px and narrower)
9550
+ * 'lg' 1.25rem (20px) title, 0.9375rem description, 36px tile, 20px icon; padding 18px 22px (14px 16px at 480px and narrower)
9551
+ * 'xl' 1.5rem (24px) title (1.375rem at 480px and narrower), 1rem description, 44px tile, 24px icon; padding 22px 26px (16px 18px at 480px and narrower)
9552
+ * Padding is built in per size - there is no padding input.
9251
9553
  *
9252
9554
  * Content slots:
9253
9555
  * - `[section-header-icon]`: your own icon (an `<svg>`, an `<img>` ...) shown in the tile instead of the `icon` input.
@@ -9278,8 +9580,8 @@ export declare class SectionHeaderComponent {
9278
9580
  readonly iconBackground: import("@angular/core").InputSignal<string>;
9279
9581
  /** 1px border and 10px corners. */
9280
9582
  readonly bordered: import("@angular/core").InputSignal<boolean>;
9281
- /** 'md' (default) or 'sm'. */
9282
- readonly size: import("@angular/core").InputSignal<"sm" | "md">;
9583
+ /** Visual size: 'sm', 'md' (default), 'lg' or 'xl'. Independent of `level`; anything else renders as 'md'. */
9584
+ readonly size: import("@angular/core").InputSignal<"sm" | "md" | "lg" | "xl">;
9283
9585
  protected readonly titleId: string;
9284
9586
  protected readonly descriptionId: string;
9285
9587
  protected readonly headingLevel: import("@angular/core").Signal<number>;