@forgeroute/ui 0.4.75 → 0.4.77

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.
@@ -68,6 +68,23 @@ export interface ToolbarAction {
68
68
  * the on / off state. Leave unset for ordinary buttons (no attribute).
69
69
  */
70
70
  pressed?: boolean;
71
+ /**
72
+ * Optional confirmation before the click is reported (library source 2026-11-05, not yet published). Set it ONLY on an action that needs a
73
+ * confirm dialog (pause / run now / send to all): the table shows its confirm modal first, emits `(tableButtonClick)` only when the user
74
+ * confirms, and emits nothing on Cancel / Escape / backdrop. An action without `confirm` behaves exactly as before. Not used for the
75
+ * table's own Import and Export. Same copy fields as a row action's `modal` (`message` may be a function read at click time, for text that
76
+ * depends on the host's current state); say what happens before -> after and what is NOT affected.
77
+ */
78
+ confirm?: ToolbarConfirm;
79
+ }
80
+ /** Confirm dialog copy of a toolbar action (see `ToolbarAction.confirm`). */
81
+ export interface ToolbarConfirm {
82
+ title: string;
83
+ message: string | (() => string);
84
+ confirmLabel?: string;
85
+ cancelLabel?: string;
86
+ variant?: 'danger' | 'primary' | 'warning';
87
+ details?: string[];
71
88
  }
72
89
  export interface ConfirmConfig {
73
90
  title: string;
@@ -179,6 +196,28 @@ export interface ColumnDef {
179
196
  * Example: `{ key: 'name', label: 'Name', starFn: (doc) => doc.isAuthForm ? 'Authorization Form' : null }`
180
197
  */
181
198
  starFn?: (item: any) => string | null | undefined;
199
+ /**
200
+ * Library source 2026-11-05, not yet published. Draws a small decorative icon (16px, `aria-hidden`, currentColor, on the first text line, never shrinks)
201
+ * to the LEFT of the cell text, in desktop cells and in the phone card (title, badge pills, detail rows). Returns a `<ui-icon>` key (see `iconPath()`) or a
202
+ * raw 24x24 stroke SVG path (drawing commands and numbers only, same rule as ui-radio's `icon`); null / undefined / '' / anything else draws nothing.
203
+ * Applies to text, badge, date, phone and number cells; never to avatar-name, link, tags, progress, image, days-ago or actions. The cell's text and the row's
204
+ * accessible name are unchanged (see `iconLabelFn` for meaningful icons). Placed before a `starFn` star.
205
+ * Example: `{ key: 'name', label: 'Name', iconFn: (r) => r.kind === 'rental' ? 'wrench' : 'cup' }`
206
+ */
207
+ iconFn?: (item: any) => string | null | undefined;
208
+ /**
209
+ * Library source 2026-11-05, not yet published. Accessible text for a MEANINGFUL `iconFn` icon: rendered as visually hidden text right after the icon
210
+ * (the icon stays `aria-hidden`). Default (absent / null / '') = the icon is decorative. Ignored when no icon is drawn for the row.
211
+ */
212
+ iconLabelFn?: (item: any) => string | null | undefined;
213
+ /**
214
+ * Footer text for this column, from the table's `totalsEndpoint` response (shown only while the table has rows and the totals loaded).
215
+ * Return null / undefined / '' for an empty footer cell. `cellType: 'number'` columns are right-aligned like their body cells.
216
+ * The table's `totalsLabel` goes in the footer cell of the first visible column; when that column has a `footerFn` too, the label is
217
+ * kept as visually hidden text before the value ("Total: $1,200") so it is still announced once.
218
+ * Example: `{ key: 'amount', label: 'Amount', cellType: 'number', footerFn: t => t['amount'] == null ? null : '$' + t['amount'] }`
219
+ */
220
+ footerFn?: (totals: Record<string, string | number | null>) => string | null | undefined;
182
221
  /** Date format string. Default: 'MMM d, y' */
183
222
  dateFormat?: string;
184
223
  /** Returns the display name for the row. Default: item[col.key] */
@@ -1555,6 +1594,16 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
1555
1594
  protected readonly _showHeader: Signal<boolean>;
1556
1595
  /** Optional endpoint that returns Record<string,number> counts per quick-filter value. */
1557
1596
  readonly countsEndpoint: import("@angular/core").InputSignal<string>;
1597
+ /**
1598
+ * Optional footer totals row. Path relative to `baseUrl` (like `endpoint`). When set, the table GETs it with the same query params as the
1599
+ * rows request except paging and sorting (host `params`, lower-cased `search` + `searchFields`, active tab as `filter`, column filters) and
1600
+ * shows a footer built from each column's `footerFn`. The response is `Record<string, string | number | null>`. Totals follow the FILTERED
1601
+ * set, not the page; they are refetched on search / tab / filter / params / refresh() / resetToFirstPage() / import (not on paging or
1602
+ * sorting) and never cached. Hidden while loading, on error, with zero rows, or when the totals request fails (silently).
1603
+ */
1604
+ readonly totalsEndpoint: import("@angular/core").InputSignal<string>;
1605
+ /** Text of the footer's label cell (first visible column) and the phone summary card's accessible name. */
1606
+ readonly totalsLabel: import("@angular/core").InputSignal<string>;
1558
1607
  /**
1559
1608
  * Optional extra query params owned by the host page (e.g. a period picker or a parent-record id),
1560
1609
  * sent with every row, /counts, /filter-counts and export request. When the value changes the table
@@ -1803,6 +1852,23 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
1803
1852
  /** Current active filter/search/sort params — passed to the export so it exports the filtered view. */
1804
1853
  /** Visible searchable column keys (comma-joined) — the table and Export only search what's on screen. */
1805
1854
  protected readonly _searchFields: Signal<string>;
1855
+ /** Latest footer totals response (null = none / failed / not requested). */
1856
+ protected readonly _totals: import("@angular/core").WritableSignal<Record<string, string | number | null> | null>;
1857
+ private _totalsSub?;
1858
+ /** Set by paging and sorting: they reload rows but never change the totals. */
1859
+ private _totalsSkipNext;
1860
+ protected readonly _footerVisible: Signal<boolean>;
1861
+ /** Footer text per visible column key (only columns whose footerFn returns text). */
1862
+ protected readonly _footerCells: Signal<Record<string, string>>;
1863
+ protected readonly _footerPhoneLines: Signal<{
1864
+ key: string;
1865
+ label: string;
1866
+ value: string;
1867
+ }[]>;
1868
+ /** Totals request params: the export params without sorting (the rows request without paging and sorting). */
1869
+ private _totalsParams;
1870
+ /** `keepShown`: a silent (background) refresh keeps the current footer on screen until the new totals arrive. */
1871
+ private _fetchTotals;
1806
1872
  protected readonly _exportParams: Signal<Record<string, string>>;
1807
1873
  /**
1808
1874
  * Toolbar buttons with auto-injected Export (always) and Import (only when
@@ -1868,6 +1934,13 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
1868
1934
  protected rowActionsLabel(item: T): string;
1869
1935
  protected toggleSelectAll(): void;
1870
1936
  protected toggleRow(item: T): void;
1937
+ /**
1938
+ * The table's current query as the parameters it sends with Export: the host `params`, the lower-cased `search` (+ `searchFields`),
1939
+ * the active quick tab as `filter`, `sort` + `direction`, and every active column filter (multi-values comma-joined). A new copy
1940
+ * on every call; reading it changes nothing. A host uses it to act on exactly what the table shows (print the same rows, call a
1941
+ * report endpoint with the same search / filters) without keeping its own copy of that state. Paging is not included.
1942
+ */
1943
+ currentQuery(): Record<string, string>;
1871
1944
  /** Clears the selection — call from the host component after a bulk action completes. */
1872
1945
  clearSelection(): void;
1873
1946
  resetColumns(): void;
@@ -2023,7 +2096,7 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
2023
2096
  protected onRowClick(item: T): void;
2024
2097
  /** Enter / Space on a focused clickable row or card activates it — ignored when focus is on a control inside it. */
2025
2098
  protected onRowKeydown(e: KeyboardEvent, item: T): void;
2026
- protected onInternalButtonClick(type: string): void;
2099
+ protected onInternalButtonClick(type: string): Promise<void>;
2027
2100
  protected onImported(): void;
2028
2101
  /** Row actions visible for the current permission: everything for 'full'; otherwise only View (`type: 'view'`) and actions marked
2029
2102
  * `allowReadOnly` (never the built-in delete). The Actions column itself is shown only while some row has a visible action. */
@@ -2055,6 +2128,16 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
2055
2128
  protected onLinkClick(e: MouseEvent, link: ResolvedLink, col: ColumnDef, item: T): void;
2056
2129
  protected getInitials(name: string): string;
2057
2130
  protected isCardOverdue(col: ColumnDef, item: T): boolean;
2131
+ /** Cell types that never get a leading icon: they draw their own leading visual or are not text-like. */
2132
+ private static readonly _NO_ICON_TYPES;
2133
+ /**
2134
+ * Path of the leading icon for a cell (library source 2026-11-05, not yet published): `iconFn` returns a `<ui-icon>` key (known key wins) or a raw
2135
+ * 24x24 stroke path (drawing commands and numbers only, same rule as ui-radio's `icon`); anything else, an empty value, a throwing `iconFn` or a
2136
+ * non-text-like cell type gives null (nothing is drawn).
2137
+ */
2138
+ protected cellIconPath(col: ColumnDef, item: T): string | null;
2139
+ /** Screen-reader text for a meaningful icon (`iconLabelFn`); '' (decorative) when absent, empty, throwing or when no icon is drawn. */
2140
+ protected cellIconLabel(col: ColumnDef, item: T): string;
2058
2141
  /** Renders any non-badge column value as a plain string for the mobile card view. */
2059
2142
  protected cardCellText(col: ColumnDef, item: T): string;
2060
2143
  /** Refresh data rows only — used internally for sort, filter, search, pagination. */
@@ -2169,6 +2252,16 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
2169
2252
  "required": false;
2170
2253
  "isSignal": true;
2171
2254
  };
2255
+ "totalsEndpoint": {
2256
+ "alias": "totalsEndpoint";
2257
+ "required": false;
2258
+ "isSignal": true;
2259
+ };
2260
+ "totalsLabel": {
2261
+ "alias": "totalsLabel";
2262
+ "required": false;
2263
+ "isSignal": true;
2264
+ };
2172
2265
  "params": {
2173
2266
  "alias": "params";
2174
2267
  "required": false;
@@ -2545,7 +2638,7 @@ export declare class ModalComponent implements OnInit, OnDestroy {
2545
2638
  "close": "close";
2546
2639
  }, never, ["[modal-header-end]", "*", "[modal-footer-left]", "[modal-footer-center]", "[modal-footer-right]"], true, never>;
2547
2640
  }
2548
- export type ToastType = 'success' | 'error' | 'info';
2641
+ export type ToastType = 'success' | 'error' | 'info' | 'warning';
2549
2642
  /** A button on a toast (e.g. "View Contact", "Call Back"). */
2550
2643
  export interface ToastAction {
2551
2644
  /** Identifies the button in `onAction` and in the `(action)` output; also the test id suffix (`toast-action-<id>`). */
@@ -2565,11 +2658,11 @@ export interface ToastActionEvent {
2565
2658
  key?: string;
2566
2659
  }
2567
2660
  /**
2568
- * Per-message options for `show()` / `success()` / `info()` / `error()` / `notify()`. Every field is optional; a call without any of them is a plain
2661
+ * Per-message options for `show()` / `success()` / `info()` / `warning()` / `error()` / `notify()`. Every field is optional; a call without any of them is a plain
2569
2662
  * toast exactly as before.
2570
2663
  */
2571
2664
  export interface ToastOptions {
2572
- /** Only `notify()` reads this (`show` / `success` / `info` / `error` fix their own type). Default `success`. */
2665
+ /** Only `notify()` reads this (`show` / `success` / `info` / `warning` / `error` fix their own type). Default `success`. */
2573
2666
  type?: ToastType;
2574
2667
  /** How long it stays, in ms. Default: 3000 (4000 for errors). */
2575
2668
  duration?: number;
@@ -2651,6 +2744,12 @@ export declare class ToastService implements OnDestroy {
2651
2744
  success(msg: string, durationOrOptions?: number | ToastOptions): void;
2652
2745
  /** Neutral (blue) toast for a result that is neither a success nor a failure, e.g. "No changes to save.". */
2653
2746
  info(msg: string, durationOrOptions?: number | ToastOptions): void;
2747
+ /**
2748
+ * Amber toast for a result that worked but needs attention, e.g. "Saved, but 2 screenshots could not be attached." Announced politely (not as an
2749
+ * alert: nothing failed). Default 4000ms, a little longer than info because the user has something to read and maybe act on.
2750
+ * (library source 2026-11-04, not yet published)
2751
+ */
2752
+ warning(msg: string, durationOrOptions?: number | ToastOptions): void;
2654
2753
  error(msg: string, durationOrOptions?: number | ToastOptions): void;
2655
2754
  /** A toast whose type comes from `options.type` (default `success`); the same as the named methods otherwise. */
2656
2755
  notify(msg: string, options?: ToastOptions): void;
@@ -2869,6 +2968,86 @@ export declare class ProgressBarComponent {
2869
2968
  };
2870
2969
  }, {}, never, never, true, never>;
2871
2970
  }
2971
+ /** Library source 2026-11-05, not yet published. One segment of a `ui-stacked-bar`. */
2972
+ export interface StackedBarSegment {
2973
+ /** Name shown in the legend and read out for the segment. */
2974
+ label: string;
2975
+ /** Amount of this segment (negative / NaN count as 0). */
2976
+ value: number;
2977
+ /** Built-in colour (same set as `ui-progress-bar`). Default: a fixed rotation by position. */
2978
+ variant?: ProgressBarVariant;
2979
+ /** Any CSS colour; wins over `variant`. */
2980
+ color?: string;
2981
+ }
2982
+ /**
2983
+ * A single horizontal bar split into coloured segments by their share of the total (e.g. an aging snapshot: current / 1-30 / 31-60 / 61-90 / 91+).
2984
+ * Pure CSS (no chart library): each segment's width is its rounded share, a value above 0 is never drawn narrower than 2%, segments of 0 are left
2985
+ * out of the bar (but stay in the legend). A total of 0 draws an empty track.
2986
+ *
2987
+ * Accessible without sight: the coloured strip is decorative (`aria-hidden`); the legend is a real list ("<label>: <value> (<share>%)") that is always
2988
+ * in the page, and `showLegend="false"` only hides it visually. The group is named by `ariaLabel`. Each segment also has a hover `title`.
2989
+ * Colours never carry the meaning alone (the legend repeats label, value and share); forced-colors mode draws the segments with a border.
2990
+ *
2991
+ * Inputs: `segments`, `ariaLabel`, `height` (px, default 14), `showLegend` (default true), `formatValue` (default: en-US grouped number; pass e.g. a
2992
+ * currency formatter). Output: none.
2993
+ */
2994
+ export declare class StackedBarComponent {
2995
+ readonly segments: import("@angular/core").InputSignal<StackedBarSegment[]>;
2996
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
2997
+ readonly height: import("@angular/core").InputSignal<number>;
2998
+ readonly showLegend: import("@angular/core").InputSignal<boolean>;
2999
+ readonly formatValue: import("@angular/core").InputSignal<(value: number) => string>;
3000
+ /** Segments with their cleaned value, colour and share (legend order = input order). */
3001
+ protected readonly rows: import("@angular/core").Signal<{
3002
+ percent: number;
3003
+ text: string;
3004
+ title: string;
3005
+ key: string;
3006
+ label: string;
3007
+ color: string;
3008
+ variant: ProgressBarVariant;
3009
+ value: number;
3010
+ }[]>;
3011
+ /** Only the segments that have something to draw. */
3012
+ protected readonly drawn: import("@angular/core").Signal<{
3013
+ percent: number;
3014
+ text: string;
3015
+ title: string;
3016
+ key: string;
3017
+ label: string;
3018
+ color: string;
3019
+ variant: ProgressBarVariant;
3020
+ value: number;
3021
+ }[]>;
3022
+ static ɵfac: i0.ɵɵFactoryDeclaration<StackedBarComponent, never>;
3023
+ static ɵcmp: i0.ɵɵComponentDeclaration<StackedBarComponent, "ui-stacked-bar", never, {
3024
+ "segments": {
3025
+ "alias": "segments";
3026
+ "required": false;
3027
+ "isSignal": true;
3028
+ };
3029
+ "ariaLabel": {
3030
+ "alias": "ariaLabel";
3031
+ "required": false;
3032
+ "isSignal": true;
3033
+ };
3034
+ "height": {
3035
+ "alias": "height";
3036
+ "required": false;
3037
+ "isSignal": true;
3038
+ };
3039
+ "showLegend": {
3040
+ "alias": "showLegend";
3041
+ "required": false;
3042
+ "isSignal": true;
3043
+ };
3044
+ "formatValue": {
3045
+ "alias": "formatValue";
3046
+ "required": false;
3047
+ "isSignal": true;
3048
+ };
3049
+ }, {}, never, never, true, never>;
3050
+ }
2872
3051
  export type ProgressRingVariant = 'blue' | 'green' | 'amber' | 'red' | 'slate' | 'sky';
2873
3052
  /**
2874
3053
  * Circular progress ring with the rounded percentage (or a custom `label`) in the middle.
@@ -3145,6 +3324,153 @@ export declare class StarComponent {
3145
3324
  "starClick": "starClick";
3146
3325
  }, never, never, true, never>;
3147
3326
  }
3327
+ /**
3328
+ * Library source 2026-11-05, not yet published.
3329
+ *
3330
+ * Accessible star rating, 1..`max` (default 5). A ControlValueAccessor with a number value (`0` = no rating).
3331
+ *
3332
+ * - Input mode (default): a `<fieldset role="radiogroup">` (+ `<legend>` = `label`) of native radio inputs that share one `name`, so the browser
3333
+ * gives the roving tab stop and ArrowLeft / ArrowRight / ArrowUp / ArrowDown (move + select) for free; Space selects the focused star natively,
3334
+ * Enter selects it too and Home / End select the first / last star (handled here). Each radio is named "1 star", "2 stars", ...
3335
+ * - `readonly`: all `max` stars are drawn (filled up to the value, the rest outlined) as one `role="img"` named "4 stars out of 5" ("No rating" for 0; with a `label`: "Quality: 4 stars out of 5"). No inputs.
3336
+ * - Validation follows `ui-radio-group` (`UiFieldValidity`, `Validator`, `invalidChange`): `required` -> "<label> is required." when the value is 0;
3337
+ * a value that is not a whole number from 0 to `max` -> "Select a valid option."; messages show after the group lost focus or while `[showErrors]="true"`;
3338
+ * a host `[error]` wins. Disabled and readonly are never invalid.
3339
+ * - Stars are gold (same look as `ui-star`, with a darker amber outline so the shape reaches 3:1 against white); empty stars are outlined, so the value never relies on colour alone. 44px touch targets on touch / phones.
3340
+ *
3341
+ * <ui-star-rating label="Quality" [required]="true" [showErrors]="touched()" [(ngModel)]="form.rating" />
3342
+ * <ui-star-rating [readonly]="true" [value]="4" />
3343
+ */
3344
+ export declare class StarRatingComponent implements ControlValueAccessor, Validator, UiFieldValidity {
3345
+ /** Largest rating (number of stars). Default 5; values below 1 or non-integers are clamped to a whole number of at least 1. */
3346
+ readonly max: import("@angular/core").InputSignal<number>;
3347
+ /** Current rating for standalone / readonly use (`[value]="4"`); `0` = none. With forms, the control value wins after it is written. */
3348
+ readonly value: import("@angular/core").InputSignal<number>;
3349
+ readonly label: import("@angular/core").InputSignal<string>;
3350
+ /** Accessible name when there is no visible `label` (default "Rating"). */
3351
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
3352
+ readonly hint: import("@angular/core").InputSignal<string>;
3353
+ readonly error: import("@angular/core").InputSignal<string>;
3354
+ readonly required: import("@angular/core").InputSignal<boolean>;
3355
+ /** Reveal the built-in error messages now (e.g. after a failed Save click), without waiting for blur. */
3356
+ readonly showErrors: import("@angular/core").InputSignal<boolean>;
3357
+ /** Star size in px (default 24). */
3358
+ readonly size: import("@angular/core").InputSignal<number>;
3359
+ /** Display only: filled stars as one image named "4 stars out of 5"; no inputs, never invalid. */
3360
+ readonly readonly: import("@angular/core").InputSignal<boolean>;
3361
+ /** Native `name` shared by the radios; a unique one is generated when omitted. */
3362
+ readonly name: import("@angular/core").InputSignal<string>;
3363
+ readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
3364
+ private readonly _cvaDisabled;
3365
+ protected readonly disabled: import("@angular/core").Signal<boolean>;
3366
+ /** Emits the new rating when the USER picks a star (not for values the host writes). */
3367
+ readonly valueChange: import("@angular/core").OutputEmitterRef<number>;
3368
+ /** Emits whenever the field becomes invalid / valid. */
3369
+ readonly invalidChange: import("@angular/core").OutputEmitterRef<boolean>;
3370
+ protected readonly _value: import("@angular/core").WritableSignal<number>;
3371
+ protected readonly _max: import("@angular/core").Signal<number>;
3372
+ protected readonly _stars: import("@angular/core").Signal<number[]>;
3373
+ /** Stars drawn filled: the value, kept inside 0..max (an invalid value never overflows the row). */
3374
+ protected readonly _shown: import("@angular/core").Signal<number>;
3375
+ protected readonly _readonlyText: import("@angular/core").Signal<string>;
3376
+ protected readonly _path = "M10 1.5l2.6 5.3 5.9.9-4.25 4.15 1 5.85L10 14.9l-5.25 2.8 1-5.85L1.5 7.7l5.9-.9L10 1.5z";
3377
+ private readonly _generatedName;
3378
+ protected get _name(): string;
3379
+ protected readonly _descId: string;
3380
+ private readonly _host;
3381
+ private readonly _reveal;
3382
+ private readonly _issue;
3383
+ /** True while the value breaks a built-in rule or the host passed an `[error]`. */
3384
+ readonly invalid: import("@angular/core").Signal<boolean>;
3385
+ /** Message of the first broken built-in rule ('' when valid), shown or not. */
3386
+ readonly errorMessage: import("@angular/core").Signal<string>;
3387
+ protected readonly _activeError: import("@angular/core").Signal<string>;
3388
+ private _onValidatorChange;
3389
+ constructor();
3390
+ /** Re-run the form control's validation when a rule input (required, max) changes. */
3391
+ ngOnChanges(): void;
3392
+ validate(control: AbstractControl): ValidationErrors | null;
3393
+ registerOnValidatorChange(fn: () => void): void;
3394
+ private _onChange;
3395
+ private _onTouched;
3396
+ writeValue(val: number | null): void;
3397
+ registerOnChange(fn: (v: number) => void): void;
3398
+ registerOnTouched(fn: () => void): void;
3399
+ setDisabledState(d: boolean): void;
3400
+ private static _norm;
3401
+ protected onSelect(n: number): void;
3402
+ /** Enter selects the focused star (Space and the arrow keys are native radio behaviour); Home / End select the first / last star. */
3403
+ protected onKeydown(event: KeyboardEvent, n: number): void;
3404
+ /** Touched once focus leaves the whole group (moving between its stars does not count). */
3405
+ protected onFocusOut(event: FocusEvent): void;
3406
+ private _check;
3407
+ static ɵfac: i0.ɵɵFactoryDeclaration<StarRatingComponent, never>;
3408
+ static ɵcmp: i0.ɵɵComponentDeclaration<StarRatingComponent, "ui-star-rating", never, {
3409
+ "max": {
3410
+ "alias": "max";
3411
+ "required": false;
3412
+ "isSignal": true;
3413
+ };
3414
+ "value": {
3415
+ "alias": "value";
3416
+ "required": false;
3417
+ "isSignal": true;
3418
+ };
3419
+ "label": {
3420
+ "alias": "label";
3421
+ "required": false;
3422
+ "isSignal": true;
3423
+ };
3424
+ "ariaLabel": {
3425
+ "alias": "ariaLabel";
3426
+ "required": false;
3427
+ "isSignal": true;
3428
+ };
3429
+ "hint": {
3430
+ "alias": "hint";
3431
+ "required": false;
3432
+ "isSignal": true;
3433
+ };
3434
+ "error": {
3435
+ "alias": "error";
3436
+ "required": false;
3437
+ "isSignal": true;
3438
+ };
3439
+ "required": {
3440
+ "alias": "required";
3441
+ "required": false;
3442
+ "isSignal": true;
3443
+ };
3444
+ "showErrors": {
3445
+ "alias": "showErrors";
3446
+ "required": false;
3447
+ "isSignal": true;
3448
+ };
3449
+ "size": {
3450
+ "alias": "size";
3451
+ "required": false;
3452
+ "isSignal": true;
3453
+ };
3454
+ "readonly": {
3455
+ "alias": "readonly";
3456
+ "required": false;
3457
+ "isSignal": true;
3458
+ };
3459
+ "name": {
3460
+ "alias": "name";
3461
+ "required": false;
3462
+ "isSignal": true;
3463
+ };
3464
+ "_disabledInput": {
3465
+ "alias": "disabled";
3466
+ "required": false;
3467
+ "isSignal": true;
3468
+ };
3469
+ }, {
3470
+ "valueChange": "valueChange";
3471
+ "invalidChange": "invalidChange";
3472
+ }, never, never, true, never>;
3473
+ }
3148
3474
  export type ImageRepositionShape = 'circle' | 'rounded';
3149
3475
  /**
3150
3476
  * Drag-to-center photo frame. The image fills the frame (`object-fit: cover`) and the user drags it, or uses the arrow
@@ -3969,6 +4295,15 @@ export interface RadioOption {
3969
4295
  * path. Decorative (`aria-hidden`); none when omitted.
3970
4296
  */
3971
4297
  icon?: string;
4298
+ /**
4299
+ * Library source 2026-11-05, not yet published. Link shown after the option's description (e.g. "Read the terms"): only http(s), mailto, tel and
4300
+ * in-app paths are linked, an absolute http(s) address opens in a new tab. `testId` is the link's `data-testid`. None when omitted.
4301
+ */
4302
+ descriptionLink?: {
4303
+ label: string;
4304
+ url: string;
4305
+ testId?: string;
4306
+ };
3972
4307
  }
3973
4308
  /**
3974
4309
  * Group of native radio buttons inside a `<fieldset>` (+ `<legend>` = `label`), a ControlValueAccessor (string value, `''`
@@ -5544,6 +5879,26 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
5544
5879
  * view exists, or on a disabled field, it does nothing and never throws.
5545
5880
  */
5546
5881
  focus(options?: FocusOptions): void;
5882
+ /**
5883
+ * Library source 2026-11-05, not yet published. Caret access for hosts (e.g. an "insert variable at the cursor" chip row), so a host never
5884
+ * queries the inner element. Reach it with `viewChild(TextInputComponent)`. All three methods are safe at any time: before the view exists, on a
5885
+ * disabled / read-only field, or for a type that has no selection API (email, number) they do nothing / return null and never throw.
5886
+ *
5887
+ * `getSelection()` -> `{ start, end }` of the selected text (equal when only a caret) or `null` when it cannot be read.
5888
+ */
5889
+ getSelection(): {
5890
+ start: number;
5891
+ end: number;
5892
+ } | null;
5893
+ /** Selects `start`..`end` (a caret when `end` is left out); values are clamped to the text. Does nothing where the selection API is unavailable. */
5894
+ setSelection(start: number, end?: number): void;
5895
+ /**
5896
+ * Inserts `text` at the caret, replacing any selected text, and puts the caret right after it. The change goes through the normal typing path
5897
+ * (formatting, `ngModel` / form control, `valueChange`), exactly as if the user had typed it, and `maxlength` caps it like typing does (the
5898
+ * part that does not fit is not inserted). With no caret known (a type without a selection API) the text is appended. Does nothing on a
5899
+ * disabled or read-only field or for an empty `text`.
5900
+ */
5901
+ insertAtCaret(text: string): void;
5547
5902
  private _onChange;
5548
5903
  private _onTouched;
5549
5904
  private _onValidatorChange;
@@ -5858,6 +6213,10 @@ export declare class TextareaInputComponent implements ControlValueAccessor, Val
5858
6213
  readonly errorMessage: import("@angular/core").Signal<string>;
5859
6214
  /** Emits whenever the field becomes invalid / valid. */
5860
6215
  readonly invalidChange: import("@angular/core").OutputEmitterRef<boolean>;
6216
+ /** Library source 2026-11-05, not yet published. Emits when the inner `<textarea>` gains focus (same as `ui-text-input`). */
6217
+ readonly focused: import("@angular/core").OutputEmitterRef<void>;
6218
+ /** Library source 2026-11-05, not yet published. Emits when the inner `<textarea>` loses focus (same as `ui-text-input`); the form control is marked touched and the built-in error reveal still happens. */
6219
+ readonly blurred: import("@angular/core").OutputEmitterRef<void>;
5861
6220
  protected readonly _activeError: import("@angular/core").Signal<string>;
5862
6221
  private _onValidatorChange;
5863
6222
  constructor();
@@ -5873,6 +6232,27 @@ export declare class TextareaInputComponent implements ControlValueAccessor, Val
5873
6232
  * nothing and never throws.
5874
6233
  */
5875
6234
  focus(options?: FocusOptions): void;
6235
+ /**
6236
+ * Library source 2026-11-05, not yet published. Caret access for hosts (e.g. an "insert variable at the cursor" chip row), so a host never
6237
+ * queries the inner element. Reach it with `viewChild(TextareaInputComponent)`. All three methods are safe at any time: before the view exists, on a
6238
+ * disabled / read-only field they do nothing / return null and never throw.
6239
+ *
6240
+ * `getSelection()` -> `{ start, end }` of the selected text (equal when only a caret) or `null` when it cannot be read.
6241
+ */
6242
+ getSelection(): {
6243
+ start: number;
6244
+ end: number;
6245
+ } | null;
6246
+ /** Selects `start`..`end` (a caret when `end` is left out); values are clamped to the text. Does nothing where the selection API is unavailable. */
6247
+ setSelection(start: number, end?: number): void;
6248
+ /**
6249
+ * Inserts `text` at the caret, replacing any selected text, and puts the caret right after it. The change goes through the normal typing path
6250
+ * (`ngModel` / form control), exactly as if the user had typed it, and `maxlength` caps it like typing does (the
6251
+ * part that does not fit is not inserted). With no caret known the text is appended. Does nothing on a
6252
+ * disabled or read-only field or for an empty `text`.
6253
+ */
6254
+ insertAtCaret(text: string): void;
6255
+ private _textarea;
5876
6256
  private _onChange;
5877
6257
  private _onTouched;
5878
6258
  writeValue(val: string | null): void;
@@ -5880,6 +6260,7 @@ export declare class TextareaInputComponent implements ControlValueAccessor, Val
5880
6260
  registerOnTouched(fn: () => void): void;
5881
6261
  setDisabledState(d: boolean): void;
5882
6262
  protected onInput(event: Event): void;
6263
+ protected onFocus(): void;
5883
6264
  protected onBlur(): void;
5884
6265
  private _check;
5885
6266
  static ɵfac: i0.ɵɵFactoryDeclaration<TextareaInputComponent, never>;
@@ -5956,6 +6337,8 @@ export declare class TextareaInputComponent implements ControlValueAccessor, Val
5956
6337
  };
5957
6338
  }, {
5958
6339
  "invalidChange": "invalidChange";
6340
+ "focused": "focused";
6341
+ "blurred": "blurred";
5959
6342
  }, never, ["[uiLabelEnd]"], true, never>;
5960
6343
  }
5961
6344
  export type TextSize = 'sm' | 'md' | 'lg';
@@ -6393,7 +6776,7 @@ export declare class CopyFieldComponent implements OnDestroy {
6393
6776
  /** Neither the Clipboard API nor the fallback could copy. */
6394
6777
  readonly copyFailed: import("@angular/core").OutputEmitterRef<void>;
6395
6778
  protected readonly _id: string;
6396
- protected readonly _state: import("@angular/core").WritableSignal<"idle" | "copied" | "failed">;
6779
+ protected readonly _state: import("@angular/core").WritableSignal<"idle" | "failed" | "copied">;
6397
6780
  protected readonly _announcement: import("@angular/core").Signal<string>;
6398
6781
  protected readonly _buttonName: import("@angular/core").Signal<string>;
6399
6782
  protected readonly _describedBy: import("@angular/core").Signal<string | null>;
@@ -7549,6 +7932,13 @@ export declare class FormColSpanDirective {
7549
7932
  * <ui-button list-item-action variant="icon" ariaLabel="Remove" (click)="remove(d)">…</ui-button>
7550
7933
  * </ui-list-item>
7551
7934
  *
7935
+ * Library source 2026-11-05, not yet published: row-end content slot. An element with the `list-item-end` attribute (a `<ui-star-rating>`, a badge, a price...) is
7936
+ * projected at the END of the row, after the text and before the busy spinner and the `list-item-action` buttons, vertically centred, at its own size. Like the action
7937
+ * slot it sits outside the row's label: clicks inside it never emit `select` (also on a plain pressable row), and Enter / Space inside it are not treated as a row
7938
+ * press. Absent = no extra DOM, nothing changes. Accessibility note: a plain pressable row (`leading="none"`, interactive) is `role="button"`, whose children are presentational, so
7939
+ * INTERACTIVE content in this slot (a `<ui-star-rating>`, a button) should go on a row with `[interactive]="false"` (no role, nothing pressable); a badge or other static text is fine on any row.
7940
+ * <ui-list-item [title]="r.name" [details]="[r.date]"><ui-star-rating list-item-end [readonly]="true" [value]="r.rating" [size]="16" /></ui-list-item>
7941
+ *
7552
7942
  * Library source 2026-11-04, not yet published: `[disabled]` (aria-disabled, not focusable, never emits `select`, non-colour cue), `[busy]`
7553
7943
  * (aria-busy, spinner, presses ignored) and a leading image slot, `<img list-item-image>` / `<ui-image list-item-image>`, rendered in front of
7554
7944
  * the text and instead of the icon tile (clicks on it select a plain row; on a radio / checkbox row they do not, because the image sits outside
@@ -7561,10 +7951,22 @@ export declare class FormColSpanDirective {
7561
7951
  */
7562
7952
  /** One secondary line under the title: plain text, or text with a small icon and a tone (`danger` red, `warning` amber). */
7563
7953
  export type ListItemDetail = string | {
7564
- text: string;
7954
+ text?: string;
7955
+ segments?: ListItemSegment[];
7565
7956
  icon?: string;
7566
7957
  tone?: 'default' | 'warning' | 'danger';
7567
7958
  };
7959
+ /**
7960
+ * One piece of a rich detail line (library source 2026-11-04, not yet published): plain text, or text shown in bold and/or as inline code. Rich text
7961
+ * is structured data, never HTML, so nothing is injected. `{ segments: ['Click ', { text: 'Connect', bold: true }, ' and copy ', { text: 'client_id', code: true }] }`
7962
+ * renders `Click <strong>Connect</strong> and copy <code>client_id</code>`. A detail with `segments` ignores `text` for display (when `text` is empty
7963
+ * the segments' plain text is used, e.g. for the visible-line check).
7964
+ */
7965
+ export type ListItemSegment = string | {
7966
+ text: string;
7967
+ bold?: boolean;
7968
+ code?: boolean;
7969
+ };
7568
7970
  /** Colour of the optional leading icon tile. */
7569
7971
  export type ListItemIconColor = 'slate' | 'amber' | 'red' | 'blue' | 'green' | 'purple' | 'teal' | 'orange';
7570
7972
  export declare class ListItemComponent implements AfterContentChecked {
@@ -7652,6 +8054,11 @@ export declare class ListItemComponent implements AfterContentChecked {
7652
8054
  protected onRowKey(e: Event): void;
7653
8055
  protected readonly visibleDetails: () => {
7654
8056
  text: string;
8057
+ segs: {
8058
+ text: string;
8059
+ bold: boolean;
8060
+ code: boolean;
8061
+ }[] | null;
7655
8062
  d: string | null;
7656
8063
  tone: "default" | "warning" | "danger";
7657
8064
  }[];
@@ -7744,7 +8151,7 @@ export declare class ListItemComponent implements AfterContentChecked {
7744
8151
  };
7745
8152
  }, {
7746
8153
  "select": "select";
7747
- }, never, ["[list-item-image]", "[list-item-action], [li-action]"], true, never>;
8154
+ }, never, ["[list-item-image]", "[list-item-end]", "[list-item-action], [li-action]"], true, never>;
7748
8155
  }
7749
8156
  /** Colour of the priority dot (`high` red, `medium` amber, `low` grey, `blue`, `green`); `none` = no dot. */
7750
8157
  export type CardListIndicator = 'high' | 'medium' | 'low' | 'blue' | 'green' | 'none';
@@ -8707,7 +9114,7 @@ export declare class ChipGroupComponent {
8707
9114
  readonly spaceAbove: import("@angular/core").InputSignal<"none" | "sm" | "md">;
8708
9115
  /** Space below the chip group. */
8709
9116
  readonly spaceBelow: import("@angular/core").InputSignal<"none" | "sm" | "md">;
8710
- protected readonly _gap: import("@angular/core").Signal<"6px" | "12px" | "8px">;
9117
+ protected readonly _gap: import("@angular/core").Signal<"8px" | "6px" | "12px">;
8711
9118
  protected readonly _spaceAbove: import("@angular/core").Signal<"0" | "6px" | "12px">;
8712
9119
  protected readonly _spaceBelow: import("@angular/core").Signal<"0" | "6px" | "12px">;
8713
9120
  static ɵfac: i0.ɵɵFactoryDeclaration<ChipGroupComponent, never>;
@@ -9087,13 +9494,13 @@ export declare class AlertComponent {
9087
9494
  }
9088
9495
  /**
9089
9496
  * Every key `<ui-icon>` draws by itself (the data-table action keys such as `view` / `edit` / `call` are accepted too, see `builtInActionIcon`).
9090
- * Each resolves with `iconPath(key)`. Includes `search`, `cup` (food / drink) and `wrench` (rental / tools), library source 2026-11-04, and `cash` (banknote) and `dollar` (payment methods / amounts), library source 2026-11-05, not yet published.
9497
+ * Each resolves with `iconPath(key)`. Includes `search`, `cup` (food / drink) and `wrench` (rental / tools), library source 2026-11-04, and `cash` (banknote) and `dollar` (payment methods / amounts), library source 2026-11-05, not yet published. Also `star`, `gift`, `award` and `calendar-check` (library source 2026-11-05, not yet published).
9091
9498
  */
9092
9499
  export declare const ICON_NAMES: readonly string[];
9093
9500
  /** The SVG path (24×24 stroke icon) for an icon key, or undefined when the key is unknown. */
9094
9501
  export declare function iconPath(name: string): string | undefined;
9095
9502
  /** Keys with an icon of their own (the data-table action keys are accepted too — see `builtInActionIcon`). */
9096
- export type IconName = 'add' | 'close' | 'check' | 'upload' | 'image' | 'chevron-up' | 'chevron-down' | 'arrow-left' | 'bell' | 'print' | 'lock' | 'shield' | 'arrow-up' | 'arrow-down' | 'arrow-right' | 'document' | 'grip' | 'card' | 'bank' | 'view' | 'view-off' | 'edit' | 'delete' | 'download' | 'duplicate' | 'archive' | 'restore' | 'share' | 'email' | 'message' | 'call' | 'refund' | 'chevron-right' | 'link' | 'save' | 'chart' | 'clipboard' | 'unlink' | 'send' | 'refresh' | 'search' | 'cup' | 'wrench' | 'cash' | 'dollar' | 'history' | 'move-up' | 'move-down';
9503
+ export type IconName = 'add' | 'close' | 'check' | 'upload' | 'image' | 'chevron-up' | 'chevron-down' | 'arrow-left' | 'bell' | 'print' | 'lock' | 'shield' | 'arrow-up' | 'arrow-down' | 'arrow-right' | 'document' | 'grip' | 'card' | 'bank' | 'view' | 'view-off' | 'edit' | 'delete' | 'download' | 'duplicate' | 'archive' | 'restore' | 'share' | 'email' | 'message' | 'call' | 'refund' | 'chevron-right' | 'link' | 'save' | 'chart' | 'clipboard' | 'unlink' | 'send' | 'refresh' | 'search' | 'cup' | 'wrench' | 'cash' | 'dollar' | 'star' | 'gift' | 'award' | 'calendar-check' | 'history' | 'move-up' | 'move-down';
9097
9504
  /**
9098
9505
  * A clickable icon. The host passes a key (`name="delete"`) and the library draws that icon; clicking it emits
9099
9506
  * `iconClick`, and the host does the actual work (delete the row, open a panel, …).
@@ -10508,6 +10915,16 @@ export declare function humanReadableMessage(value: unknown): string | null;
10508
10915
  export declare class RadioComponent {
10509
10916
  readonly label: import("@angular/core").InputSignal<string>;
10510
10917
  readonly description: import("@angular/core").InputSignal<string>;
10918
+ /**
10919
+ * Library source 2026-11-05, not yet published. Optional link shown after the description: `linkLabel` is its text, `linkUrl` its address. Only `http:`, `https:`,
10920
+ * `mailto:` and `tel:` addresses and in-app paths (`/...`, `#...`) are linked; anything else (`javascript:`, `data:`, empty) draws nothing. An absolute http(s)
10921
+ * address opens in a new tab (`noopener noreferrer`, with "(opens in a new tab)" for screen readers); the others follow in the same tab. The radio's
10922
+ * accessible name stays the label only.
10923
+ */
10924
+ readonly linkLabel: import("@angular/core").InputSignal<string>;
10925
+ readonly linkUrl: import("@angular/core").InputSignal<string>;
10926
+ /** `data-testid` of the link; none when empty. */
10927
+ readonly linkTestId: import("@angular/core").InputSignal<string>;
10511
10928
  /**
10512
10929
  * Library source 2026-11-04, not yet published. Optional icon drawn in front of the label: a `<ui-icon>` key (`cup`, `wrench`, `card`, ...) or a raw 24x24
10513
10930
  * stroke SVG path (`M12 5v14 M5 12h14`). Decorative (`aria-hidden`), so the accessible name stays the label. Empty (default), an unknown key or
@@ -10532,11 +10949,14 @@ export declare class RadioComponent {
10532
10949
  protected readonly disabled: import("@angular/core").InputSignal<boolean>;
10533
10950
  /** Path of the icon: a known icon key, else the text itself when it looks like an SVG path (drawing commands and numbers only), else none. */
10534
10951
  protected readonly _iconD: import("@angular/core").Signal<string | null>;
10952
+ /** The address to link, or null when the link is not drawn (no label, empty or unsafe address). */
10953
+ protected readonly _linkHref: import("@angular/core").Signal<string | null>;
10954
+ protected readonly _linkNewTab: import("@angular/core").Signal<boolean>;
10535
10955
  /** Id of the visible label text. Optional: a host (e.g. `ui-radio-group`) can set it to point another element at the label with `aria-labelledby`; a unique id is generated when empty. */
10536
10956
  readonly labelId: import("@angular/core").InputSignal<string>;
10537
10957
  private readonly _generatedLabelId;
10538
10958
  protected readonly _labelId: import("@angular/core").Signal<string>;
10539
- /** With a description inside the <label>, the accessible name would read "Email We send a message": name the input by the label text only. */
10959
+ /** With a description or link inside the <label>, the accessible name would read "Email We send a message": name the input by the label text only. */
10540
10960
  protected readonly _labelledBy: import("@angular/core").Signal<string | null>;
10541
10961
  protected readonly _descriptionId: string;
10542
10962
  /** Group hint/error id plus the option's own description (kept out of the label so the accessible name is label-only). */
@@ -10556,6 +10976,21 @@ export declare class RadioComponent {
10556
10976
  "required": false;
10557
10977
  "isSignal": true;
10558
10978
  };
10979
+ "linkLabel": {
10980
+ "alias": "linkLabel";
10981
+ "required": false;
10982
+ "isSignal": true;
10983
+ };
10984
+ "linkUrl": {
10985
+ "alias": "linkUrl";
10986
+ "required": false;
10987
+ "isSignal": true;
10988
+ };
10989
+ "linkTestId": {
10990
+ "alias": "linkTestId";
10991
+ "required": false;
10992
+ "isSignal": true;
10993
+ };
10559
10994
  "icon": {
10560
10995
  "alias": "icon";
10561
10996
  "required": false;
@@ -16134,7 +16569,7 @@ export declare class PaymentSidePanelComponent {
16134
16569
  private readonly terminalAvailable;
16135
16570
  /** value -> label of every live method the rendered plugins contribute (the first plugin wins a duplicate value). */
16136
16571
  private readonly liveMethods;
16137
- protected readonly kind: import("@angular/core").Signal<"none" | "live" | "terminal" | "manual">;
16572
+ protected readonly kind: import("@angular/core").Signal<"none" | "manual" | "live" | "terminal">;
16138
16573
  private kindOf;
16139
16574
  /** The method list as shown: record-only built-ins (a plugin takes over its own values), plugin extras, and only manual ones while a split is being built. */
16140
16575
  readonly methodList: import("@angular/core").Signal<PaymentMethodOption[]>;