@forgeroute/ui 0.4.56 → 0.4.58

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.
@@ -1049,6 +1049,11 @@ export declare function isoKey(p: {
1049
1049
  export declare function parseTime(value: string | null | undefined): number | null;
1050
1050
  /** "9:00 AM" / "12:30 PM" from an `HH:mm` value (returned unchanged when it cannot be parsed; '' for null/undefined/non-strings). */
1051
1051
  export declare function formatTime(value: string | null | undefined): string;
1052
+ /**
1053
+ * Joins a control's own `aria-describedby` ids with the ids a host passes through `[ariaDescribedBy]` (space separated, own ids first,
1054
+ * duplicates dropped). Returns null when there is nothing to point at, so the attribute is absent.
1055
+ */
1056
+ export declare function mergeDescribedBy(own: string | null | undefined, external: string | null | undefined): string | null;
1052
1057
  /**
1053
1058
  * One choice. `V` defaults to `string`, so existing `SelectOption[]` code is unchanged; `ui-select` itself accepts
1054
1059
  * `SelectOption<string | number>[]` (numeric values for `valueType="number"`).
@@ -1085,10 +1090,12 @@ export declare class SelectComponent implements ControlValueAccessor, Validator,
1085
1090
  readonly valueType: import("@angular/core").InputSignal<"string" | "number">;
1086
1091
  readonly required: import("@angular/core").InputSignal<boolean>;
1087
1092
  readonly hint: import("@angular/core").InputSignal<string>;
1093
+ /** Id(s) of an external element that also describes this control (e.g. one shared error text for a group of fields). Space separated; MERGED after the control's own hint / error id in `aria-describedby`, never replacing it. Empty = unchanged. */
1094
+ readonly ariaDescribedBy: import("@angular/core").InputSignal<string>;
1088
1095
  readonly error: import("@angular/core").InputSignal<string>;
1089
1096
  /** Reveal the built-in error messages now (e.g. after a failed Save click), without waiting for blur. */
1090
1097
  readonly showErrors: import("@angular/core").InputSignal<boolean>;
1091
- readonly size: import("@angular/core").InputSignal<"default" | "sm">;
1098
+ readonly size: import("@angular/core").InputSignal<"sm" | "default">;
1092
1099
  readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
1093
1100
  private readonly _cvaDisabled;
1094
1101
  protected readonly disabled: import("@angular/core").Signal<boolean>;
@@ -1098,7 +1105,7 @@ export declare class SelectComponent implements ControlValueAccessor, Validator,
1098
1105
  /** The selected option's `description` ('' when none is selected or it has none); hidden while an error shows. */
1099
1106
  protected readonly _selectedDescription: import("@angular/core").Signal<string>;
1100
1107
  /** ids of the texts that describe the select: the error / hint, then the selected option's description. */
1101
- protected readonly _describedBy: import("@angular/core").Signal<string>;
1108
+ protected readonly _describedBy: import("@angular/core").Signal<string | null>;
1102
1109
  private readonly _reveal;
1103
1110
  private readonly _issue;
1104
1111
  /** True while the value breaks a built-in rule or the host passed an `[error]`. */
@@ -1170,6 +1177,11 @@ export declare class SelectComponent implements ControlValueAccessor, Validator,
1170
1177
  "required": false;
1171
1178
  "isSignal": true;
1172
1179
  };
1180
+ "ariaDescribedBy": {
1181
+ "alias": "ariaDescribedBy";
1182
+ "required": false;
1183
+ "isSignal": true;
1184
+ };
1173
1185
  "error": {
1174
1186
  "alias": "error";
1175
1187
  "required": false;
@@ -2140,7 +2152,7 @@ export declare class SidePanelComponent implements OnDestroy {
2140
2152
  readonly cancelLabel: import("@angular/core").InputSignal<string>;
2141
2153
  /** Right-aligned primary action button label. Empty string = hidden. */
2142
2154
  readonly primaryLabel: import("@angular/core").InputSignal<string>;
2143
- readonly primaryVariant: import("@angular/core").InputSignal<"primary" | "danger" | "warning">;
2155
+ readonly primaryVariant: import("@angular/core").InputSignal<"danger" | "warning" | "primary">;
2144
2156
  readonly primaryLoading: import("@angular/core").InputSignal<boolean>;
2145
2157
  readonly primaryDisabled: import("@angular/core").InputSignal<boolean>;
2146
2158
  /** `data-testid` of the Cancel button; none when empty (default). */
@@ -2248,7 +2260,7 @@ export declare class ModalComponent implements OnInit, OnDestroy {
2248
2260
  readonly title: import("@angular/core").InputSignal<string>;
2249
2261
  readonly description: import("@angular/core").InputSignal<string>;
2250
2262
  readonly maxWidth: import("@angular/core").InputSignal<string>;
2251
- readonly bodyOverflow: import("@angular/core").InputSignal<"hidden" | "auto" | "visible">;
2263
+ readonly bodyOverflow: import("@angular/core").InputSignal<"auto" | "hidden" | "visible">;
2252
2264
  /** `data-testid` of the dialog element itself (the host `<ui-modal>` is always in the page, the dialog only while open). None when empty. */
2253
2265
  readonly dialogTestId: import("@angular/core").InputSignal<string>;
2254
2266
  /** Hides the header X button (e.g. while a request is running). Escape and a backdrop click still close unless `closable` is false. */
@@ -2258,12 +2270,28 @@ export declare class ModalComponent implements OnInit, OnDestroy {
2258
2270
  * (e.g. while a save is running; the host closes it itself). Default `true` = today's behaviour.
2259
2271
  */
2260
2272
  readonly closable: import("@angular/core").InputSignal<boolean>;
2273
+ /**
2274
+ * Look of the dialog. `'default'` (today's dialog; a bottom sheet on a phone) or `'kiosk'`: a darker backdrop and a centred card on every screen
2275
+ * size that never grows past the visible viewport (header and footer stay, the body scrolls, 100dvh with a 100vh fallback). Meant for full-attention
2276
+ * dialogs such as a payment or bank-account entry; combine with `[closeOnBackdrop]="false"` and `[busy]`. See docs/modal-kiosk-and-bank-account-form.md.
2277
+ */
2278
+ readonly layout: import("@angular/core").InputSignal<"default" | "kiosk">;
2279
+ /** `false` = a click on the backdrop does not close (a mis-click must not lose a half-filled payment form). Default `true`. */
2280
+ readonly closeOnBackdrop: import("@angular/core").InputSignal<boolean>;
2281
+ /** `false` = Escape does not close. Default `true`. */
2282
+ readonly closeOnEscape: import("@angular/core").InputSignal<boolean>;
2283
+ /**
2284
+ * `true` while a request is running (e.g. a payment is processing): sets `aria-busy` on the dialog, disables the X button and blocks Escape and
2285
+ * backdrop dismissal, whatever `closable` / `closeOnEscape` / `closeOnBackdrop` say. Default `false`.
2286
+ */
2287
+ readonly busy: import("@angular/core").InputSignal<boolean>;
2261
2288
  readonly close: import("@angular/core").OutputEmitterRef<void>;
2262
2289
  /**
2263
2290
  * Element that gets focus back when the dialog closes. Takes precedence over the element that was focused (or last
2264
2291
  * clicked / activated) when it opened; used only if it is still in the page and visible. Default null = the opener.
2265
2292
  */
2266
2293
  readonly returnFocusTo: import("@angular/core").InputSignal<HTMLElement | null>;
2294
+ protected readonly kiosk: import("@angular/core").Signal<boolean>;
2267
2295
  protected readonly titleId: string;
2268
2296
  private readonly el;
2269
2297
  private readonly ren;
@@ -2276,6 +2304,8 @@ export declare class ModalComponent implements OnInit, OnDestroy {
2276
2304
  private readonly _interaction;
2277
2305
  constructor();
2278
2306
  onKeydown(event: KeyboardEvent): void;
2307
+ /** Emits `close` when the dialog may be dismissed this way (not closable / busy / backdrop or Escape switched off = nothing). */
2308
+ protected dismiss(via: 'backdrop' | 'escape' | 'close'): void;
2279
2309
  /** A focus-guard sentinel received focus (Tab left the dialog's tab order, e.g. out of an iframe): send it back inside. */
2280
2310
  protected onGuardFocus(which: 'start' | 'end', event?: FocusEvent): void;
2281
2311
  /** Initial focus — see `focusInitial` (autofocus target → first usable field → dialog container). */
@@ -2325,6 +2355,26 @@ export declare class ModalComponent implements OnInit, OnDestroy {
2325
2355
  "required": false;
2326
2356
  "isSignal": true;
2327
2357
  };
2358
+ "layout": {
2359
+ "alias": "layout";
2360
+ "required": false;
2361
+ "isSignal": true;
2362
+ };
2363
+ "closeOnBackdrop": {
2364
+ "alias": "closeOnBackdrop";
2365
+ "required": false;
2366
+ "isSignal": true;
2367
+ };
2368
+ "closeOnEscape": {
2369
+ "alias": "closeOnEscape";
2370
+ "required": false;
2371
+ "isSignal": true;
2372
+ };
2373
+ "busy": {
2374
+ "alias": "busy";
2375
+ "required": false;
2376
+ "isSignal": true;
2377
+ };
2328
2378
  "returnFocusTo": {
2329
2379
  "alias": "returnFocusTo";
2330
2380
  "required": false;
@@ -2332,7 +2382,7 @@ export declare class ModalComponent implements OnInit, OnDestroy {
2332
2382
  };
2333
2383
  }, {
2334
2384
  "close": "close";
2335
- }, never, ["*", "[modal-footer-left]", "[modal-footer-center]", "[modal-footer-right]"], true, never>;
2385
+ }, never, ["[modal-header-end]", "*", "[modal-footer-left]", "[modal-footer-center]", "[modal-footer-right]"], true, never>;
2336
2386
  }
2337
2387
  export type ToastType = 'success' | 'error' | 'info';
2338
2388
  export declare class ToastService implements OnDestroy {
@@ -3913,7 +3963,7 @@ export declare class ButtonComponent {
3913
3963
  * `ghost-start`: a ghost button for list / section toggles - a full-width row with its content aligned to the start, transparent
3914
3964
  * background, hover tint and the normal focus ring. Pair it with `ariaExpanded` / `ariaPressed`; the label may contain a heading element.
3915
3965
  */
3916
- readonly variant: import("@angular/core").InputSignal<"primary" | "secondary" | "danger" | "warning" | "link" | "ghost" | "ghost-start" | "tab" | "icon" | "icon-danger">;
3966
+ readonly variant: import("@angular/core").InputSignal<"link" | "danger" | "warning" | "primary" | "secondary" | "ghost" | "ghost-start" | "tab" | "icon" | "icon-danger">;
3917
3967
  /** 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`). */
3918
3968
  readonly routerLink: import("@angular/core").InputSignal<string | readonly unknown[] | null>;
3919
3969
  /** Query params of the `routerLink` (e.g. `{ section: 'deal-defaults' }`). */
@@ -3934,7 +3984,7 @@ export declare class ButtonComponent {
3934
3984
  */
3935
3985
  readonly href: import("@angular/core").InputSignal<string | null>;
3936
3986
  /** Where to open the `href` (`_blank` = a new tab). */
3937
- readonly target: import("@angular/core").InputSignal<"_self" | "_blank" | "_parent" | "_top" | null>;
3987
+ readonly target: import("@angular/core").InputSignal<"_blank" | "_self" | "_parent" | "_top" | null>;
3938
3988
  /** `rel` of the `href` link. A `_blank` target always gets `noopener noreferrer` added. */
3939
3989
  readonly rel: import("@angular/core").InputSignal<string | null>;
3940
3990
  /** The href when it is allowed (http, https, mailto, tel, sms or a relative URL), else null. */
@@ -3958,8 +4008,8 @@ export declare class ButtonComponent {
3958
4008
  private readonly _narrow;
3959
4009
  readonly color: import("@angular/core").InputSignal<string | undefined>;
3960
4010
  readonly active: import("@angular/core").InputSignal<boolean>;
3961
- readonly size: import("@angular/core").InputSignal<"sm" | "md" | "lg" | "xs">;
3962
- readonly type: import("@angular/core").InputSignal<"reset" | "submit" | "button">;
4011
+ readonly size: import("@angular/core").InputSignal<"xs" | "sm" | "md" | "lg">;
4012
+ readonly type: import("@angular/core").InputSignal<"button" | "reset" | "submit">;
3963
4013
  readonly disabled: import("@angular/core").InputSignal<boolean>;
3964
4014
  readonly loading: import("@angular/core").InputSignal<boolean>;
3965
4015
  readonly fullWidth: import("@angular/core").InputSignal<boolean>;
@@ -4598,6 +4648,130 @@ export declare class OptionCardComponent {
4598
4648
  "action": "action";
4599
4649
  }, never, ["*"], true, never>;
4600
4650
  }
4651
+ /** Default ACH debit authorization text (same wording the contractor bank-account kiosk used). */
4652
+ export declare const DEFAULT_BANK_MANDATE_TEXT: string;
4653
+ export type BankAccountType = 'checking' | 'savings';
4654
+ export type BankHolderType = 'individual' | 'company';
4655
+ /** What `(submitted)` emits: every text value trimmed, `mandateAccepted` always `true`. */
4656
+ export interface BankAccountFormValue {
4657
+ routingNumber: string;
4658
+ accountNumber: string;
4659
+ accountType: BankAccountType;
4660
+ accountHolderName: string;
4661
+ holderType: BankHolderType;
4662
+ mandateAccepted: true;
4663
+ }
4664
+ export declare const DEFAULT_BANK_ACCOUNT_TYPE_OPTIONS: SelectOption[];
4665
+ export declare const DEFAULT_BANK_HOLDER_TYPE_OPTIONS: SelectOption[];
4666
+ /**
4667
+ * `ui-bank-account-form` - the US bank-account entry form (routing number, account number + confirmation, account type, holder name + type,
4668
+ * ACH debit authorization). Built only from library inputs; it holds NO HTTP and no provider logic: the host listens to `(submitted)` and talks to
4669
+ * its payment provider (Stripe `confirmUsBankAccountSetup`, Square, ...). See docs/modal-kiosk-and-bank-account-form.md.
4670
+ *
4671
+ * - Validation is inline through the inputs' own `[error]` / built-in rules. The routing number is only checked for 9 digits (no ABA checksum: the
4672
+ * provider validates the real number, and a client checksum would reject test numbers). Account numbers are 4-17 digits.
4673
+ * - Messages show after blur, while a field holds something invalid, or while `[showErrors]` is true; a failed `submit()` reveals them all.
4674
+ * - The form provides `UiFieldValidity` (`invalid` = not submittable), so a host can gate its own button with `viewChildren(UiFieldValidity)`,
4675
+ * or use `(validChange)`.
4676
+ * - The host's footer button calls `form.submit()` (via `viewChild`); Enter in a text field submits too.
4677
+ */
4678
+ export declare class BankAccountFormComponent implements UiFieldValidity {
4679
+ /** Reveal every built-in error now (e.g. bind to a panel's `touched()`); `submit()` on an invalid form also reveals them. */
4680
+ readonly showErrors: import("@angular/core").InputSignal<boolean>;
4681
+ /** Disables every field and blocks `submit()`. */
4682
+ readonly disabled: import("@angular/core").InputSignal<boolean>;
4683
+ /** Like `disabled`, plus `aria-busy` on the host: a provider call is running. */
4684
+ readonly busy: import("@angular/core").InputSignal<boolean>;
4685
+ /** The authorization text next to the checkbox (it is the checkbox label). The unticked default is never changed by the form. */
4686
+ readonly mandateText: import("@angular/core").InputSignal<string>;
4687
+ /** Account type choices; values must stay `checking` / `savings`. */
4688
+ readonly accountTypeOptions: import("@angular/core").InputSignal<SelectOption<string>[]>;
4689
+ /** Holder type choices; values must stay `individual` / `company`. */
4690
+ readonly holderTypeOptions: import("@angular/core").InputSignal<SelectOption<string>[]>;
4691
+ /** Pre-fills the account holder name (e.g. the customer's name) whenever it changes; the user can edit it. */
4692
+ readonly accountHolderNameDefault: import("@angular/core").InputSignal<string>;
4693
+ /** Prefix of the inner test ids: `<prefix>-routing`, `-account`, `-confirm`, `-holder-name`, `-account-type`, `-holder-type`, `-mandate`. */
4694
+ readonly testIdPrefix: import("@angular/core").InputSignal<string>;
4695
+ /** Emits the typed payload when `submit()` runs on a valid form. */
4696
+ readonly submitted: import("@angular/core").OutputEmitterRef<BankAccountFormValue>;
4697
+ /** Emits `true` / `false` whenever the form becomes submittable / not (also once on init). */
4698
+ readonly validChange: import("@angular/core").OutputEmitterRef<boolean>;
4699
+ protected readonly routingNumber: import("@angular/core").WritableSignal<string>;
4700
+ protected readonly accountNumber: import("@angular/core").WritableSignal<string>;
4701
+ protected readonly confirmAccount: import("@angular/core").WritableSignal<string>;
4702
+ protected readonly accountHolderName: import("@angular/core").WritableSignal<string>;
4703
+ protected readonly accountType: import("@angular/core").WritableSignal<string>;
4704
+ protected readonly holderType: import("@angular/core").WritableSignal<string>;
4705
+ protected readonly mandateAccepted: import("@angular/core").WritableSignal<boolean>;
4706
+ private readonly _touched;
4707
+ protected readonly routingFormatter: (raw: string) => string;
4708
+ protected readonly accountFormatter: (raw: string) => string;
4709
+ protected readonly locked: import("@angular/core").Signal<boolean>;
4710
+ protected readonly reveal: import("@angular/core").Signal<boolean>;
4711
+ protected readonly routingError: import("@angular/core").Signal<"" | "Routing number must be 9 digits.">;
4712
+ protected readonly accountError: import("@angular/core").Signal<"" | "Account number must be at least 4 digits.">;
4713
+ protected readonly confirmError: import("@angular/core").Signal<"" | "Account numbers do not match.">;
4714
+ /** First reason the form cannot be submitted ('' when it can). */
4715
+ readonly errorMessage: import("@angular/core").Signal<"" | "Account holder name is required." | "Routing number is required." | "Routing number must be 9 digits." | "Account number is required." | "Account number must be at least 4 digits." | "Confirm account number is required." | "Account numbers do not match." | "Select a valid account type." | "Select a valid holder type." | "You must authorize ACH debits to continue.">;
4716
+ /** True while the form cannot be submitted (`UiFieldValidity`). */
4717
+ readonly invalid: import("@angular/core").Signal<boolean>;
4718
+ /** True when the form can be submitted (ignores `disabled` / `busy`). */
4719
+ readonly valid: import("@angular/core").Signal<boolean>;
4720
+ private readonly _fields;
4721
+ constructor();
4722
+ protected id(name: string): string;
4723
+ protected onEnter(event: Event): void;
4724
+ /** Validates and, when valid, emits `submitted`. An invalid form reveals all messages and emits nothing. Ignored while `disabled` / `busy`. */
4725
+ submit(): void;
4726
+ /** Clears every field back to the defaults (checking, individual, authorization unticked, holder name = `accountHolderNameDefault`). */
4727
+ reset(): void;
4728
+ static ɵfac: i0.ɵɵFactoryDeclaration<BankAccountFormComponent, never>;
4729
+ static ɵcmp: i0.ɵɵComponentDeclaration<BankAccountFormComponent, "ui-bank-account-form", never, {
4730
+ "showErrors": {
4731
+ "alias": "showErrors";
4732
+ "required": false;
4733
+ "isSignal": true;
4734
+ };
4735
+ "disabled": {
4736
+ "alias": "disabled";
4737
+ "required": false;
4738
+ "isSignal": true;
4739
+ };
4740
+ "busy": {
4741
+ "alias": "busy";
4742
+ "required": false;
4743
+ "isSignal": true;
4744
+ };
4745
+ "mandateText": {
4746
+ "alias": "mandateText";
4747
+ "required": false;
4748
+ "isSignal": true;
4749
+ };
4750
+ "accountTypeOptions": {
4751
+ "alias": "accountTypeOptions";
4752
+ "required": false;
4753
+ "isSignal": true;
4754
+ };
4755
+ "holderTypeOptions": {
4756
+ "alias": "holderTypeOptions";
4757
+ "required": false;
4758
+ "isSignal": true;
4759
+ };
4760
+ "accountHolderNameDefault": {
4761
+ "alias": "accountHolderNameDefault";
4762
+ "required": false;
4763
+ "isSignal": true;
4764
+ };
4765
+ "testIdPrefix": {
4766
+ "alias": "testIdPrefix";
4767
+ "required": false;
4768
+ "isSignal": true;
4769
+ };
4770
+ }, {
4771
+ "submitted": "submitted";
4772
+ "validChange": "validChange";
4773
+ }, never, never, true, never>;
4774
+ }
4601
4775
  export interface ActiveConfirm {
4602
4776
  title: string;
4603
4777
  message: string;
@@ -4783,9 +4957,11 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
4783
4957
  * `search`, `text`, `none`). Empty (default) = the browser's default for the field, except `type="tel"`, which keeps `tel`.
4784
4958
  * It only picks the keyboard; it does not restrict what can be typed or pasted.
4785
4959
  */
4786
- readonly inputmode: import("@angular/core").InputSignal<"" | "none" | "text" | "search" | "email" | "tel" | "url" | "decimal" | "numeric">;
4960
+ readonly inputmode: import("@angular/core").InputSignal<"" | "none" | "search" | "text" | "email" | "tel" | "url" | "decimal" | "numeric">;
4787
4961
  readonly readonly: import("@angular/core").InputSignal<boolean>;
4788
4962
  readonly hint: import("@angular/core").InputSignal<string>;
4963
+ /** Id(s) of an external element that also describes this control (e.g. one shared error text for a group of fields). Space separated; MERGED after the control's own hint / error id in `aria-describedby`, never replacing it. Empty = unchanged. */
4964
+ readonly ariaDescribedBy: import("@angular/core").InputSignal<string>;
4789
4965
  readonly error: import("@angular/core").InputSignal<string>;
4790
4966
  /** When true, automatically formats the value as a US phone number as the user types. */
4791
4967
  readonly phoneFormat: import("@angular/core").InputSignal<boolean>;
@@ -4971,6 +5147,11 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
4971
5147
  "required": false;
4972
5148
  "isSignal": true;
4973
5149
  };
5150
+ "ariaDescribedBy": {
5151
+ "alias": "ariaDescribedBy";
5152
+ "required": false;
5153
+ "isSignal": true;
5154
+ };
4974
5155
  "error": {
4975
5156
  "alias": "error";
4976
5157
  "required": false;
@@ -5043,6 +5224,8 @@ export declare class TextareaInputComponent implements ControlValueAccessor, Val
5043
5224
  readonly required: import("@angular/core").InputSignal<boolean>;
5044
5225
  readonly readonly: import("@angular/core").InputSignal<boolean>;
5045
5226
  readonly hint: import("@angular/core").InputSignal<string>;
5227
+ /** Id(s) of an external element that also describes this control (e.g. one shared error text for a group of fields). Space separated; MERGED after the control's own hint / error id in `aria-describedby`, never replacing it. Empty = unchanged. */
5228
+ readonly ariaDescribedBy: import("@angular/core").InputSignal<string>;
5046
5229
  /**
5047
5230
  * Opt-in. `false` (default) = unchanged: a labelled field's hint renders INSIDE the `<label>` ("Label (hint)" is the accessible name,
5048
5231
  * no aria-describedby for it). `true` = the hint is a sibling of the label (`.ta-head` row, id `<textarea id>-hint`), the accessible
@@ -5065,6 +5248,7 @@ export declare class TextareaInputComponent implements ControlValueAccessor, Val
5065
5248
  * hint is replaced by the error) followed by the error. The label is the accessible NAME; the hint is the DESCRIPTION.
5066
5249
  */
5067
5250
  protected readonly _describedBy: import("@angular/core").Signal<string | null>;
5251
+ private readonly _ownDescribedBy;
5068
5252
  private readonly _reveal;
5069
5253
  private readonly _issue;
5070
5254
  /** True while the value breaks a built-in rule or the host passed an `[error]`. */
@@ -5132,6 +5316,11 @@ export declare class TextareaInputComponent implements ControlValueAccessor, Val
5132
5316
  "required": false;
5133
5317
  "isSignal": true;
5134
5318
  };
5319
+ "ariaDescribedBy": {
5320
+ "alias": "ariaDescribedBy";
5321
+ "required": false;
5322
+ "isSignal": true;
5323
+ };
5135
5324
  "hintAsDescription": {
5136
5325
  "alias": "hintAsDescription";
5137
5326
  "required": false;
@@ -5535,6 +5724,8 @@ export declare class DateInputComponent implements ControlValueAccessor, Validat
5535
5724
  readonly min: import("@angular/core").InputSignal<string>;
5536
5725
  readonly max: import("@angular/core").InputSignal<string>;
5537
5726
  readonly hint: import("@angular/core").InputSignal<string>;
5727
+ /** Id(s) of an external element that also describes this control (e.g. one shared error text for a group of fields). Space separated; MERGED after the control's own hint / error id in `aria-describedby`, never replacing it. Empty = unchanged. */
5728
+ readonly ariaDescribedBy: import("@angular/core").InputSignal<string>;
5538
5729
  readonly error: import("@angular/core").InputSignal<string>;
5539
5730
  /** Reveal the built-in error messages now (e.g. after a failed Save click), without waiting for blur. */
5540
5731
  readonly showErrors: import("@angular/core").InputSignal<boolean>;
@@ -5543,6 +5734,8 @@ export declare class DateInputComponent implements ControlValueAccessor, Validat
5543
5734
  private readonly _cvaDisabled;
5544
5735
  protected readonly disabled: import("@angular/core").Signal<boolean>;
5545
5736
  protected readonly _value: import("@angular/core").WritableSignal<string>;
5737
+ /** `aria-describedby`: the error / hint text, then the host's `ariaDescribedBy` id(s). */
5738
+ protected readonly _describedBy: import("@angular/core").Signal<string | null>;
5546
5739
  private readonly _reveal;
5547
5740
  private readonly _issue;
5548
5741
  /** True while the value breaks a built-in rule or the host passed an `[error]`. */
@@ -5597,6 +5790,11 @@ export declare class DateInputComponent implements ControlValueAccessor, Validat
5597
5790
  "required": false;
5598
5791
  "isSignal": true;
5599
5792
  };
5793
+ "ariaDescribedBy": {
5794
+ "alias": "ariaDescribedBy";
5795
+ "required": false;
5796
+ "isSignal": true;
5797
+ };
5600
5798
  "error": {
5601
5799
  "alias": "error";
5602
5800
  "required": false;
@@ -5623,6 +5821,8 @@ export declare class DatetimeInputComponent implements ControlValueAccessor, Val
5623
5821
  readonly min: import("@angular/core").InputSignal<string>;
5624
5822
  readonly max: import("@angular/core").InputSignal<string>;
5625
5823
  readonly hint: import("@angular/core").InputSignal<string>;
5824
+ /** Id(s) of an external element that also describes this control (e.g. one shared error text for a group of fields). Space separated; MERGED after the control's own hint / error id in `aria-describedby`, never replacing it. Empty = unchanged. */
5825
+ readonly ariaDescribedBy: import("@angular/core").InputSignal<string>;
5626
5826
  readonly error: import("@angular/core").InputSignal<string>;
5627
5827
  /** Reveal the built-in error messages now (e.g. after a failed Save click), without waiting for blur. */
5628
5828
  readonly showErrors: import("@angular/core").InputSignal<boolean>;
@@ -5630,6 +5830,8 @@ export declare class DatetimeInputComponent implements ControlValueAccessor, Val
5630
5830
  private readonly _cvaDisabled;
5631
5831
  protected readonly disabled: import("@angular/core").Signal<boolean>;
5632
5832
  protected readonly _value: import("@angular/core").WritableSignal<string>;
5833
+ /** `aria-describedby`: the error / hint text, then the host's `ariaDescribedBy` id(s). */
5834
+ protected readonly _describedBy: import("@angular/core").Signal<string | null>;
5633
5835
  private readonly _reveal;
5634
5836
  private readonly _issue;
5635
5837
  /** True while the value breaks a built-in rule or the host passed an `[error]`. */
@@ -5682,6 +5884,11 @@ export declare class DatetimeInputComponent implements ControlValueAccessor, Val
5682
5884
  "required": false;
5683
5885
  "isSignal": true;
5684
5886
  };
5887
+ "ariaDescribedBy": {
5888
+ "alias": "ariaDescribedBy";
5889
+ "required": false;
5890
+ "isSignal": true;
5891
+ };
5685
5892
  "error": {
5686
5893
  "alias": "error";
5687
5894
  "required": false;
@@ -5709,6 +5916,8 @@ export declare class TimeInputComponent implements ControlValueAccessor, Validat
5709
5916
  readonly min: import("@angular/core").InputSignal<string>;
5710
5917
  readonly max: import("@angular/core").InputSignal<string>;
5711
5918
  readonly hint: import("@angular/core").InputSignal<string>;
5919
+ /** Id(s) of an external element that also describes this control (e.g. one shared error text for a group of fields). Space separated; MERGED after the control's own hint / error id in `aria-describedby`, never replacing it. Empty = unchanged. */
5920
+ readonly ariaDescribedBy: import("@angular/core").InputSignal<string>;
5712
5921
  readonly error: import("@angular/core").InputSignal<string>;
5713
5922
  /** Reveal the built-in error messages now (e.g. after a failed Save click), without waiting for blur. */
5714
5923
  readonly showErrors: import("@angular/core").InputSignal<boolean>;
@@ -5718,6 +5927,8 @@ export declare class TimeInputComponent implements ControlValueAccessor, Validat
5718
5927
  protected readonly disabled: import("@angular/core").Signal<boolean>;
5719
5928
  protected readonly _value: import("@angular/core").WritableSignal<string>;
5720
5929
  protected readonly _inputId: string;
5930
+ /** `aria-describedby`: the error / hint text, then the host's `ariaDescribedBy` id(s). */
5931
+ protected readonly _describedBy: import("@angular/core").Signal<string | null>;
5721
5932
  private readonly _reveal;
5722
5933
  private readonly _issue;
5723
5934
  /** True while the value breaks a built-in rule or the host passed an `[error]`. */
@@ -5774,6 +5985,11 @@ export declare class TimeInputComponent implements ControlValueAccessor, Validat
5774
5985
  "required": false;
5775
5986
  "isSignal": true;
5776
5987
  };
5988
+ "ariaDescribedBy": {
5989
+ "alias": "ariaDescribedBy";
5990
+ "required": false;
5991
+ "isSignal": true;
5992
+ };
5777
5993
  "error": {
5778
5994
  "alias": "error";
5779
5995
  "required": false;
@@ -6208,7 +6424,7 @@ export declare class DropdownComponent {
6208
6424
  readonly loader: import("@angular/core").InputSignal<(() => Promise<DropdownItem[]>) | null>;
6209
6425
  readonly active: import("@angular/core").InputSignal<boolean>;
6210
6426
  readonly activeValue: import("@angular/core").InputSignal<string>;
6211
- readonly variant: import("@angular/core").InputSignal<"badge" | "button">;
6427
+ readonly variant: import("@angular/core").InputSignal<"button" | "badge">;
6212
6428
  readonly menuWidth: import("@angular/core").InputSignal<string>;
6213
6429
  /**
6214
6430
  * Fixed width of the trigger as a CSS length (e.g. `'280px'`). Empty (default) = the trigger is as wide as its label. When set, the trigger keeps that
@@ -6529,7 +6745,7 @@ export declare class FormRowComponent {
6529
6745
  * child simply takes the full width. Keep a numeric span within the row's `cols` (use `all` for the whole row).
6530
6746
  */
6531
6747
  export declare class FormColSpanDirective {
6532
- readonly uiColSpan: import("@angular/core").InputSignal<"" | "2" | "3" | 2 | 3 | "all">;
6748
+ readonly uiColSpan: import("@angular/core").InputSignal<"" | "all" | "2" | 2 | "3" | 3>;
6533
6749
  protected readonly _class: import("@angular/core").Signal<string>;
6534
6750
  static ɵfac: i0.ɵɵFactoryDeclaration<FormColSpanDirective, never>;
6535
6751
  static ɵdir: i0.ɵɵDirectiveDeclaration<FormColSpanDirective, "[uiColSpan]", never, {
@@ -6779,6 +6995,8 @@ export declare class CardListItemComponent {
6779
6995
  readonly actionLabel: import("@angular/core").InputSignal<string>;
6780
6996
  readonly actionTestId: import("@angular/core").InputSignal<string>;
6781
6997
  readonly actionAriaLabel: import("@angular/core").InputSignal<string>;
6998
+ /** A built-in Edit / View / action / delete button shows (the row then keeps a minimum height so a badge and a chip never overlap). */
6999
+ protected readonly hasBuiltInChip: import("@angular/core").Signal<boolean>;
6782
7000
  readonly editClick: import("@angular/core").OutputEmitterRef<void>;
6783
7001
  readonly viewClick: import("@angular/core").OutputEmitterRef<void>;
6784
7002
  readonly delete: import("@angular/core").OutputEmitterRef<void>;
@@ -7644,9 +7862,9 @@ export declare class ChipGroupComponent {
7644
7862
  readonly spaceAbove: import("@angular/core").InputSignal<"none" | "sm" | "md">;
7645
7863
  /** Space below the chip group. */
7646
7864
  readonly spaceBelow: import("@angular/core").InputSignal<"none" | "sm" | "md">;
7647
- protected readonly _gap: import("@angular/core").Signal<"6px" | "12px" | "8px">;
7648
- protected readonly _spaceAbove: import("@angular/core").Signal<"0" | "6px" | "12px">;
7649
- protected readonly _spaceBelow: import("@angular/core").Signal<"0" | "6px" | "12px">;
7865
+ protected readonly _gap: import("@angular/core").Signal<"12px" | "6px" | "8px">;
7866
+ protected readonly _spaceAbove: import("@angular/core").Signal<"12px" | "0" | "6px">;
7867
+ protected readonly _spaceBelow: import("@angular/core").Signal<"12px" | "0" | "6px">;
7650
7868
  static ɵfac: i0.ɵɵFactoryDeclaration<ChipGroupComponent, never>;
7651
7869
  static ɵcmp: i0.ɵɵComponentDeclaration<ChipGroupComponent, "ui-chip-group", never, {
7652
7870
  "gap": {
@@ -9439,7 +9657,7 @@ export declare class PdfHotspotComponent {
9439
9657
  /** `ready`: clickable; `blocked`: disabled (a prerequisite is missing); `signed`: shows `image`. */
9440
9658
  readonly state: import("@angular/core").InputSignal<"ready" | "blocked" | "signed">;
9441
9659
  /** `warning` gives the ready state an amber look (e.g. for initials), default is blue. */
9442
- readonly tone: import("@angular/core").InputSignal<"primary" | "warning">;
9660
+ readonly tone: import("@angular/core").InputSignal<"warning" | "primary">;
9443
9661
  /** Text of the ready button (e.g. "Sign Here"). */
9444
9662
  readonly label: import("@angular/core").InputSignal<string>;
9445
9663
  /** Text of the blocked button (e.g. "Add signature above"). */
@@ -12701,4 +12919,251 @@ export declare const DEFAULT_EMAIL_TEMPLATE_VARIABLE_GROUPS: {
12701
12919
  * Content-Security-Policy meta blocks scripts and anything but images / inline styles, and links open nowhere (sandbox, no popups).
12702
12920
  */
12703
12921
  export declare function buildPreviewDocument(bodyHtml: string): string;
12922
+ export type ShareOption = 'native' | 'facebook' | 'x' | 'linkedin' | 'email' | 'gmail' | 'outlook' | 'copy';
12923
+ interface ShareTile {
12924
+ value: ShareOption;
12925
+ label: string;
12926
+ background: string;
12927
+ }
12928
+ /**
12929
+ * "Share" control for a public page (an obituary, a blog post, any shareable item). The button opens a floating panel (over the page, so nothing moves)
12930
+ * with one round icon per option and its name underneath, in a row like a phone's share sheet. Phones and tablets get Facebook, X,
12931
+ * LinkedIn, Email (their mail app), Copy link and "More" (the device's own share sheet). Desktops get Gmail and Outlook instead of Email:
12932
+ * a `mailto:` link does nothing on a computer without a mail app, while the webmail compose windows always open. "Link copied" is the library toast. The link is the public page
12933
+ * of the item (never an `?embed=true` widget URL). Theming: `--ui-share-accent` (focus ring and the Copy link tile; default the library `--primary`).
12934
+ *
12935
+ * <ui-share-menu [url]="pageUrl" [title]="post.title" label="blog post" />
12936
+ */
12937
+ export declare class ShareMenuComponent {
12938
+ /** The public page link to share. */
12939
+ readonly url: import("@angular/core").InputSignal<string>;
12940
+ /** The headline: the item's name or title (the X text, the email subject and the share-sheet title). */
12941
+ readonly title: import("@angular/core").InputSignal<string>;
12942
+ /** Used in the accessible name, e.g. "obituary" or "blog post" (→ "Share obituary"). */
12943
+ readonly label: import("@angular/core").InputSignal<string>;
12944
+ /** Unique id of the floating panel (several menus can be on one page). */
12945
+ protected readonly panelId: string;
12946
+ private readonly doc;
12947
+ private readonly toast;
12948
+ private readonly injector;
12949
+ private readonly host;
12950
+ private readonly trigger;
12951
+ private readonly panel;
12952
+ readonly open: import("@angular/core").WritableSignal<boolean>;
12953
+ /** Pixels the panel is moved sideways so it never runs off either edge of the screen (or of the embedding frame). */
12954
+ readonly shiftX: import("@angular/core").WritableSignal<number>;
12955
+ /**
12956
+ * "More" opens the device's own share sheet (Messages, AirDrop, Mail, WhatsApp…). It is offered on touch devices only: a desktop
12957
+ * browser has the other options already, and its share sheet is limited (or absent), so "More" there would look broken.
12958
+ */
12959
+ private readonly isTouchDevice;
12960
+ private readonly canNativeShare;
12961
+ readonly tiles: import("@angular/core").Signal<ShareTile[]>;
12962
+ /** The link each option opens (social sites in a new tab; the mail app in this window). */
12963
+ readonly links: import("@angular/core").Signal<{
12964
+ facebook: string;
12965
+ x: string;
12966
+ linkedin: string;
12967
+ email: string;
12968
+ gmail: string;
12969
+ outlook: string;
12970
+ }>;
12971
+ toggle(event: Event): void;
12972
+ private show;
12973
+ close(returnFocus?: boolean): void;
12974
+ onEscape(): void;
12975
+ onDocumentClick(event: Event): void;
12976
+ onFocusOut(event: FocusEvent): void;
12977
+ /** Left / Right / Home / End move between the options. */
12978
+ onPanelKeydown(event: KeyboardEvent): void;
12979
+ choose(option: ShareOption): void;
12980
+ private nativeShare;
12981
+ /** Phones and tablets: opens the device's mail app with the subject and body filled in. */
12982
+ private email;
12983
+ private copy;
12984
+ private legacyCopy;
12985
+ static ɵfac: i0.ɵɵFactoryDeclaration<ShareMenuComponent, never>;
12986
+ static ɵcmp: i0.ɵɵComponentDeclaration<ShareMenuComponent, "ui-share-menu", never, {
12987
+ "url": {
12988
+ "alias": "url";
12989
+ "required": true;
12990
+ "isSignal": true;
12991
+ };
12992
+ "title": {
12993
+ "alias": "title";
12994
+ "required": true;
12995
+ "isSignal": true;
12996
+ };
12997
+ "label": {
12998
+ "alias": "label";
12999
+ "required": false;
13000
+ "isSignal": true;
13001
+ };
13002
+ }, {}, never, never, true, never>;
13003
+ }
13004
+ /**
13005
+ * The links the public Share control builds. Pure functions so the component and its spec produce the exact same text.
13006
+ * Every value is URL-encoded, so a title holding `&`, `#`, quotes or non-ASCII text can never break out of its query parameter.
13007
+ */
13008
+ export declare const facebookShareUrl: (url: string) => string;
13009
+ export declare const xShareUrl: (url: string, text: string) => string;
13010
+ export declare const linkedInShareUrl: (url: string) => string;
13011
+ /** Gmail's compose window (a new tab) with the subject and body filled in: for desktop visitors, who often have no mail app for `mailto:`. */
13012
+ export declare const gmailShareUrl: (url: string, title: string) => string;
13013
+ /** Outlook.com's compose window (a new tab) with the subject and body filled in. */
13014
+ export declare const outlookShareUrl: (url: string, title: string) => string;
13015
+ /** `mailto:` with the title as the subject and the title plus the link as the body (encodeURIComponent, never `+` for spaces). */
13016
+ export declare const emailShareUrl: (url: string, title: string) => string;
13017
+ export type SnackbarType = 'success' | 'error' | 'info';
13018
+ /** An optional button inside a snackbar (e.g. "View"): clicking it runs `callback` and closes the snackbar. */
13019
+ export interface SnackbarAction {
13020
+ label: string;
13021
+ callback: () => void;
13022
+ }
13023
+ export interface SnackbarMessage {
13024
+ id: number;
13025
+ message: string;
13026
+ type: SnackbarType;
13027
+ action?: SnackbarAction;
13028
+ }
13029
+ /**
13030
+ * Stacked, top-right notifications: several can be on screen at once, each closes itself after `duration` ms (0 = stays until closed)
13031
+ * and can carry one action button. Render them once, near the root of the app, with `<ui-snackbar />`.
13032
+ * (`ToastService` / `<ui-toast>` is the single bottom-centre message; this is the stack with actions.)
13033
+ */
13034
+ export declare class SnackbarService {
13035
+ private readonly _messages;
13036
+ private nextId;
13037
+ private readonly timers;
13038
+ /** The messages on screen, oldest first (a copy). */
13039
+ messages$(): SnackbarMessage[];
13040
+ showSuccess(message: string, duration?: number): void;
13041
+ showError(message: string, duration?: number): void;
13042
+ showInfo(message: string, duration?: number, action?: SnackbarAction): void;
13043
+ private show;
13044
+ dismiss(id: number): void;
13045
+ static ɵfac: i0.ɵɵFactoryDeclaration<SnackbarService, never>;
13046
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
13047
+ }
13048
+ /**
13049
+ * The on-screen stack of `SnackbarService` messages (top-right, above the page). Put one `<ui-snackbar />` near the root of the app.
13050
+ * Each message is a library `ui-alert` (green success, red error, blue info) with a close button and, when the message has one, an
13051
+ * action button. Test ids: `success-message` / `error-message` / `info-message` on each message, `snackbar-action` on the action button.
13052
+ */
13053
+ export declare class SnackbarComponent {
13054
+ private readonly service;
13055
+ /** The messages on screen. */
13056
+ protected readonly messages: import("@angular/core").Signal<SnackbarMessage[]>;
13057
+ protected variant(m: SnackbarMessage): 'success' | 'danger' | 'info';
13058
+ protected dismiss(id: number): void;
13059
+ /** Runs the action, then closes the message. */
13060
+ protected runAction(m: SnackbarMessage, callback: () => void): void;
13061
+ static ɵfac: i0.ɵɵFactoryDeclaration<SnackbarComponent, never>;
13062
+ static ɵcmp: i0.ɵɵComponentDeclaration<SnackbarComponent, "ui-snackbar", never, {}, {}, never, never, true, never>;
13063
+ }
13064
+ /**
13065
+ * A banner across the top of the page while the browser is offline (`navigator.onLine`, kept current by the window's `online` /
13066
+ * `offline` events). The user can dismiss it; it comes back the next time the connection drops. Put one near the root of the app:
13067
+ *
13068
+ * <ui-offline-banner />
13069
+ *
13070
+ * `offline` overrides the browser's own state (for an app that does its own connectivity check). Texts can be changed with `title`
13071
+ * and `message`. Test ids: `offline-banner`, `offline-banner-dismiss`.
13072
+ */
13073
+ export declare class OfflineBannerComponent {
13074
+ readonly title: import("@angular/core").InputSignal<string>;
13075
+ readonly message: import("@angular/core").InputSignal<string>;
13076
+ /** Forces the state (true = offline); `null` (default) follows the browser. */
13077
+ readonly offline: import("@angular/core").InputSignal<boolean | null>;
13078
+ private readonly browserOffline;
13079
+ private readonly dismissed;
13080
+ protected readonly isOffline: import("@angular/core").Signal<boolean>;
13081
+ protected readonly visible: import("@angular/core").Signal<boolean>;
13082
+ constructor();
13083
+ protected dismiss(): void;
13084
+ static ɵfac: i0.ɵɵFactoryDeclaration<OfflineBannerComponent, never>;
13085
+ static ɵcmp: i0.ɵɵComponentDeclaration<OfflineBannerComponent, "ui-offline-banner", never, {
13086
+ "title": {
13087
+ "alias": "title";
13088
+ "required": false;
13089
+ "isSignal": true;
13090
+ };
13091
+ "message": {
13092
+ "alias": "message";
13093
+ "required": false;
13094
+ "isSignal": true;
13095
+ };
13096
+ "offline": {
13097
+ "alias": "offline";
13098
+ "required": false;
13099
+ "isSignal": true;
13100
+ };
13101
+ }, {}, never, never, true, never>;
13102
+ }
13103
+ export type ReminderAlertTone = 'danger' | 'warning' | 'info' | 'neutral';
13104
+ export interface ReminderAlertAction {
13105
+ /** Reported by `(action)`; also part of the button's test id (`alert-<id>`). */
13106
+ id: string;
13107
+ label: string;
13108
+ variant?: 'primary' | 'secondary' | 'ghost';
13109
+ }
13110
+ /** One in-app alert: a due reminder, an event starting soon, anything the user should notice now. The HOST decides what is due and what the buttons do. */
13111
+ export interface ReminderAlertItem {
13112
+ id: string;
13113
+ tone: ReminderAlertTone;
13114
+ /** Small uppercase line above the title, e.g. "Overdue Reminder". */
13115
+ label: string;
13116
+ title: string;
13117
+ /** Plain lines under the title (case name, description, due date…). */
13118
+ lines?: string[];
13119
+ /** A small purple pill under the title, e.g. the organization that created the item. */
13120
+ badge?: {
13121
+ label: string;
13122
+ ariaLabel?: string;
13123
+ testId?: string;
13124
+ };
13125
+ actions?: ReminderAlertAction[];
13126
+ /** Accessible name of the hide (X) button; default "Hide alert". */
13127
+ hideLabel?: string;
13128
+ /** Test id of the hide button; default `alert-hide`. */
13129
+ hideTestId?: string;
13130
+ }
13131
+ /**
13132
+ * The stack of in-app alerts in the top-right corner (above the page, newest app state wins: the host passes the list). Each alert is a
13133
+ * library `ui-alert` with a coloured tone, its label / title / lines, an optional badge, action buttons and a hide (X) button:
13134
+ *
13135
+ * <ui-reminder-alerts [items]="alerts()" (action)="onAction($event)" (hidden)="hide($event)" />
13136
+ *
13137
+ * `(action)` gives `{ item, actionId }`; `(hidden)` gives the item. The component keeps no state: the host removes an item from `items`
13138
+ * to make it go away (hiding, completing, snoozing are the host's rules). Nothing is drawn for an empty list.
13139
+ */
13140
+ export declare class ReminderAlertsComponent {
13141
+ readonly items: import("@angular/core").InputSignal<ReminderAlertItem[]>;
13142
+ /** Accessible name of the region. */
13143
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
13144
+ /** An action button was clicked. */
13145
+ readonly action: import("@angular/core").OutputEmitterRef<{
13146
+ item: ReminderAlertItem;
13147
+ actionId: string;
13148
+ }>;
13149
+ /** The hide (X) button was clicked. */
13150
+ readonly hidden: import("@angular/core").OutputEmitterRef<ReminderAlertItem>;
13151
+ protected variant(item: ReminderAlertItem): AlertVariant;
13152
+ static ɵfac: i0.ɵɵFactoryDeclaration<ReminderAlertsComponent, never>;
13153
+ static ɵcmp: i0.ɵɵComponentDeclaration<ReminderAlertsComponent, "ui-reminder-alerts", never, {
13154
+ "items": {
13155
+ "alias": "items";
13156
+ "required": false;
13157
+ "isSignal": true;
13158
+ };
13159
+ "ariaLabel": {
13160
+ "alias": "ariaLabel";
13161
+ "required": false;
13162
+ "isSignal": true;
13163
+ };
13164
+ }, {
13165
+ "action": "action";
13166
+ "hidden": "hidden";
13167
+ }, never, never, true, never>;
13168
+ }
12704
13169
  export type { CalendarDay, CalendarRange, CalendarViewMode };