@forgeroute/ui 0.4.4 → 0.4.5

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.
@@ -940,6 +940,13 @@ export interface SelectOption<V extends string | number = string> {
940
940
  * `aria-describedby`) and sets it as the option's `title` tooltip where the browser shows one. Options without it are unchanged.
941
941
  */
942
942
  description?: string;
943
+ /**
944
+ * Optional short tag shown after the label, e.g. `{ label: 'Pro plan', badge: 'Partner: Acme' }` is listed as "Pro plan — Partner: Acme".
945
+ * A native `<option>` can only hold text (no elements, no colours), so the badge is a TEXT suffix joined by " —" (space, em dash,
946
+ * space); screen readers read it as part of the option. The selected value, search-by-typing and the description are unaffected.
947
+ * Options without it are unchanged.
948
+ */
949
+ badge?: string;
943
950
  }
944
951
  export declare class SelectComponent implements ControlValueAccessor, Validator, UiFieldValidity {
945
952
  readonly label: import("@angular/core").InputSignal<string>;
@@ -1808,6 +1815,10 @@ export declare class SidePanelComponent implements OnDestroy {
1808
1815
  readonly primaryVariant: import("@angular/core").InputSignal<"primary" | "danger" | "warning">;
1809
1816
  readonly primaryLoading: import("@angular/core").InputSignal<boolean>;
1810
1817
  readonly primaryDisabled: import("@angular/core").InputSignal<boolean>;
1818
+ /** `data-testid` of the Cancel button; none when empty (default). */
1819
+ readonly cancelTestId: import("@angular/core").InputSignal<string>;
1820
+ /** `data-testid` of the primary footer button; none when empty (default). */
1821
+ readonly primaryTestId: import("@angular/core").InputSignal<string>;
1811
1822
  readonly closed: import("@angular/core").OutputEmitterRef<void>;
1812
1823
  readonly primaryClick: import("@angular/core").OutputEmitterRef<void>;
1813
1824
  protected readonly titleId: string;
@@ -1875,10 +1886,20 @@ export declare class SidePanelComponent implements OnDestroy {
1875
1886
  "required": false;
1876
1887
  "isSignal": true;
1877
1888
  };
1889
+ "cancelTestId": {
1890
+ "alias": "cancelTestId";
1891
+ "required": false;
1892
+ "isSignal": true;
1893
+ };
1894
+ "primaryTestId": {
1895
+ "alias": "primaryTestId";
1896
+ "required": false;
1897
+ "isSignal": true;
1898
+ };
1878
1899
  }, {
1879
1900
  "closed": "closed";
1880
1901
  "primaryClick": "primaryClick";
1881
- }, never, ["*"], true, never>;
1902
+ }, never, ["*", "[panel-footer-extra]"], true, never>;
1882
1903
  }
1883
1904
  export declare class ModalComponent implements OnInit, OnDestroy {
1884
1905
  readonly open: import("@angular/core").InputSignal<boolean>;
@@ -1886,6 +1907,15 @@ export declare class ModalComponent implements OnInit, OnDestroy {
1886
1907
  readonly description: import("@angular/core").InputSignal<string>;
1887
1908
  readonly maxWidth: import("@angular/core").InputSignal<string>;
1888
1909
  readonly bodyOverflow: import("@angular/core").InputSignal<"hidden" | "auto" | "visible">;
1910
+ /** `data-testid` of the dialog element itself (the host `<ui-modal>` is always in the page, the dialog only while open). None when empty. */
1911
+ readonly dialogTestId: import("@angular/core").InputSignal<string>;
1912
+ /** Hides the header X button (e.g. while a request is running). Escape and a backdrop click still close unless `closable` is false. */
1913
+ readonly hideClose: import("@angular/core").InputSignal<boolean>;
1914
+ /**
1915
+ * `false` = the user cannot dismiss the dialog: the X button is hidden and Escape / a backdrop click do not emit `close`
1916
+ * (e.g. while a save is running; the host closes it itself). Default `true` = today's behaviour.
1917
+ */
1918
+ readonly closable: import("@angular/core").InputSignal<boolean>;
1889
1919
  readonly close: import("@angular/core").OutputEmitterRef<void>;
1890
1920
  protected readonly titleId: string;
1891
1921
  private readonly el;
@@ -1929,9 +1959,24 @@ export declare class ModalComponent implements OnInit, OnDestroy {
1929
1959
  "required": false;
1930
1960
  "isSignal": true;
1931
1961
  };
1962
+ "dialogTestId": {
1963
+ "alias": "dialogTestId";
1964
+ "required": false;
1965
+ "isSignal": true;
1966
+ };
1967
+ "hideClose": {
1968
+ "alias": "hideClose";
1969
+ "required": false;
1970
+ "isSignal": true;
1971
+ };
1972
+ "closable": {
1973
+ "alias": "closable";
1974
+ "required": false;
1975
+ "isSignal": true;
1976
+ };
1932
1977
  }, {
1933
1978
  "close": "close";
1934
- }, never, ["*", "[modal-footer-left]", "[modal-footer-right]"], true, never>;
1979
+ }, never, ["*", "[modal-footer-left]", "[modal-footer-center]", "[modal-footer-right]"], true, never>;
1935
1980
  }
1936
1981
  export type ToastType = 'success' | 'error' | 'info';
1937
1982
  export declare class ToastService implements OnDestroy {
@@ -2418,6 +2463,8 @@ export interface CheckboxOption {
2418
2463
  /** Helper text under the option. */
2419
2464
  description?: string;
2420
2465
  disabled?: boolean;
2466
+ /** `data-testid` of this option's native checkbox (e.g. for end-to-end tests); none when omitted. */
2467
+ testId?: string;
2421
2468
  }
2422
2469
  export declare class CheckboxComponent implements ControlValueAccessor, Validator, UiFieldValidity {
2423
2470
  readonly label: import("@angular/core").InputSignal<string>;
@@ -2434,6 +2481,26 @@ export declare class CheckboxComponent implements ControlValueAccessor, Validato
2434
2481
  readonly options: import("@angular/core").InputSignal<CheckboxOption[]>;
2435
2482
  /** Group heading (the fieldset's legend). */
2436
2483
  readonly legend: import("@angular/core").InputSignal<string>;
2484
+ /**
2485
+ * `ui-checkbox-group` is the same component under a group-friendly tag: `<ui-checkbox-group legend="Interests" [options]="opts" [(ngModel)]="picked" />`
2486
+ * (value = array of ticked option values). On the `<ui-checkbox-group>` tag the legend falls back to `label` when `legend` is empty (`<ui-checkbox [options]>` ignores `label` as before).
2487
+ */
2488
+ protected readonly _legend: import("@angular/core").Signal<string>;
2489
+ /** Group mode: lay the options out in a column (default) or in a wrapping row. */
2490
+ readonly orientation: import("@angular/core").InputSignal<"vertical" | "horizontal">;
2491
+ /**
2492
+ * Group mode: the ticked option values as a two-way model (`[(values)]`), an alternative to ngModel / forms. Unset (default) = the
2493
+ * group is driven by ngModel / FormControl only. Values that are not an option are dropped and the order follows `options`.
2494
+ */
2495
+ readonly values: import("@angular/core").ModelSignal<string[] | undefined>;
2496
+ /** Single mode: small helper text under the label, linked to the native checkbox with `aria-describedby`. None when empty (default). */
2497
+ readonly description: import("@angular/core").InputSignal<string>;
2498
+ /** Set when the host projects a `[checkbox-trailing]` element (see `CheckboxTrailingDirective`). */
2499
+ private readonly _trailingContent;
2500
+ protected readonly _trailing: import("@angular/core").Signal<boolean>;
2501
+ private readonly _host;
2502
+ /** `aria-describedby` of the single checkbox: its description, then the error / hint; none when neither exists (as before). */
2503
+ protected readonly _singleDescribedBy: import("@angular/core").Signal<string | null>;
2437
2504
  /** Indent this checkbox (or the whole group) under its parent option, aligned with the parent's label. */
2438
2505
  readonly indent: import("@angular/core").InputSignal<boolean>;
2439
2506
  protected readonly groupMode: import("@angular/core").Signal<boolean>;
@@ -2460,6 +2527,14 @@ export declare class CheckboxComponent implements ControlValueAccessor, Validato
2460
2527
  protected readonly _activeError: import("@angular/core").Signal<string>;
2461
2528
  private _onValidatorChange;
2462
2529
  constructor();
2530
+ /**
2531
+ * Puts the box back to a state chosen by the host after it refused a change (e.g. a confirm was declined). Writes the model, the
2532
+ * native input(s) and the form control, which re-setting the same bound value cannot do (the one-way binding sees no change
2533
+ * while the DOM and the internal state already moved). Single mode: `reset(false)` / `reset(true)`; group mode: `reset(['a'])`.
2534
+ */
2535
+ reset(value?: boolean | string[]): void;
2536
+ /** Sets every native checkbox of this component to the state the component holds (the DOM may have moved ahead of it). */
2537
+ private _syncNative;
2463
2538
  /** Re-run the form control's validation when a rule input (`required`, `requiredMessage`, `label`) changes. */
2464
2539
  ngOnChanges(): void;
2465
2540
  validate(control: AbstractControl): ValidationErrors | null;
@@ -2481,7 +2556,7 @@ export declare class CheckboxComponent implements ControlValueAccessor, Validato
2481
2556
  /** Group mode: ticks / unticks one option; the form gets the full list of ticked values. */
2482
2557
  onToggleOption(value: string, event: Event): void;
2483
2558
  static ɵfac: i0.ɵɵFactoryDeclaration<CheckboxComponent, never>;
2484
- static ɵcmp: i0.ɵɵComponentDeclaration<CheckboxComponent, "ui-checkbox", never, {
2559
+ static ɵcmp: i0.ɵɵComponentDeclaration<CheckboxComponent, "ui-checkbox, ui-checkbox-group", never, {
2485
2560
  "label": {
2486
2561
  "alias": "label";
2487
2562
  "required": false;
@@ -2512,6 +2587,21 @@ export declare class CheckboxComponent implements ControlValueAccessor, Validato
2512
2587
  "required": false;
2513
2588
  "isSignal": true;
2514
2589
  };
2590
+ "orientation": {
2591
+ "alias": "orientation";
2592
+ "required": false;
2593
+ "isSignal": true;
2594
+ };
2595
+ "values": {
2596
+ "alias": "values";
2597
+ "required": false;
2598
+ "isSignal": true;
2599
+ };
2600
+ "description": {
2601
+ "alias": "description";
2602
+ "required": false;
2603
+ "isSignal": true;
2604
+ };
2515
2605
  "indent": {
2516
2606
  "alias": "indent";
2517
2607
  "required": false;
@@ -2549,8 +2639,23 @@ export declare class CheckboxComponent implements ControlValueAccessor, Validato
2549
2639
  };
2550
2640
  }, {
2551
2641
  "checked": "checkedChange";
2642
+ "values": "valuesChange";
2552
2643
  "invalidChange": "invalidChange";
2553
- }, never, ["*"], true, never>;
2644
+ }, ["_trailingContent"], ["*", "[checkbox-trailing]"], true, never>;
2645
+ }
2646
+ /**
2647
+ * Marks content that a single `ui-checkbox` shows at the END of its row, outside the clickable label (a badge, a price, a link):
2648
+ *
2649
+ * <ui-checkbox label="Priority handling" description="Ships first" [(ngModel)]="priority">
2650
+ * <span checkbox-trailing>$5.00</span>
2651
+ * </ui-checkbox>
2652
+ *
2653
+ * Import this directive in the host component (it is how the checkbox knows a trailing slot is in use); without it the checkbox
2654
+ * renders exactly as before. Clicking the trailing content does not toggle the box.
2655
+ */
2656
+ export declare class CheckboxTrailingDirective {
2657
+ static ɵfac: i0.ɵɵFactoryDeclaration<CheckboxTrailingDirective, never>;
2658
+ static ɵdir: i0.ɵɵDirectiveDeclaration<CheckboxTrailingDirective, "[checkbox-trailing]", never, {}, {}, never, never, true, never>;
2554
2659
  }
2555
2660
  /**
2556
2661
  * On/off switch for settings: a label and optional hint on the left, the switch on the right
@@ -2946,15 +3051,20 @@ export declare class RadioGroupComponent implements ControlValueAccessor, Valida
2946
3051
  readonly error: import("@angular/core").InputSignal<string>;
2947
3052
  /** Reveal the built-in error messages now (e.g. after a failed Save click), without waiting for blur. */
2948
3053
  readonly showErrors: import("@angular/core").InputSignal<boolean>;
2949
- readonly orientation: import("@angular/core").InputSignal<"horizontal" | "vertical">;
3054
+ readonly orientation: import("@angular/core").InputSignal<"vertical" | "horizontal">;
2950
3055
  /** Native `name` shared by the radios; a unique one is generated when omitted. */
2951
3056
  readonly name: import("@angular/core").InputSignal<string>;
3057
+ /** `<ng-template uiRadioOptionContent="value">` children: content shown under that option while it is selected. */
3058
+ private readonly _optionContent;
3059
+ protected readonly _nestedContent: import("@angular/core").Signal<Map<string, TemplateRef<unknown>>>;
2952
3060
  protected readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
2953
3061
  private readonly _cvaDisabled;
2954
3062
  protected readonly disabled: import("@angular/core").Signal<boolean>;
2955
3063
  private readonly _generatedName;
2956
3064
  protected get _name(): string;
2957
3065
  protected readonly _descId: string;
3066
+ /** Id of the content block under the selected option; that radio points at it with aria-controls. */
3067
+ protected readonly _nestedId: string;
2958
3068
  protected readonly _value: import("@angular/core").WritableSignal<string>;
2959
3069
  private readonly _reveal;
2960
3070
  private readonly _issue;
@@ -3030,7 +3140,7 @@ export declare class RadioGroupComponent implements ControlValueAccessor, Valida
3030
3140
  };
3031
3141
  }, {
3032
3142
  "invalidChange": "invalidChange";
3033
- }, never, never, true, never>;
3143
+ }, ["_optionContent"], never, true, never>;
3034
3144
  }
3035
3145
  /** One phone number the host found for sale. */
3036
3146
  export interface PhoneNumberOption {
@@ -3222,11 +3332,17 @@ export declare class PhoneNumberPickerComponent {
3222
3332
  }, never, never, true, never>;
3223
3333
  }
3224
3334
  export declare class ButtonComponent {
3225
- readonly variant: import("@angular/core").InputSignal<"primary" | "secondary" | "danger" | "warning" | "link" | "ghost" | "tab" | "icon" | "icon-danger">;
3226
- /** Renders an anchor to this route instead of a button (use with `variant="link"` for an inline text link). `['/settings']` or `'/settings'`. */
3335
+ /**
3336
+ * `ghost-start`: a ghost button for list / section toggles - a full-width row with its content aligned to the start, transparent
3337
+ * background, hover tint and the normal focus ring. Pair it with `ariaExpanded` / `ariaPressed`; the label may contain a heading element.
3338
+ */
3339
+ readonly variant: import("@angular/core").InputSignal<"primary" | "secondary" | "danger" | "warning" | "link" | "ghost" | "ghost-start" | "tab" | "icon" | "icon-danger">;
3340
+ /** Renders an anchor to this route instead of a button (use with `variant="link"` for an inline text link). `['/settings']` or `'/settings'`. While `disabled` or `loading` it renders a non-clickable `<span role="link" aria-disabled>` with no href (like `href`). */
3227
3341
  readonly routerLink: import("@angular/core").InputSignal<string | readonly unknown[] | null>;
3228
3342
  /** Query params of the `routerLink` (e.g. `{ section: 'deal-defaults' }`). */
3229
3343
  readonly queryParams: import("@angular/core").InputSignal<Record<string, unknown> | null>;
3344
+ /** Fragment (hash) of the `routerLink`, without the `#` (e.g. `'billing'` -> `/settings#billing`). */
3345
+ readonly fragment: import("@angular/core").InputSignal<string | null>;
3230
3346
  /**
3231
3347
  * Renders a plain `<a href>` instead of a button: for `mailto:`, `tel:`, `sms:`, `https://…` and relative URLs (use with
3232
3348
  * `variant="link"` for an inline text link). The browser handles the click, so middle-click, copy-link and open-in-new-tab work and
@@ -3272,6 +3388,11 @@ export declare class ButtonComponent {
3272
3388
  "required": false;
3273
3389
  "isSignal": true;
3274
3390
  };
3391
+ "fragment": {
3392
+ "alias": "fragment";
3393
+ "required": false;
3394
+ "isSignal": true;
3395
+ };
3275
3396
  "href": {
3276
3397
  "alias": "href";
3277
3398
  "required": false;
@@ -3761,6 +3882,12 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
3761
3882
  /** Accessible name for a field with no visible label (e.g. an inline cell or title input). */
3762
3883
  readonly ariaLabel: import("@angular/core").InputSignal<string>;
3763
3884
  readonly placeholder: import("@angular/core").InputSignal<string>;
3885
+ /**
3886
+ * An optional leading mark shown inside the field, left of the text (e.g. `prefix="$"` for a dollar amount). Hidden unless set; it is
3887
+ * decoration only (not part of the value, not read by screen readers), so say the unit in the label too when it matters ("Amount (USD)").
3888
+ * Meant for a short mark of 1-3 characters.
3889
+ */
3890
+ readonly prefix: import("@angular/core").InputSignal<string>;
3764
3891
  readonly type: import("@angular/core").InputSignal<"number" | "text" | "email" | "tel" | "password" | "url">;
3765
3892
  readonly maxlength: import("@angular/core").InputSignal<number | undefined>;
3766
3893
  readonly required: import("@angular/core").InputSignal<boolean>;
@@ -3793,17 +3920,31 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
3793
3920
  * (otherwise a dev-mode warning is logged once and string behaviour is used).
3794
3921
  */
3795
3922
  readonly valueType: import("@angular/core").InputSignal<"string" | "number">;
3923
+ /**
3924
+ * Optional text filter/mask applied to every typed or pasted value: `(raw) => cleaned`, e.g. `v => v.replace(/\D/g, '').slice(0, 9)`.
3925
+ * The result is what the box shows and what the model gets (the caret moves to the end when the text was changed). Unset (default)
3926
+ * = the typed text is used as is. Not applied to values the host writes (`writeValue`), and for `type="tel"` / `phoneFormat` the
3927
+ * phone formatting runs first and the formatter then sees its result.
3928
+ */
3929
+ readonly formatter: import("@angular/core").InputSignal<((raw: string) => string) | undefined>;
3796
3930
  /** Reveal the built-in error messages now (e.g. after a failed Save click), without waiting for blur. */
3797
3931
  readonly showErrors: import("@angular/core").InputSignal<boolean>;
3798
3932
  readonly focused: import("@angular/core").OutputEmitterRef<void>;
3799
3933
  readonly blurred: import("@angular/core").OutputEmitterRef<void>;
3800
3934
  /** Emits whenever the field becomes invalid / valid. */
3801
3935
  readonly invalidChange: import("@angular/core").OutputEmitterRef<boolean>;
3802
- protected readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
3936
+ /**
3937
+ * The `[disabled]` input. Public on purpose: a `protected` input makes `[disabled]="x"` in a host template fail strict template
3938
+ * type-checking (TS2445: Angular checks the field the alias points at). The field is disabled when this OR the form control
3939
+ * (`setDisabledState`, e.g. `FormControl.disable()`) says so.
3940
+ */
3941
+ readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
3803
3942
  private readonly _cvaDisabled;
3804
3943
  protected readonly disabled: import("@angular/core").Signal<boolean>;
3805
3944
  protected readonly _value: import("@angular/core").WritableSignal<string>;
3806
3945
  private readonly _reveal;
3946
+ /** Left padding that makes room for the prefix (its width in `ch` plus the field's own 12px and a 6px gap); none without a prefix. */
3947
+ protected readonly _prefixPadding: import("@angular/core").Signal<string | null>;
3807
3948
  /** True when the control value is a number: `valueType="number"` on a `type="number"` field. */
3808
3949
  private readonly _numeric;
3809
3950
  /** The native `step` attribute: only for `type="number"` and only for a finite number above 0; otherwise none (the browser's step of 1). */
@@ -3857,6 +3998,11 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
3857
3998
  "required": false;
3858
3999
  "isSignal": true;
3859
4000
  };
4001
+ "prefix": {
4002
+ "alias": "prefix";
4003
+ "required": false;
4004
+ "isSignal": true;
4005
+ };
3860
4006
  "type": {
3861
4007
  "alias": "type";
3862
4008
  "required": false;
@@ -3927,6 +4073,11 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
3927
4073
  "required": false;
3928
4074
  "isSignal": true;
3929
4075
  };
4076
+ "formatter": {
4077
+ "alias": "formatter";
4078
+ "required": false;
4079
+ "isSignal": true;
4080
+ };
3930
4081
  "showErrors": {
3931
4082
  "alias": "showErrors";
3932
4083
  "required": false;
@@ -4162,6 +4313,13 @@ export declare class FileInputComponent implements ControlValueAccessor, Validat
4162
4313
  readonly showField: import("@angular/core").InputSignal<boolean>;
4163
4314
  /** Reveal the built-in "required" message now (e.g. after a failed Save click). */
4164
4315
  readonly showErrors: import("@angular/core").InputSignal<boolean>;
4316
+ /**
4317
+ * Also report every refused file (wrong type, too big, too small, empty) with a `ToastService` error toast that names the file and
4318
+ * the reason, e.g. `"scan.exe" was not added. Only PDF files are allowed.` Meant for the picker-only mode (`[showField]="false"`),
4319
+ * where no field is visible to show the message; it works with a visible field too. Several refused files make ONE toast listing each.
4320
+ * Default `false`: nothing is toasted (the field message and `(fileRejected)` are unchanged). Needs a `ui-toast` outlet like any toast.
4321
+ */
4322
+ readonly toastOnReject: import("@angular/core").InputSignal<boolean>;
4165
4323
  /** Show a Remove button next to the chosen file. */
4166
4324
  readonly clearable: import("@angular/core").InputSignal<boolean>;
4167
4325
  readonly removeLabel: import("@angular/core").InputSignal<string>;
@@ -4207,6 +4365,7 @@ export declare class FileInputComponent implements ControlValueAccessor, Validat
4207
4365
  private readonly fileEl;
4208
4366
  protected readonly _dragging: import("@angular/core").WritableSignal<boolean>;
4209
4367
  /** Message of the last refused file ('' when the last pick was fine); shown in every mode. */
4368
+ private readonly _toast;
4210
4369
  private readonly _rejection;
4211
4370
  private readonly _reveal;
4212
4371
  private readonly _issue;
@@ -4304,6 +4463,11 @@ export declare class FileInputComponent implements ControlValueAccessor, Validat
4304
4463
  "required": false;
4305
4464
  "isSignal": true;
4306
4465
  };
4466
+ "toastOnReject": {
4467
+ "alias": "toastOnReject";
4468
+ "required": false;
4469
+ "isSignal": true;
4470
+ };
4307
4471
  "clearable": {
4308
4472
  "alias": "clearable";
4309
4473
  "required": false;
@@ -4400,7 +4564,8 @@ export declare class DateInputComponent implements ControlValueAccessor, Validat
4400
4564
  readonly error: import("@angular/core").InputSignal<string>;
4401
4565
  /** Reveal the built-in error messages now (e.g. after a failed Save click), without waiting for blur. */
4402
4566
  readonly showErrors: import("@angular/core").InputSignal<boolean>;
4403
- protected readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
4567
+ /** The `[disabled]` input. Public so `[disabled]="x"` in a host template type-checks (a protected alias target fails with TS2445); disabled when this OR the form control says so. */
4568
+ readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
4404
4569
  private readonly _cvaDisabled;
4405
4570
  protected readonly disabled: import("@angular/core").Signal<boolean>;
4406
4571
  protected readonly _value: import("@angular/core").WritableSignal<string>;
@@ -5183,6 +5348,24 @@ export declare class FormRowComponent {
5183
5348
  };
5184
5349
  }, {}, never, ["*"], true, never>;
5185
5350
  }
5351
+ /**
5352
+ * Lets a direct child of `ui-form-row` span several columns: `<ui-text-input uiColSpan="2" .../>` (2 or 3 columns) or
5353
+ * `uiColSpan="all"` (every column). It only adds the class `ui-span-2` / `ui-span-3` / `ui-span-all`, which `ui-form-row` styles, so a
5354
+ * plain `class="ui-span-2"` on the child works too without importing this directive. On a phone (<= 480px) the row is one column and the
5355
+ * child simply takes the full width. Keep a numeric span within the row's `cols` (use `all` for the whole row).
5356
+ */
5357
+ export declare class FormColSpanDirective {
5358
+ readonly uiColSpan: import("@angular/core").InputSignal<"" | "2" | "3" | 2 | 3 | "all">;
5359
+ protected readonly _class: import("@angular/core").Signal<string>;
5360
+ static ɵfac: i0.ɵɵFactoryDeclaration<FormColSpanDirective, never>;
5361
+ static ɵdir: i0.ɵɵDirectiveDeclaration<FormColSpanDirective, "[uiColSpan]", never, {
5362
+ "uiColSpan": {
5363
+ "alias": "uiColSpan";
5364
+ "required": false;
5365
+ "isSignal": true;
5366
+ };
5367
+ }, {}, never, never, true, never>;
5368
+ }
5186
5369
  /**
5187
5370
  * Fixed-layout list item with an optional leading radio/checkbox, a title + badge,
5188
5371
  * and a secondary detail row rendered from a string array. All layout is handled
@@ -5733,6 +5916,16 @@ export interface PanelInfoItem {
5733
5916
  }>;
5734
5917
  /** Router link for the value. */
5735
5918
  link?: string;
5919
+ /**
5920
+ * A real `<a href>` for the value (the visible `value` is the link text). Only `mailto:`, `tel:`, `http:` and `https:` are
5921
+ * allowed; any other scheme (`javascript:`, `data:` ...) renders the value as plain text. `http(s)` links open in a new tab with
5922
+ * `rel="noopener noreferrer"`. Wins over `email` / `phone` / `link`.
5923
+ */
5924
+ href?: string;
5925
+ /** Shortcut: the value becomes a `mailto:` link to this address (the value defaults to the address). */
5926
+ email?: string;
5927
+ /** Shortcut: the value becomes a `tel:` link to this number (digits and a leading + are kept; the value defaults to the number as written). */
5928
+ phone?: string;
5736
5929
  /** Show the value with an "open" icon instead of blue link styling. */
5737
5930
  linkIcon?: boolean;
5738
5931
  /** Renders a small edit (pencil) icon button after the value. */
@@ -5766,6 +5959,14 @@ export declare class PanelInfoListComponent {
5766
5959
  readonly sections: import("@angular/core").InputSignal<PanelInfoSection[]>;
5767
5960
  readonly showEmptyState: import("@angular/core").InputSignal<boolean>;
5768
5961
  readonly displaySections: import("@angular/core").Signal<PanelInfoSection[]>;
5962
+ /**
5963
+ * The safe href of an item, or null: `href` first, else `mailto:`/`tel:` built from `email`/`phone`. Only mailto, tel, http and https
5964
+ * are allowed (the scheme is checked after removing control characters and spaces, like browsers do).
5965
+ */
5966
+ hrefOf(item: PanelInfoItem): string | null;
5967
+ isWeb(href: string): boolean;
5968
+ /** Link text: the value, else the email / phone as written. */
5969
+ textOf(item: PanelInfoItem): string;
5769
5970
  visibleItems(section: PanelInfoSection): PanelInfoItem[];
5770
5971
  static ɵfac: i0.ɵɵFactoryDeclaration<PanelInfoListComponent, never>;
5771
5972
  static ɵcmp: i0.ɵɵComponentDeclaration<PanelInfoListComponent, "ui-panel-info-list", never, {
@@ -6098,9 +6299,9 @@ export declare class AppShellComponent implements OnInit, OnDestroy {
6098
6299
  "logoutClick": "logoutClick";
6099
6300
  }, never, ["[shell-brand]", "[shell-header-end]", "[shell-banners]", "*"], true, never>;
6100
6301
  }
6101
- export type AlertVariant = 'info' | 'success' | 'warning' | 'danger';
6302
+ export type AlertVariant = 'info' | 'success' | 'warning' | 'danger' | 'neutral';
6102
6303
  /**
6103
- * Inline status message (info / success / warning / danger) with an optional title,
6304
+ * Inline status message (info / success / warning / danger / neutral gray) with an optional title,
6104
6305
  * optional dismiss button, and projected body content (text, links, a retry ui-button…).
6105
6306
  * `quiet` drops the live-region role (no announcement) and `compact` tightens it for list rows — both off by default.
6106
6307
  *
@@ -6155,19 +6356,10 @@ export declare class AlertComponent {
6155
6356
  "dismissed": "dismissed";
6156
6357
  }, never, ["*"], true, never>;
6157
6358
  }
6158
- /**
6159
- * Small muted helper text shown under a form or panel section.
6160
- *
6161
- * <ui-hint>This does not affect the scheduled send date.</ui-hint>
6162
- */
6163
- export declare class HintComponent {
6164
- static ɵfac: i0.ɵɵFactoryDeclaration<HintComponent, never>;
6165
- static ɵcmp: i0.ɵɵComponentDeclaration<HintComponent, "ui-hint", never, {}, {}, never, ["*"], true, never>;
6166
- }
6167
6359
  /** The SVG path (24×24 stroke icon) for an icon key, or undefined when the key is unknown. */
6168
6360
  export declare function iconPath(name: string): string | undefined;
6169
6361
  /** Keys with an icon of their own (the data-table action keys are accepted too — see `builtInActionIcon`). */
6170
- export type IconName = 'add' | 'close' | 'check' | 'upload' | 'image' | 'chevron-up' | 'chevron-down' | 'arrow-left' | 'bell' | 'print' | 'view' | 'edit' | 'delete' | 'download' | 'duplicate' | 'archive' | 'restore' | 'share' | 'email' | 'message' | 'call';
6362
+ export type IconName = 'add' | 'close' | 'check' | 'upload' | 'image' | 'chevron-up' | 'chevron-down' | 'arrow-left' | 'bell' | 'print' | 'lock' | 'arrow-up' | 'arrow-down' | 'arrow-right' | 'document' | 'grip' | 'card' | 'bank' | 'view' | 'edit' | 'delete' | 'download' | 'duplicate' | 'archive' | 'restore' | 'share' | 'email' | 'message' | 'call';
6171
6363
  /**
6172
6364
  * A clickable icon. The host passes a key (`name="delete"`) and the library draws that icon; clicking it emits
6173
6365
  * `iconClick`, and the host does the actual work (delete the row, open a panel, …).
@@ -6251,6 +6443,71 @@ export declare class IconComponent {
6251
6443
  "iconClick": "iconClick";
6252
6444
  }, never, never, true, never>;
6253
6445
  }
6446
+ export type TimelineTone = 'default' | 'success' | 'warning' | 'danger';
6447
+ export interface TimelineItem {
6448
+ /** Stable id used for `track`; the index is used when absent. */
6449
+ id?: string;
6450
+ title: string;
6451
+ description?: string;
6452
+ /** Pre-formatted time text shown to the reader, e.g. "Oct 20, 2026, 3:15 PM". */
6453
+ time?: string;
6454
+ /** ISO date / date-time for the `datetime` attribute of the `<time>` element (machine-readable). */
6455
+ dateTime?: string;
6456
+ badge?: {
6457
+ label: string;
6458
+ variant: BadgeVariant;
6459
+ };
6460
+ /** Icon drawn inside the dot (static, decorative). Unknown names draw nothing. */
6461
+ icon?: IconName | (string & {});
6462
+ /** Colour of the dot / icon. Default `default`. */
6463
+ tone?: TimelineTone;
6464
+ }
6465
+ /**
6466
+ * Vertical activity feed: an ordered list of events joined by a line, each with a dot (or icon), title, optional badge,
6467
+ * description and time.
6468
+ *
6469
+ * <ui-timeline ariaLabel="Case activity" emptyMessage="No activity yet." [items]="[
6470
+ * { id: 'a', title: 'Case opened', time: 'Oct 20, 3:15 PM', dateTime: '2026-10-20T15:15:00Z', badge: { label: 'Open', variant: 'green' } },
6471
+ * { id: 'b', title: 'Letter sent', description: 'Mailed to the owner.', tone: 'success', icon: 'email' },
6472
+ * ]" />
6473
+ *
6474
+ * Semantics: `<ol>` / `<li>`; the line and dots are decorative (aria-hidden). `time` is the visible text; `dateTime` goes into
6475
+ * `<time datetime>`. With no items, `emptyMessage` (if set) is shown as a hint, otherwise nothing is rendered.
6476
+ */
6477
+ export declare class TimelineComponent {
6478
+ readonly items: import("@angular/core").InputSignal<TimelineItem[]>;
6479
+ /** Accessible name of the list (e.g. "Case activity"). */
6480
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
6481
+ /** Shown (as a hint) when there are no items. Empty = render nothing. */
6482
+ readonly emptyMessage: import("@angular/core").InputSignal<string>;
6483
+ static ɵfac: i0.ɵɵFactoryDeclaration<TimelineComponent, never>;
6484
+ static ɵcmp: i0.ɵɵComponentDeclaration<TimelineComponent, "ui-timeline", never, {
6485
+ "items": {
6486
+ "alias": "items";
6487
+ "required": false;
6488
+ "isSignal": true;
6489
+ };
6490
+ "ariaLabel": {
6491
+ "alias": "ariaLabel";
6492
+ "required": false;
6493
+ "isSignal": true;
6494
+ };
6495
+ "emptyMessage": {
6496
+ "alias": "emptyMessage";
6497
+ "required": false;
6498
+ "isSignal": true;
6499
+ };
6500
+ }, {}, never, never, true, never>;
6501
+ }
6502
+ /**
6503
+ * Small muted helper text shown under a form or panel section.
6504
+ *
6505
+ * <ui-hint>This does not affect the scheduled send date.</ui-hint>
6506
+ */
6507
+ export declare class HintComponent {
6508
+ static ɵfac: i0.ɵɵFactoryDeclaration<HintComponent, never>;
6509
+ static ɵcmp: i0.ɵɵComponentDeclaration<HintComponent, "ui-hint", never, {}, {}, never, ["*"], true, never>;
6510
+ }
6254
6511
  export type ImagePreviewShape = 'circle' | 'rounded';
6255
6512
  export type ImagePreviewSize = 'sm' | 'md' | 'lg';
6256
6513
  export type ImagePreviewPlaceholder = 'person' | 'image';
@@ -6741,6 +6998,8 @@ export declare class RadioComponent {
6741
6998
  readonly invalid: import("@angular/core").InputSignal<boolean>;
6742
6999
  /** Id(s) of the element(s) describing the group (hint / error). */
6743
7000
  readonly describedBy: import("@angular/core").InputSignal<string>;
7001
+ /** Id of an element this radio reveals while selected (`aria-controls`); no attribute when empty. */
7002
+ readonly controls: import("@angular/core").InputSignal<string>;
6744
7003
  /** Public so a host template can bind `[disabled]` (a protected input fails strict template type-checking). */
6745
7004
  readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
6746
7005
  protected readonly disabled: import("@angular/core").InputSignal<boolean>;
@@ -6795,6 +7054,11 @@ export declare class RadioComponent {
6795
7054
  "required": false;
6796
7055
  "isSignal": true;
6797
7056
  };
7057
+ "controls": {
7058
+ "alias": "controls";
7059
+ "required": false;
7060
+ "isSignal": true;
7061
+ };
6798
7062
  "_disabledInput": {
6799
7063
  "alias": "disabled";
6800
7064
  "required": false;
@@ -6804,6 +7068,32 @@ export declare class RadioComponent {
6804
7068
  "selected": "selected";
6805
7069
  }, never, ["*"], true, never>;
6806
7070
  }
7071
+ /**
7072
+ * Content shown directly under ONE option of a `ui-radio-group`, only while that option is selected (e.g. an address form under
7073
+ * "Ship to an alternate address"). Put an `<ng-template>` inside the group and name the option's value:
7074
+ *
7075
+ * <ui-radio-group label="Delivery" [options]="opts" [(ngModel)]="method">
7076
+ * <ng-template uiRadioOptionContent="SHIP">
7077
+ * <ui-text-input label="Street" ... />
7078
+ * </ng-template>
7079
+ * </ui-radio-group>
7080
+ *
7081
+ * Groups without such a template render exactly as before. The content is indented under the option's label; in a horizontal group it
7082
+ * takes a full row below the options. It lives inside the group's fieldset, so moving focus into it does not count as leaving the group.
7083
+ */
7084
+ export declare class RadioOptionContentDirective {
7085
+ /** The `value` of the option this content belongs to. */
7086
+ readonly value: import("@angular/core").InputSignal<string>;
7087
+ readonly template: TemplateRef<unknown>;
7088
+ static ɵfac: i0.ɵɵFactoryDeclaration<RadioOptionContentDirective, never>;
7089
+ static ɵdir: i0.ɵɵDirectiveDeclaration<RadioOptionContentDirective, "ng-template[uiRadioOptionContent]", never, {
7090
+ "value": {
7091
+ "alias": "uiRadioOptionContent";
7092
+ "required": true;
7093
+ "isSignal": true;
7094
+ };
7095
+ }, {}, never, never, true, never>;
7096
+ }
6807
7097
  /** One row of a `ui-radio-matrix`: `value` is the key in the model, `label` the row header. */
6808
7098
  export interface RadioMatrixRow {
6809
7099
  value: string;
@@ -6931,6 +7221,283 @@ export declare class RadioMatrixComponent implements ControlValueAccessor, Valid
6931
7221
  "invalidChange": "invalidChange";
6932
7222
  }, never, never, true, never>;
6933
7223
  }
7224
+ /**
7225
+ * A pad to draw a signature (or initials) on: a ControlValueAccessor whose value is a PNG data URL (`null` = empty).
7226
+ *
7227
+ * <ui-signature-pad label="Your signature" [(ngModel)]="signature" />
7228
+ * <ui-signature-pad ariaLabel="Initials" [outputWidth]="200" [outputHeight]="60" (signatureChange)="onSigned($event)" />
7229
+ *
7230
+ * Drawing works with a mouse, a finger or a pen (pointer events; the pad blocks touch scrolling while you draw) and with the keyboard:
7231
+ * focus the pad, move the cursor with the arrow keys (Shift = bigger steps), hold Space to draw, Escape hides the cursor (it does not
7232
+ * leave the dialog the pad may sit in until the cursor is hidden). When a stroke ends the drawing is cropped to its content (4px margin),
7233
+ * scaled to fit `outputWidth` x `outputHeight` (left-aligned, vertically centered) and emitted, so every signature has the same visual
7234
+ * weight. Clear empties the pad. `disabled` (input or form control) blocks drawing.
7235
+ *
7236
+ * The pad is shown at the container's width and keeps the bitmap's aspect ratio (`width` : `height`), so ink is never stretched and the saved PNG
7237
+ * looks like what was drawn. Changing `width` / `height` after drawing repaints the current signature (scaled to fit) instead of losing it.
7238
+ * Screen readers get the keyboard instructions as a description of the pad and a polite "Signature captured" / "Signature cleared" announcement.
7239
+ *
7240
+ * Public methods: `clear()`, `isEmpty()` and `toDataUrl()` (the current normalized signature, or `null` when empty).
7241
+ */
7242
+ export declare class SignaturePadComponent implements ControlValueAccessor {
7243
+ readonly label: import("@angular/core").InputSignal<string>;
7244
+ /** Accessible name when there is no visible label. A default describing the keyboard controls is used when neither is set. */
7245
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
7246
+ readonly hint: import("@angular/core").InputSignal<string>;
7247
+ readonly error: import("@angular/core").InputSignal<string>;
7248
+ /** Bitmap size of the drawing surface in pixels. The pad is displayed at the container's width with this same aspect ratio, so strokes keep their proportions. */
7249
+ readonly width: import("@angular/core").InputSignal<number>;
7250
+ readonly height: import("@angular/core").InputSignal<number>;
7251
+ /** Size of the emitted PNG: the drawing is cropped to its content and scaled to fit this box. */
7252
+ readonly outputWidth: import("@angular/core").InputSignal<number>;
7253
+ readonly outputHeight: import("@angular/core").InputSignal<number>;
7254
+ readonly penColor: import("@angular/core").InputSignal<string>;
7255
+ readonly penWidth: import("@angular/core").InputSignal<number>;
7256
+ /** Show the built-in Clear button under the pad. */
7257
+ readonly showClear: import("@angular/core").InputSignal<boolean>;
7258
+ readonly clearLabel: import("@angular/core").InputSignal<string>;
7259
+ readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
7260
+ /** Emits the normalized PNG data URL when a stroke ends, and `null` when the pad is cleared. */
7261
+ readonly signatureChange: import("@angular/core").OutputEmitterRef<string | null>;
7262
+ private readonly _canvas;
7263
+ private readonly _cvaDisabled;
7264
+ protected readonly disabled: import("@angular/core").Signal<boolean>;
7265
+ protected readonly _empty: import("@angular/core").WritableSignal<boolean>;
7266
+ protected readonly _cursorVisible: import("@angular/core").WritableSignal<boolean>;
7267
+ protected readonly _cursorX: import("@angular/core").WritableSignal<number>;
7268
+ protected readonly _cursorY: import("@angular/core").WritableSignal<number>;
7269
+ protected readonly _keyboardDrawing: import("@angular/core").WritableSignal<boolean>;
7270
+ protected readonly _announcement: import("@angular/core").WritableSignal<string>;
7271
+ protected readonly _keyboardHelp = "Use the arrow keys to move the cursor, hold Space to draw, press Escape to hide the cursor.";
7272
+ private readonly _injector;
7273
+ private readonly _id;
7274
+ protected readonly _labelId: string;
7275
+ protected readonly _descId: string;
7276
+ protected readonly _helpId: string;
7277
+ /** The `ariaLabel`; with neither it nor a visible `label`, a default name (the canvas always has one). The keyboard instructions are a separate description. */
7278
+ protected readonly _accessibleName: import("@angular/core").Signal<string | null>;
7279
+ /** The error / hint (when shown) plus the always-present keyboard instructions, so they are announced whatever names the canvas. */
7280
+ protected readonly _describedBy: import("@angular/core").Signal<string>;
7281
+ private _ctx;
7282
+ private _pointerId;
7283
+ private _dirty;
7284
+ /** A value was written before the canvas existed: the setup effect paints it. */
7285
+ private _pendingImage;
7286
+ private _value;
7287
+ /** A written / repainted image is still decoding: the bitmap does not hold the signature yet, `_value` does. */
7288
+ private _loading;
7289
+ /** `width`x`height` the bitmap was last set up for; a change wipes the canvas, so the signature is repainted from `_value`. */
7290
+ private _sizeKey;
7291
+ private _onChange;
7292
+ private _onTouched;
7293
+ constructor();
7294
+ isEmpty(): boolean;
7295
+ /** The current signature as a normalized PNG data URL, or `null` when nothing is drawn. */
7296
+ toDataUrl(): string | null;
7297
+ /** Empties the pad and tells the form (value `null`). */
7298
+ clear(): void;
7299
+ writeValue(value: string | null): void;
7300
+ /** Draws a written value scaled to fit, left-aligned and vertically centered (ignored when the value was replaced while it loaded). */
7301
+ private _paint;
7302
+ /**
7303
+ * Assigning the canvas `width` / `height` wipes the bitmap while `_value` and `_empty` still describe a signature: once the new size is
7304
+ * rendered, paint the current signature (the last committed / written PNG, scaled to fit) again so state and bitmap agree.
7305
+ */
7306
+ private _repaintAfterResize;
7307
+ registerOnChange(fn: (value: string | null) => void): void;
7308
+ registerOnTouched(fn: () => void): void;
7309
+ setDisabledState(disabled: boolean): void;
7310
+ protected onPointerDown(event: PointerEvent): void;
7311
+ protected onPointerMove(event: PointerEvent): void;
7312
+ protected onPointerEnd(event: PointerEvent): void;
7313
+ protected onKeyDown(event: KeyboardEvent): void;
7314
+ protected onKeyUp(event: KeyboardEvent): void;
7315
+ protected onBlur(): void;
7316
+ private _stopKeyboardStroke;
7317
+ /** A stroke ended: normalize the drawing, publish it to the form and the output. */
7318
+ private _commit;
7319
+ private _setUpContext;
7320
+ /** The drawing context, created on first use (a form can write its value before the setup effect has run). */
7321
+ private _contextOf;
7322
+ /**
7323
+ * Pen settings go on the context at the start of every stroke as well as in the setup effect: assigning the canvas `width` / `height`
7324
+ * (the `[width]` / `[height]` bindings, which run after the effect on the first render and on every size change) resets the context state.
7325
+ */
7326
+ private _applyPen;
7327
+ private _clearBitmap;
7328
+ /** Display coordinates -> bitmap coordinates (the pad is scaled by CSS). */
7329
+ private _pointOf;
7330
+ /** Crop the drawing to its content (4px margin) and scale it into `outputWidth` x `outputHeight`, left-aligned and vertically centered. */
7331
+ private _normalize;
7332
+ static ɵfac: i0.ɵɵFactoryDeclaration<SignaturePadComponent, never>;
7333
+ static ɵcmp: i0.ɵɵComponentDeclaration<SignaturePadComponent, "ui-signature-pad", never, {
7334
+ "label": {
7335
+ "alias": "label";
7336
+ "required": false;
7337
+ "isSignal": true;
7338
+ };
7339
+ "ariaLabel": {
7340
+ "alias": "ariaLabel";
7341
+ "required": false;
7342
+ "isSignal": true;
7343
+ };
7344
+ "hint": {
7345
+ "alias": "hint";
7346
+ "required": false;
7347
+ "isSignal": true;
7348
+ };
7349
+ "error": {
7350
+ "alias": "error";
7351
+ "required": false;
7352
+ "isSignal": true;
7353
+ };
7354
+ "width": {
7355
+ "alias": "width";
7356
+ "required": false;
7357
+ "isSignal": true;
7358
+ };
7359
+ "height": {
7360
+ "alias": "height";
7361
+ "required": false;
7362
+ "isSignal": true;
7363
+ };
7364
+ "outputWidth": {
7365
+ "alias": "outputWidth";
7366
+ "required": false;
7367
+ "isSignal": true;
7368
+ };
7369
+ "outputHeight": {
7370
+ "alias": "outputHeight";
7371
+ "required": false;
7372
+ "isSignal": true;
7373
+ };
7374
+ "penColor": {
7375
+ "alias": "penColor";
7376
+ "required": false;
7377
+ "isSignal": true;
7378
+ };
7379
+ "penWidth": {
7380
+ "alias": "penWidth";
7381
+ "required": false;
7382
+ "isSignal": true;
7383
+ };
7384
+ "showClear": {
7385
+ "alias": "showClear";
7386
+ "required": false;
7387
+ "isSignal": true;
7388
+ };
7389
+ "clearLabel": {
7390
+ "alias": "clearLabel";
7391
+ "required": false;
7392
+ "isSignal": true;
7393
+ };
7394
+ "_disabledInput": {
7395
+ "alias": "disabled";
7396
+ "required": false;
7397
+ "isSignal": true;
7398
+ };
7399
+ }, {
7400
+ "signatureChange": "signatureChange";
7401
+ }, never, never, true, never>;
7402
+ }
7403
+ /**
7404
+ * A "sign here" spot placed over a rendered PDF page, at the coordinates the document gives (pixels from the page's top-left corner).
7405
+ * Put it inside a `position: relative` element that holds the page, one per field:
7406
+ *
7407
+ * <div style="position: relative; width: 612px; height: 792px">
7408
+ * <canvas ...></canvas>
7409
+ * <ui-pdf-hotspot [x]="f.x" [y]="f.y" [width]="f.width" [height]="f.height"
7410
+ * [state]="ready ? 'ready' : 'blocked'" label="Sign Here" blockedLabel="Add signature above"
7411
+ * ariaLabel="Click to sign here" [image]="f.signatureImage" (activate)="apply(f)" />
7412
+ * </div>
7413
+ *
7414
+ * `state="ready"` is a clickable button (`label`), `"blocked"` the same button disabled (`blockedLabel`, e.g. "create your signature first"),
7415
+ * and `"signed"` shows the applied `image` (a signature data URL) contained inside the box instead (signed without an image is a disabled button showing `label`). The box size comes from the document
7416
+ * so the text is scaled to it (height x 0.25, clamped to 7-11px); on touch devices the tap area is extended to at least 44px tall.
7417
+ */
7418
+ export declare class PdfHotspotComponent {
7419
+ /** Position and size in pixels, from the page's top-left corner. */
7420
+ readonly x: import("@angular/core").InputSignal<number>;
7421
+ readonly y: import("@angular/core").InputSignal<number>;
7422
+ readonly width: import("@angular/core").InputSignal<number>;
7423
+ readonly height: import("@angular/core").InputSignal<number>;
7424
+ /** `ready`: clickable; `blocked`: disabled (a prerequisite is missing); `signed`: shows `image`. */
7425
+ readonly state: import("@angular/core").InputSignal<"ready" | "blocked" | "signed">;
7426
+ /** `warning` gives the ready state an amber look (e.g. for initials), default is blue. */
7427
+ readonly tone: import("@angular/core").InputSignal<"primary" | "warning">;
7428
+ /** Text of the ready button (e.g. "Sign Here"). */
7429
+ readonly label: import("@angular/core").InputSignal<string>;
7430
+ /** Text of the blocked button (e.g. "Add signature above"). */
7431
+ readonly blockedLabel: import("@angular/core").InputSignal<string>;
7432
+ /** Accessible name of the button (its text is used when empty). */
7433
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
7434
+ /** The applied signature (data URL), shown when `state` is `signed`. */
7435
+ readonly image: import("@angular/core").InputSignal<string | null>;
7436
+ readonly imageAlt: import("@angular/core").InputSignal<string>;
7437
+ /** The ready button was clicked. */
7438
+ readonly activate: import("@angular/core").OutputEmitterRef<void>;
7439
+ protected readonly fontSize: import("@angular/core").Signal<number>;
7440
+ static ɵfac: i0.ɵɵFactoryDeclaration<PdfHotspotComponent, never>;
7441
+ static ɵcmp: i0.ɵɵComponentDeclaration<PdfHotspotComponent, "ui-pdf-hotspot", never, {
7442
+ "x": {
7443
+ "alias": "x";
7444
+ "required": false;
7445
+ "isSignal": true;
7446
+ };
7447
+ "y": {
7448
+ "alias": "y";
7449
+ "required": false;
7450
+ "isSignal": true;
7451
+ };
7452
+ "width": {
7453
+ "alias": "width";
7454
+ "required": false;
7455
+ "isSignal": true;
7456
+ };
7457
+ "height": {
7458
+ "alias": "height";
7459
+ "required": false;
7460
+ "isSignal": true;
7461
+ };
7462
+ "state": {
7463
+ "alias": "state";
7464
+ "required": false;
7465
+ "isSignal": true;
7466
+ };
7467
+ "tone": {
7468
+ "alias": "tone";
7469
+ "required": false;
7470
+ "isSignal": true;
7471
+ };
7472
+ "label": {
7473
+ "alias": "label";
7474
+ "required": false;
7475
+ "isSignal": true;
7476
+ };
7477
+ "blockedLabel": {
7478
+ "alias": "blockedLabel";
7479
+ "required": false;
7480
+ "isSignal": true;
7481
+ };
7482
+ "ariaLabel": {
7483
+ "alias": "ariaLabel";
7484
+ "required": false;
7485
+ "isSignal": true;
7486
+ };
7487
+ "image": {
7488
+ "alias": "image";
7489
+ "required": false;
7490
+ "isSignal": true;
7491
+ };
7492
+ "imageAlt": {
7493
+ "alias": "imageAlt";
7494
+ "required": false;
7495
+ "isSignal": true;
7496
+ };
7497
+ }, {
7498
+ "activate": "activate";
7499
+ }, never, never, true, never>;
7500
+ }
6934
7501
  /**
6935
7502
  * Card for detail pages: an optional header and a body, both filled by the page that uses it.
6936
7503
  *
@@ -6948,7 +7515,7 @@ export declare class RadioMatrixComponent implements ControlValueAccessor, Valid
6948
7515
  * - `collapsible` (default true): a chevron toggle and a clickable header; `[(expanded)]` is two-way.
6949
7516
  * Without a header, or with `collapsible` false, the body is always open.
6950
7517
  *
6951
- * The title is always shown in capitals; the subtitle keeps the case you give it. The body is the default content slot. A collapsed body is removed from the tab order and from assistive tech.
7518
+ * The title is shown in capitals unless `[uppercaseTitle]="false"` (then it shows as written, e.g. "Case IDs"); the casing is CSS only, so the accessible name and heading text are always the text you gave; the subtitle keeps the case you give it. The body is the default content slot. A collapsed body is removed from the tab order and from assistive tech.
6952
7519
  *
6953
7520
  * <ui-detail-card title="COMMUNICATIONS" subtitle="All calls, texts, and emails"> ...body... </ui-detail-card>
6954
7521
  * <ui-detail-card title="CONTACT INFO" [showEdit]="true" (editClick)="openEdit()"> ... </ui-detail-card>
@@ -6963,6 +7530,8 @@ export declare class RadioMatrixComponent implements ControlValueAccessor, Valid
6963
7530
  export declare class DetailCardComponent {
6964
7531
  /** Bold uppercase title. Empty = no title text. */
6965
7532
  readonly title: import("@angular/core").InputSignal<string>;
7533
+ /** true (default) = the title is displayed in capitals (CSS only); false = shown as written. The text, aria-label and heading name are never changed. */
7534
+ readonly uppercaseTitle: import("@angular/core").InputSignal<boolean>;
6966
7535
  /** 1-6 makes the title a real heading for screen readers (role=heading, aria-level); null keeps it plain text. */
6967
7536
  readonly headingLevel: import("@angular/core").InputSignal<1 | 2 | 3 | 4 | 5 | 6 | null>;
6968
7537
  /** Optional id for the title text; the card is then labelled by it. Without it the title is the card's aria-label. */
@@ -6999,6 +7568,11 @@ export declare class DetailCardComponent {
6999
7568
  "required": false;
7000
7569
  "isSignal": true;
7001
7570
  };
7571
+ "uppercaseTitle": {
7572
+ "alias": "uppercaseTitle";
7573
+ "required": false;
7574
+ "isSignal": true;
7575
+ };
7002
7576
  "headingLevel": {
7003
7577
  "alias": "headingLevel";
7004
7578
  "required": false;