@forgeroute/ui 0.4.51 → 0.4.52

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgeroute/ui",
3
- "version": "0.4.51",
3
+ "version": "0.4.52",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=22.0.0",
6
6
  "@angular/core": ">=22.0.0",
@@ -115,7 +115,7 @@ export declare class TemplatePickerComponent {
115
115
  private readonly host;
116
116
  private readonly search$;
117
117
  /** Filter results to a specific channel: 'email', 'text', or omit for all. */
118
- readonly channel: import("@angular/core").InputSignal<"" | "email" | "text">;
118
+ readonly channel: import("@angular/core").InputSignal<"" | "text" | "email">;
119
119
  readonly selectedId: import("@angular/core").InputSignal<string | null>;
120
120
  readonly label: import("@angular/core").InputSignal<string>;
121
121
  /** Shows the red required asterisk (same as the library inputs) — e.g. when a template must be picked to send. */
@@ -543,7 +543,7 @@ export declare class DocumentSendOptionsComponent implements UiFieldValidity {
543
543
  /** API root from FORGEROUTE_CONFIG (e.g. a cross-origin prod API); falls back to same-origin `/api`. */
544
544
  private readonly apiBase;
545
545
  /** `email` → purpose select + attachment allowed; `text` → link only (purpose fixed to e-signature). */
546
- readonly channel: import("@angular/core").InputSignal<"email" | "text">;
546
+ readonly channel: import("@angular/core").InputSignal<"text" | "email">;
547
547
  readonly label: import("@angular/core").InputSignal<string>;
548
548
  /** When true, at least one document must be chosen. The message forms leave it false: documents are optional there. */
549
549
  readonly required: import("@angular/core").InputSignal<boolean>;
@@ -608,7 +608,7 @@ export declare class DocumentSendOptionsComponent implements UiFieldValidity {
608
608
  /** Roles of documents whose row had no `signerRoles` and that the host resolves (`signers().resolveRoles`). */
609
609
  readonly roleStates: import("@angular/core").WritableSignal<Record<string, RoleState>>;
610
610
  /** The envelope's documents: `loading` / `error` while the panel reads them (`loadDocuments`), `ready` once known. */
611
- readonly envelopeStatus: import("@angular/core").WritableSignal<"idle" | "loading" | "ready" | "error">;
611
+ readonly envelopeStatus: import("@angular/core").WritableSignal<"error" | "loading" | "ready" | "idle">;
612
612
  private envelopeSub;
613
613
  private readonly roleSubs;
614
614
  /** The sender opened the collapsed "Signing options" line. */
@@ -1997,7 +1997,7 @@ export declare class SendMessagePanelComponent {
1997
1997
  readonly activeContact: import("@angular/core").WritableSignal<MessageContact | null>;
1998
1998
  /** What the sender should know about the picked contact before sending (why a channel is missing, what to add). */
1999
1999
  readonly contactNotices: import("@angular/core").Signal<string[]>;
2000
- readonly channel: import("@angular/core").WritableSignal<"email" | "text">;
2000
+ readonly channel: import("@angular/core").WritableSignal<"text" | "email">;
2001
2001
  readonly valid: import("@angular/core").WritableSignal<boolean>;
2002
2002
  /** Bumped on every fresh open / new contact — re-creates the email and text forms so no draft carries over. */
2003
2003
  readonly formEpoch: import("@angular/core").WritableSignal<number>;
@@ -1300,7 +1300,7 @@ export declare class StripeConnectComponent {
1300
1300
  readonly navigateTab: import("@angular/core").InputSignal<((url: string) => void) | null>;
1301
1301
  protected readonly visible: import("@angular/core").Signal<boolean>;
1302
1302
  /** Which screen the card shows. */
1303
- protected readonly state: import("@angular/core").Signal<"none" | "complete" | "verifying" | "incomplete">;
1303
+ protected readonly state: import("@angular/core").Signal<"complete" | "verifying" | "incomplete" | "none">;
1304
1304
  /** What the persistent status region says: the current state, plus "Loading." while a request runs. Empty while nothing is shown. */
1305
1305
  protected readonly liveText: import("@angular/core").Signal<string>;
1306
1306
  /** The user pressed a button that started a request: when the screen then changes, focus moves to the new screen (the pressed button is gone). */
@@ -2233,7 +2233,7 @@ export declare class ModalComponent implements OnInit, OnDestroy {
2233
2233
  readonly title: import("@angular/core").InputSignal<string>;
2234
2234
  readonly description: import("@angular/core").InputSignal<string>;
2235
2235
  readonly maxWidth: import("@angular/core").InputSignal<string>;
2236
- readonly bodyOverflow: import("@angular/core").InputSignal<"hidden" | "visible" | "auto">;
2236
+ readonly bodyOverflow: import("@angular/core").InputSignal<"hidden" | "auto" | "visible">;
2237
2237
  /** `data-testid` of the dialog element itself (the host `<ui-modal>` is always in the page, the dialog only while open). None when empty. */
2238
2238
  readonly dialogTestId: import("@angular/core").InputSignal<string>;
2239
2239
  /** Hides the header X button (e.g. while a request is running). Escape and a backdrop click still close unless `closable` is false. */
@@ -2617,7 +2617,7 @@ export declare class AudioPlayerComponent {
2617
2617
  /** Accessible name of the player. */
2618
2618
  readonly ariaLabel: import("@angular/core").InputSignal<string>;
2619
2619
  /** How much to load before play: 'metadata' (default), 'auto' or 'none'. */
2620
- readonly preload: import("@angular/core").InputSignal<"metadata" | "none" | "auto">;
2620
+ readonly preload: import("@angular/core").InputSignal<"none" | "auto" | "metadata">;
2621
2621
  /** Fires when the browser can't load or decode the source. */
2622
2622
  readonly playbackError: import("@angular/core").OutputEmitterRef<void>;
2623
2623
  protected readonly failed: import("@angular/core").WritableSignal<boolean>;
@@ -2871,7 +2871,7 @@ export declare class CheckboxComponent implements ControlValueAccessor, Validato
2871
2871
  * clicking it still toggles the box - e.g. a product name that is both the heading of its card and the label of its checkbox.
2872
2872
  * Default null: plain label text, exactly as before. Single mode only.
2873
2873
  */
2874
- readonly headingLevel: import("@angular/core").InputSignal<3 | 1 | 2 | 6 | 4 | 5 | null>;
2874
+ readonly headingLevel: import("@angular/core").InputSignal<1 | 2 | 3 | 4 | 5 | 6 | null>;
2875
2875
  readonly indeterminate: import("@angular/core").InputSignal<boolean>;
2876
2876
  readonly checked: import("@angular/core").ModelSignal<boolean>;
2877
2877
  /**
@@ -3782,7 +3782,7 @@ export declare class PhoneNumberPickerComponent {
3782
3782
  protected readonly modeCtl: FormControl<string>;
3783
3783
  protected readonly zipCtl: FormControl<string>;
3784
3784
  protected readonly areaCtl: FormControl<string>;
3785
- protected readonly step: import("@angular/core").WritableSignal<3 | 1 | 2>;
3785
+ protected readonly step: import("@angular/core").WritableSignal<1 | 2 | 3>;
3786
3786
  protected readonly mode: import("@angular/core").WritableSignal<PhoneNumberSearchMode>;
3787
3787
  private readonly _zip;
3788
3788
  private readonly _area;
@@ -3815,6 +3815,8 @@ export declare class PhoneNumberPickerComponent {
3815
3815
  constructor();
3816
3816
  protected onPrimary(): void;
3817
3817
  protected onEnter(event: Event): void;
3818
+ /** A field that was swapped out by a mode switch blurs while it is removed: that late blur must not mark the new field touched. */
3819
+ protected onFieldBlur(from: PhoneNumberSearchMode): void;
3818
3820
  /** Typing a non-digit is blocked before it reaches the field. */
3819
3821
  protected onBeforeInput(event: Event): void;
3820
3822
  /** A pasted ZIP+4 / formatted text keeps its first 5 (or 3) digits and replaces the field's text. */
@@ -3896,7 +3898,7 @@ export declare class ButtonComponent {
3896
3898
  * `ghost-start`: a ghost button for list / section toggles - a full-width row with its content aligned to the start, transparent
3897
3899
  * background, hover tint and the normal focus ring. Pair it with `ariaExpanded` / `ariaPressed`; the label may contain a heading element.
3898
3900
  */
3899
- readonly variant: import("@angular/core").InputSignal<"link" | "primary" | "secondary" | "danger" | "warning" | "ghost" | "ghost-start" | "tab" | "icon" | "icon-danger">;
3901
+ readonly variant: import("@angular/core").InputSignal<"primary" | "secondary" | "danger" | "warning" | "link" | "ghost" | "ghost-start" | "tab" | "icon" | "icon-danger">;
3900
3902
  /** 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`). */
3901
3903
  readonly routerLink: import("@angular/core").InputSignal<string | readonly unknown[] | null>;
3902
3904
  /** Query params of the `routerLink` (e.g. `{ section: 'deal-defaults' }`). */
@@ -4158,6 +4160,9 @@ export declare class PillTabsComponent {
4158
4160
  readonly name: import("@angular/core").InputSignal<string>;
4159
4161
  /** Keep every pill at its own width on one line (default false: pills may shrink and wrap their text). On a phone the row scrolls sideways, as it always does. */
4160
4162
  readonly noWrap: import("@angular/core").InputSignal<boolean>;
4163
+ /** 'vertical' stacks the tabs in a column (Up/Down arrows move between them, `aria-orientation="vertical"`). Default 'horizontal' = unchanged. */
4164
+ readonly orientation: import("@angular/core").InputSignal<"vertical" | "horizontal">;
4165
+ protected readonly vertical: () => boolean;
4161
4166
  readonly tabChange: import("@angular/core").OutputEmitterRef<string>;
4162
4167
  /** True while pills are hidden past the start / end edge of the scroll area (drives the fade hints). */
4163
4168
  protected readonly canScrollStart: import("@angular/core").WritableSignal<boolean>;
@@ -4195,6 +4200,11 @@ export declare class PillTabsComponent {
4195
4200
  "required": false;
4196
4201
  "isSignal": true;
4197
4202
  };
4203
+ "orientation": {
4204
+ "alias": "orientation";
4205
+ "required": false;
4206
+ "isSignal": true;
4207
+ };
4198
4208
  }, {
4199
4209
  "tabChange": "tabChange";
4200
4210
  }, never, never, true, never>;
@@ -4758,7 +4768,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
4758
4768
  * `search`, `text`, `none`). Empty (default) = the browser's default for the field, except `type="tel"`, which keeps `tel`.
4759
4769
  * It only picks the keyboard; it does not restrict what can be typed or pasted.
4760
4770
  */
4761
- readonly inputmode: import("@angular/core").InputSignal<"" | "numeric" | "search" | "text" | "none" | "email" | "tel" | "url" | "decimal">;
4771
+ readonly inputmode: import("@angular/core").InputSignal<"" | "none" | "text" | "search" | "email" | "tel" | "url" | "decimal" | "numeric">;
4762
4772
  readonly readonly: import("@angular/core").InputSignal<boolean>;
4763
4773
  readonly hint: import("@angular/core").InputSignal<string>;
4764
4774
  readonly error: import("@angular/core").InputSignal<string>;
@@ -6049,6 +6059,8 @@ export declare class MultiSelectComponent implements ControlValueAccessor {
6049
6059
  registerOnTouched(fn: () => void): void;
6050
6060
  setDisabledState(d: boolean): void;
6051
6061
  protected onDocumentClick(event: Event): void;
6062
+ /** Escape with the list open closes ONLY the list (focus back on the trigger) and is not passed on, so a surrounding side panel / modal stays open. */
6063
+ protected onEscape(event: Event): void;
6052
6064
  protected toggleOpen(): void;
6053
6065
  protected toggleValue(value: string): void;
6054
6066
  protected remove(value: string): void;
@@ -6181,7 +6193,7 @@ export declare class DropdownComponent {
6181
6193
  readonly loader: import("@angular/core").InputSignal<(() => Promise<DropdownItem[]>) | null>;
6182
6194
  readonly active: import("@angular/core").InputSignal<boolean>;
6183
6195
  readonly activeValue: import("@angular/core").InputSignal<string>;
6184
- readonly variant: import("@angular/core").InputSignal<"button" | "badge">;
6196
+ readonly variant: import("@angular/core").InputSignal<"badge" | "button">;
6185
6197
  readonly menuWidth: import("@angular/core").InputSignal<string>;
6186
6198
  /**
6187
6199
  * 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
@@ -6305,6 +6317,94 @@ export declare class DropdownComponent {
6305
6317
  "itemClick": "itemClick";
6306
6318
  }, never, never, true, never>;
6307
6319
  }
6320
+ /** One insertable merge variable. `value` is what `(picked)` emits (e.g. `{{first_name}}`); `group` puts it under a header. */
6321
+ export interface TextTemplateVariable {
6322
+ value: string;
6323
+ label: string;
6324
+ group?: string;
6325
+ }
6326
+ interface Row$1 {
6327
+ kind: 'group' | 'option';
6328
+ key: string;
6329
+ text: string;
6330
+ variable?: TextTemplateVariable;
6331
+ index?: number;
6332
+ }
6333
+ /**
6334
+ * "Insert variable" picker for message templates: a button that opens a searchable list of every merge variable.
6335
+ * Type to filter by name (case and accents ignored), or scroll the list; Enter / click picks one and `(picked)` emits its `value`.
6336
+ * The list is positioned against the viewport (never clipped by a scrolling side panel), opens above the button when there is
6337
+ * no room below, and scrolls inside the room it has.
6338
+ *
6339
+ * <ui-text-template-picker [variables]="variables" (picked)="insert($event)" />
6340
+ */
6341
+ export declare class TextTemplatePickerComponent {
6342
+ readonly variables: import("@angular/core").InputSignal<TextTemplateVariable[]>;
6343
+ readonly label: import("@angular/core").InputSignal<string>;
6344
+ readonly searchPlaceholder: import("@angular/core").InputSignal<string>;
6345
+ readonly disabled: import("@angular/core").InputSignal<boolean>;
6346
+ /** The chosen variable's `value`. The list closes and focus returns to the button. */
6347
+ readonly picked: import("@angular/core").OutputEmitterRef<string>;
6348
+ protected readonly _id: string;
6349
+ protected readonly _open: import("@angular/core").WritableSignal<boolean>;
6350
+ protected readonly _query: import("@angular/core").WritableSignal<string>;
6351
+ protected readonly _active: import("@angular/core").WritableSignal<number>;
6352
+ protected readonly _top: import("@angular/core").WritableSignal<number | null>;
6353
+ protected readonly _bottom: import("@angular/core").WritableSignal<number | null>;
6354
+ protected readonly _left: import("@angular/core").WritableSignal<number>;
6355
+ protected readonly _width: import("@angular/core").WritableSignal<number>;
6356
+ protected readonly _maxHeight: import("@angular/core").WritableSignal<number>;
6357
+ private readonly host;
6358
+ private readonly injector;
6359
+ constructor();
6360
+ private static fold;
6361
+ protected readonly _matches: import("@angular/core").Signal<TextTemplateVariable[]>;
6362
+ /** Display rows: group headers (when variables carry a `group`) followed by their options, each option numbered for keyboard navigation. */
6363
+ protected readonly _rows: import("@angular/core").Signal<Row$1[]>;
6364
+ protected readonly _activeId: import("@angular/core").Signal<string | null>;
6365
+ protected readonly _status: import("@angular/core").Signal<string>;
6366
+ protected toggle(): void;
6367
+ protected openFromKey(event: Event): void;
6368
+ private openList;
6369
+ /** Measures the trigger against the viewport: the list goes below it, or above when the room below is smaller, and never grows past the room it has. */
6370
+ private place;
6371
+ protected onQuery(value: string): void;
6372
+ protected onSearchKey(event: KeyboardEvent): void;
6373
+ protected pick(variable: TextTemplateVariable): void;
6374
+ /** Escape closes only the list (and is not passed on), so a surrounding side panel / modal stays open. */
6375
+ protected onEscape(event: Event): void;
6376
+ private close;
6377
+ private scrollActive;
6378
+ protected onDocumentClick(event: Event): void;
6379
+ /** A fixed list would drift from its button when the page resizes (or scrolls, see onAnyScroll); close it instead. */
6380
+ protected onResize(): void;
6381
+ private readonly onAnyScroll;
6382
+ static ɵfac: i0.ɵɵFactoryDeclaration<TextTemplatePickerComponent, never>;
6383
+ static ɵcmp: i0.ɵɵComponentDeclaration<TextTemplatePickerComponent, "ui-text-template-picker", never, {
6384
+ "variables": {
6385
+ "alias": "variables";
6386
+ "required": false;
6387
+ "isSignal": true;
6388
+ };
6389
+ "label": {
6390
+ "alias": "label";
6391
+ "required": false;
6392
+ "isSignal": true;
6393
+ };
6394
+ "searchPlaceholder": {
6395
+ "alias": "searchPlaceholder";
6396
+ "required": false;
6397
+ "isSignal": true;
6398
+ };
6399
+ "disabled": {
6400
+ "alias": "disabled";
6401
+ "required": false;
6402
+ "isSignal": true;
6403
+ };
6404
+ }, {
6405
+ "picked": "picked";
6406
+ }, never, never, true, never>;
6407
+ }
6308
6408
  /**
6309
6409
  * A real `<form>` for a group of library fields, so the browser (and assistive tech) treats it as one: it is announced as a
6310
6410
  * "form" landmark when it has a name, and pressing Enter in a field submits it through a `ui-button type="submit"`. Apps do not write
@@ -6390,7 +6490,7 @@ export declare class FormSectionComponent {
6390
6490
  }, {}, never, ["*"], true, never>;
6391
6491
  }
6392
6492
  export declare class FormRowComponent {
6393
- readonly cols: import("@angular/core").InputSignal<3 | 1 | 2 | 4>;
6493
+ readonly cols: import("@angular/core").InputSignal<1 | 2 | 3 | 4>;
6394
6494
  static ɵfac: i0.ɵɵFactoryDeclaration<FormRowComponent, never>;
6395
6495
  static ɵcmp: i0.ɵɵComponentDeclaration<FormRowComponent, "ui-form-row", never, {
6396
6496
  "cols": {
@@ -6407,7 +6507,7 @@ export declare class FormRowComponent {
6407
6507
  * child simply takes the full width. Keep a numeric span within the row's `cols` (use `all` for the whole row).
6408
6508
  */
6409
6509
  export declare class FormColSpanDirective {
6410
- readonly uiColSpan: import("@angular/core").InputSignal<"" | "2" | 3 | 2 | "3" | "all">;
6510
+ readonly uiColSpan: import("@angular/core").InputSignal<"" | "2" | "3" | 2 | 3 | "all">;
6411
6511
  protected readonly _class: import("@angular/core").Signal<string>;
6412
6512
  static ɵfac: i0.ɵɵFactoryDeclaration<FormColSpanDirective, never>;
6413
6513
  static ɵdir: i0.ɵɵDirectiveDeclaration<FormColSpanDirective, "[uiColSpan]", never, {
@@ -6501,6 +6601,10 @@ export declare class ListItemComponent {
6501
6601
  protected readonly iconD: () => string | null;
6502
6602
  /** Emitted when the radio/checkbox changes. */
6503
6603
  readonly select: import("@angular/core").OutputEmitterRef<void>;
6604
+ /** A plain interactive row (no radio/checkbox) is itself clickable: click, Enter or Space emit `select`. */
6605
+ protected readonly pressable: () => boolean;
6606
+ protected onRowClick(e: Event): void;
6607
+ protected onRowKey(e: Event): void;
6504
6608
  protected readonly visibleDetails: () => {
6505
6609
  text: string;
6506
6610
  d: string | null;
@@ -8550,6 +8654,7 @@ export declare class DateRangePickerComponent {
8550
8654
  * shows that applied range as the highlighted tab, it does not open an empty From / To card. Clicking the tab reopens it.
8551
8655
  */
8552
8656
  private readonly popoverDismissed;
8657
+ /** `popoverDismissed` is read first on purpose: a linkedSignal is lazy, and its "created closed" start value must be computed before the preset ever becomes custom. */
8553
8658
  protected readonly popoverVisible: import("@angular/core").Signal<boolean>;
8554
8659
  protected readonly popTop: import("@angular/core").WritableSignal<number>;
8555
8660
  protected readonly popRight: import("@angular/core").WritableSignal<number>;
@@ -9362,7 +9467,7 @@ export declare class DetailCardComponent {
9362
9467
  /** true (default) = the title is displayed in capitals (CSS only); false = shown as written. The text, aria-label and heading name are never changed. */
9363
9468
  readonly uppercaseTitle: import("@angular/core").InputSignal<boolean>;
9364
9469
  /** 1-6 makes the title a real heading for screen readers (role=heading, aria-level); null keeps it plain text. */
9365
- readonly headingLevel: import("@angular/core").InputSignal<3 | 1 | 2 | 6 | 4 | 5 | null>;
9470
+ readonly headingLevel: import("@angular/core").InputSignal<1 | 2 | 3 | 4 | 5 | 6 | null>;
9366
9471
  /** Optional id for the title text; the card is then labelled by it. Without it the title is the card's aria-label. */
9367
9472
  readonly titleId: import("@angular/core").InputSignal<string>;
9368
9473
  /** Accessible name of the card when the header gives none (no header, or no title). A visible title wins; blank = no name. */