@forgeroute/ui 0.4.46 → 0.4.47

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.46",
3
+ "version": "0.4.47",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=22.0.0",
6
6
  "@angular/core": ">=22.0.0",
@@ -1266,6 +1266,8 @@ export declare function stripeConnectNotice(outcome: StripeConnectOutcome): {
1266
1266
  */
1267
1267
  export declare class StripeConnectComponent {
1268
1268
  private readonly destroyRef;
1269
+ private readonly injector;
1270
+ private readonly host;
1269
1271
  /** The call that creates the organization's Stripe account (or resumes it) and answers its id and the onboarding address. Needed for `start()`. */
1270
1272
  readonly createAccount: import("@angular/core").InputSignal<(() => Observable<StripeConnectAccount>) | null>;
1271
1273
  /** The call that reads the account's state. Needed for `check()`, `resume()` and `refreshOnReturn`. */
@@ -1297,6 +1299,13 @@ export declare class StripeConnectComponent {
1297
1299
  /** How the current tab is sent to Stripe when the browser refused the new tab (default: `window.location.href = url`); a host can route it through its own method. */
1298
1300
  readonly navigateTab: import("@angular/core").InputSignal<((url: string) => void) | null>;
1299
1301
  protected readonly visible: import("@angular/core").Signal<boolean>;
1302
+ /** Which screen the card shows. */
1303
+ protected readonly state: import("@angular/core").Signal<"none" | "complete" | "verifying" | "incomplete">;
1304
+ /** What the persistent status region says: the current state, plus "Loading." while a request runs. Empty while nothing is shown. */
1305
+ protected readonly liveText: import("@angular/core").Signal<string>;
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). */
1307
+ private acted;
1308
+ private lastState;
1300
1309
  private readonly flow;
1301
1310
  constructor();
1302
1311
  /** Creates (or resumes) the account and opens Stripe's onboarding page in a new tab. */
@@ -1305,6 +1314,8 @@ export declare class StripeConnectComponent {
1305
1314
  check(): void;
1306
1315
  /** "Complete Setup": reads the state and opens the onboarding address of an unfinished account in a new tab. */
1307
1316
  resume(): void;
1317
+ /** The flow will really send a request (the host gave the call, nothing is running, the card is not read-only). */
1318
+ private canRun;
1308
1319
  /** Opens the Stripe dashboard in a new tab. */
1309
1320
  openDashboard(): void;
1310
1321
  /** The browser refused the new tab: Stripe opens in this one (through the host's `navigateTab` when it gave one). */
@@ -1088,7 +1088,7 @@ export declare class SelectComponent implements ControlValueAccessor, Validator,
1088
1088
  readonly error: import("@angular/core").InputSignal<string>;
1089
1089
  /** Reveal the built-in error messages now (e.g. after a failed Save click), without waiting for blur. */
1090
1090
  readonly showErrors: import("@angular/core").InputSignal<boolean>;
1091
- readonly size: import("@angular/core").InputSignal<"default" | "sm">;
1091
+ readonly size: import("@angular/core").InputSignal<"sm" | "default">;
1092
1092
  readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
1093
1093
  private readonly _cvaDisabled;
1094
1094
  protected readonly disabled: import("@angular/core").Signal<boolean>;
@@ -1264,6 +1264,10 @@ export declare class ImportExportComponent {
1264
1264
  readonly finished: import("@angular/core").OutputEmitterRef<ImportSubmitResult>;
1265
1265
  readonly imported: import("@angular/core").OutputEmitterRef<void>;
1266
1266
  config: ImportExportConfig;
1267
+ private static nextUid;
1268
+ /** Unique prefix for the ids this window links with aria-describedby / aria-labelledby. */
1269
+ readonly uid: string;
1270
+ private readonly resultBox;
1267
1271
  private readonly http;
1268
1272
  /** API root from FORGEROUTE_CONFIG (e.g. a cross-origin prod API); falls back to same-origin `/api`. */
1269
1273
  private readonly apiBase;
@@ -1293,6 +1297,16 @@ export declare class ImportExportComponent {
1293
1297
  warnings: ImportError[];
1294
1298
  } | null;
1295
1299
  get stepIndex(): number;
1300
+ /** The progress list: one entry per step with its number, label and whether it is the current / a finished step. */
1301
+ get stepItems(): {
1302
+ key: ImportStep;
1303
+ num: number;
1304
+ label: string;
1305
+ current: boolean;
1306
+ done: boolean;
1307
+ }[];
1308
+ /** What the persistent status region says once the import has finished (empty before). */
1309
+ get resultAnnouncement(): string;
1296
1310
  get modalTitle(): string;
1297
1311
  openImport(): void;
1298
1312
  onSourceSelected(value: string): void;
@@ -1312,6 +1326,8 @@ export declare class ImportExportComponent {
1312
1326
  goToPreview(): void;
1313
1327
  get mappedFields(): ImportFieldDef[];
1314
1328
  get previewRows(): Record<string, string>[];
1329
+ /** Moves focus to the result summary (the button that had it is gone), so keyboard and screen reader users land on the outcome. */
1330
+ private focusResult;
1315
1331
  private stopImportTimer;
1316
1332
  submitImport(): void;
1317
1333
  static ɵfac: i0.ɵɵFactoryDeclaration<ImportExportComponent, never>;
@@ -2206,7 +2222,7 @@ export declare class ModalComponent implements OnInit, OnDestroy {
2206
2222
  readonly title: import("@angular/core").InputSignal<string>;
2207
2223
  readonly description: import("@angular/core").InputSignal<string>;
2208
2224
  readonly maxWidth: import("@angular/core").InputSignal<string>;
2209
- readonly bodyOverflow: import("@angular/core").InputSignal<"hidden" | "auto" | "visible">;
2225
+ readonly bodyOverflow: import("@angular/core").InputSignal<"auto" | "hidden" | "visible">;
2210
2226
  /** `data-testid` of the dialog element itself (the host `<ui-modal>` is always in the page, the dialog only while open). None when empty. */
2211
2227
  readonly dialogTestId: import("@angular/core").InputSignal<string>;
2212
2228
  /** Hides the header X button (e.g. while a request is running). Escape and a backdrop click still close unless `closable` is false. */
@@ -2590,7 +2606,7 @@ export declare class AudioPlayerComponent {
2590
2606
  /** Accessible name of the player. */
2591
2607
  readonly ariaLabel: import("@angular/core").InputSignal<string>;
2592
2608
  /** How much to load before play: 'metadata' (default), 'auto' or 'none'. */
2593
- readonly preload: import("@angular/core").InputSignal<"none" | "auto" | "metadata">;
2609
+ readonly preload: import("@angular/core").InputSignal<"auto" | "none" | "metadata">;
2594
2610
  /** Fires when the browser can't load or decode the source. */
2595
2611
  readonly playbackError: import("@angular/core").OutputEmitterRef<void>;
2596
2612
  protected readonly failed: import("@angular/core").WritableSignal<boolean>;
@@ -2844,7 +2860,7 @@ export declare class CheckboxComponent implements ControlValueAccessor, Validato
2844
2860
  * 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.
2845
2861
  * Default null: plain label text, exactly as before. Single mode only.
2846
2862
  */
2847
- readonly headingLevel: import("@angular/core").InputSignal<1 | 2 | 3 | 4 | 5 | 6 | null>;
2863
+ readonly headingLevel: import("@angular/core").InputSignal<1 | 4 | 2 | 3 | 5 | 6 | null>;
2848
2864
  readonly indeterminate: import("@angular/core").InputSignal<boolean>;
2849
2865
  readonly checked: import("@angular/core").ModelSignal<boolean>;
2850
2866
  /**
@@ -3869,7 +3885,7 @@ export declare class ButtonComponent {
3869
3885
  * `ghost-start`: a ghost button for list / section toggles - a full-width row with its content aligned to the start, transparent
3870
3886
  * background, hover tint and the normal focus ring. Pair it with `ariaExpanded` / `ariaPressed`; the label may contain a heading element.
3871
3887
  */
3872
- readonly variant: import("@angular/core").InputSignal<"primary" | "secondary" | "danger" | "warning" | "link" | "ghost" | "ghost-start" | "tab" | "icon" | "icon-danger">;
3888
+ readonly variant: import("@angular/core").InputSignal<"link" | "primary" | "secondary" | "danger" | "warning" | "ghost" | "ghost-start" | "tab" | "icon" | "icon-danger">;
3873
3889
  /** 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`). */
3874
3890
  readonly routerLink: import("@angular/core").InputSignal<string | readonly unknown[] | null>;
3875
3891
  /** Query params of the `routerLink` (e.g. `{ section: 'deal-defaults' }`). */
@@ -3915,7 +3931,7 @@ export declare class ButtonComponent {
3915
3931
  readonly color: import("@angular/core").InputSignal<string | undefined>;
3916
3932
  readonly active: import("@angular/core").InputSignal<boolean>;
3917
3933
  readonly size: import("@angular/core").InputSignal<"sm" | "md" | "lg" | "xs">;
3918
- readonly type: import("@angular/core").InputSignal<"reset" | "submit" | "button">;
3934
+ readonly type: import("@angular/core").InputSignal<"button" | "reset" | "submit">;
3919
3935
  readonly disabled: import("@angular/core").InputSignal<boolean>;
3920
3936
  readonly loading: import("@angular/core").InputSignal<boolean>;
3921
3937
  readonly fullWidth: import("@angular/core").InputSignal<boolean>;
@@ -4347,7 +4363,7 @@ export declare class BulkMessagePanelComponent {
4347
4363
  readonly sending: import("@angular/core").InputSignal<boolean>;
4348
4364
  readonly closed: import("@angular/core").OutputEmitterRef<void>;
4349
4365
  readonly send: import("@angular/core").OutputEmitterRef<BulkMessageSendEvent>;
4350
- readonly channel: import("@angular/core").WritableSignal<"text" | "email">;
4366
+ readonly channel: import("@angular/core").WritableSignal<"email" | "text">;
4351
4367
  private readonly _subject;
4352
4368
  private readonly _body;
4353
4369
  get subject(): string;
@@ -4402,7 +4418,7 @@ export declare class ImportSourceGridComponent {
4402
4418
  /** The `value` of the picked source (highlighted). `tile` only: the `card` appearance does not keep a selection. */
4403
4419
  readonly selected: import("@angular/core").InputSignal<string>;
4404
4420
  /** `tile`: the compact buttons of the import window. `card`: one `ui-detail-card` per source with its own select button (used on a page). */
4405
- readonly appearance: import("@angular/core").InputSignal<"card" | "tile">;
4421
+ readonly appearance: import("@angular/core").InputSignal<"tile" | "card">;
4406
4422
  /** `card`: disables every card's button (for example while the page is saving). */
4407
4423
  readonly disabled: import("@angular/core").InputSignal<boolean>;
4408
4424
  /** `card`: the text of each card's button. */
@@ -4711,7 +4727,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
4711
4727
  readonly passwordRequirements: import("@angular/core").InputSignal<boolean>;
4712
4728
  /** Rules for `passwordRequirements`; default = the library's five rules (8+ characters, upper, lower, digit, special). */
4713
4729
  readonly passwordRules: import("@angular/core").InputSignal<readonly PasswordRule[] | undefined>;
4714
- readonly type: import("@angular/core").InputSignal<"number" | "text" | "email" | "tel" | "password" | "url">;
4730
+ readonly type: import("@angular/core").InputSignal<"number" | "email" | "text" | "password" | "tel" | "url">;
4715
4731
  readonly maxlength: import("@angular/core").InputSignal<number | undefined>;
4716
4732
  readonly required: import("@angular/core").InputSignal<boolean>;
4717
4733
  readonly autocomplete: import("@angular/core").InputSignal<string>;
@@ -4720,7 +4736,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
4720
4736
  * `search`, `text`, `none`). Empty (default) = the browser's default for the field, except `type="tel"`, which keeps `tel`.
4721
4737
  * It only picks the keyboard; it does not restrict what can be typed or pasted.
4722
4738
  */
4723
- readonly inputmode: import("@angular/core").InputSignal<"" | "none" | "text" | "search" | "email" | "tel" | "url" | "decimal" | "numeric">;
4739
+ readonly inputmode: import("@angular/core").InputSignal<"" | "email" | "search" | "none" | "text" | "tel" | "url" | "decimal" | "numeric">;
4724
4740
  readonly readonly: import("@angular/core").InputSignal<boolean>;
4725
4741
  readonly hint: import("@angular/core").InputSignal<string>;
4726
4742
  readonly error: import("@angular/core").InputSignal<string>;
@@ -4784,7 +4800,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
4784
4800
  protected readonly _stepAttr: import("@angular/core").Signal<string | null>;
4785
4801
  protected readonly _revealable: import("@angular/core").Signal<boolean>;
4786
4802
  protected readonly _shown: import("@angular/core").WritableSignal<boolean>;
4787
- protected readonly _inputType: import("@angular/core").Signal<"number" | "text" | "email" | "tel" | "password" | "url">;
4803
+ protected readonly _inputType: import("@angular/core").Signal<"number" | "email" | "text" | "password" | "tel" | "url">;
4788
4804
  protected readonly _eyePath: string;
4789
4805
  protected readonly _eyeOffPath: string;
4790
4806
  protected readonly _showRequirements: import("@angular/core").Signal<boolean>;
@@ -4816,6 +4832,12 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
4816
4832
  registerOnTouched(fn: () => void): void;
4817
4833
  setDisabledState(d: boolean): void;
4818
4834
  protected onInput(event: Event): void;
4835
+ /**
4836
+ * Position in `formatted` for a caret that was at `caret` in `raw`: right after the same number of digits (the leading country-code 1 of an
4837
+ * 11-digit number is dropped by the formatting). When the character before the caret was a separator, the caret also moves over the separators
4838
+ * that follow that digit, so deleting the first digit of a group does not throw the caret back in front of ") ".
4839
+ */
4840
+ private static _caretAfterDigits;
4819
4841
  /** Typed text -> number, or null when blank / not a finite number. */
4820
4842
  private static _parse;
4821
4843
  protected onFocus(): void;
@@ -6136,7 +6158,7 @@ export declare class DropdownComponent {
6136
6158
  readonly loader: import("@angular/core").InputSignal<(() => Promise<DropdownItem[]>) | null>;
6137
6159
  readonly active: import("@angular/core").InputSignal<boolean>;
6138
6160
  readonly activeValue: import("@angular/core").InputSignal<string>;
6139
- readonly variant: import("@angular/core").InputSignal<"badge" | "button">;
6161
+ readonly variant: import("@angular/core").InputSignal<"button" | "badge">;
6140
6162
  readonly menuWidth: import("@angular/core").InputSignal<string>;
6141
6163
  /**
6142
6164
  * Accessible name. Set it when the trigger has no meaningful visible text. Applied as `aria-label` on the
@@ -6335,7 +6357,7 @@ export declare class FormSectionComponent {
6335
6357
  }, {}, never, ["*"], true, never>;
6336
6358
  }
6337
6359
  export declare class FormRowComponent {
6338
- readonly cols: import("@angular/core").InputSignal<1 | 2 | 3 | 4>;
6360
+ readonly cols: import("@angular/core").InputSignal<1 | 4 | 2 | 3>;
6339
6361
  static ɵfac: i0.ɵɵFactoryDeclaration<FormRowComponent, never>;
6340
6362
  static ɵcmp: i0.ɵɵComponentDeclaration<FormRowComponent, "ui-form-row", never, {
6341
6363
  "cols": {
@@ -6352,7 +6374,7 @@ export declare class FormRowComponent {
6352
6374
  * child simply takes the full width. Keep a numeric span within the row's `cols` (use `all` for the whole row).
6353
6375
  */
6354
6376
  export declare class FormColSpanDirective {
6355
- readonly uiColSpan: import("@angular/core").InputSignal<"" | "2" | "3" | 2 | 3 | "all">;
6377
+ readonly uiColSpan: import("@angular/core").InputSignal<"" | 2 | 3 | "2" | "3" | "all">;
6356
6378
  protected readonly _class: import("@angular/core").Signal<string>;
6357
6379
  static ɵfac: i0.ɵɵFactoryDeclaration<FormColSpanDirective, never>;
6358
6380
  static ɵdir: i0.ɵɵDirectiveDeclaration<FormColSpanDirective, "[uiColSpan]", never, {
@@ -7379,7 +7401,7 @@ export declare class ChipGroupComponent {
7379
7401
  readonly spaceAbove: import("@angular/core").InputSignal<"none" | "sm" | "md">;
7380
7402
  /** Space below the chip group. */
7381
7403
  readonly spaceBelow: import("@angular/core").InputSignal<"none" | "sm" | "md">;
7382
- protected readonly _gap: import("@angular/core").Signal<"6px" | "12px" | "8px">;
7404
+ protected readonly _gap: import("@angular/core").Signal<"8px" | "6px" | "12px">;
7383
7405
  protected readonly _spaceAbove: import("@angular/core").Signal<"0" | "6px" | "12px">;
7384
7406
  protected readonly _spaceBelow: import("@angular/core").Signal<"0" | "6px" | "12px">;
7385
7407
  static ɵfac: i0.ɵɵFactoryDeclaration<ChipGroupComponent, never>;
@@ -9293,7 +9315,7 @@ export declare class DetailCardComponent {
9293
9315
  /** true (default) = the title is displayed in capitals (CSS only); false = shown as written. The text, aria-label and heading name are never changed. */
9294
9316
  readonly uppercaseTitle: import("@angular/core").InputSignal<boolean>;
9295
9317
  /** 1-6 makes the title a real heading for screen readers (role=heading, aria-level); null keeps it plain text. */
9296
- readonly headingLevel: import("@angular/core").InputSignal<1 | 2 | 3 | 4 | 5 | 6 | null>;
9318
+ readonly headingLevel: import("@angular/core").InputSignal<1 | 4 | 2 | 3 | 5 | 6 | null>;
9297
9319
  /** Optional id for the title text; the card is then labelled by it. Without it the title is the card's aria-label. */
9298
9320
  readonly titleId: import("@angular/core").InputSignal<string>;
9299
9321
  /** Accessible name of the card when the header gives none (no header, or no title). A visible title wins; blank = no name. */
@@ -11449,6 +11471,8 @@ export interface SetupIntegration {
11449
11471
  export interface SetupWizardTexts {
11450
11472
  brand: string;
11451
11473
  stepperLabel: string;
11474
+ /** Accessible name of the sidebar landmark (default "Setup steps"). Separate from `brand`, which may be empty or a logo-only heading. */
11475
+ asideLabel: string;
11452
11476
  progress: (done: number, total: number) => string;
11453
11477
  back: string;
11454
11478
  skip: string;
@@ -11480,6 +11504,8 @@ export interface SetupWizardTexts {
11480
11504
  summarySkipped: string;
11481
11505
  summaryPending: string;
11482
11506
  areaCode: string;
11507
+ /** Helper text under the area-code field; also what a disabled Connect button there is described by. */
11508
+ areaCodeHint: string;
11483
11509
  connectIntegrationFailed: (title: string) => string;
11484
11510
  }
11485
11511
  /** An import step: the library import window (CSV / pasted data / competitor sources) with the step's own words around it. */
@@ -11519,6 +11545,17 @@ export interface SetupStep {
11519
11545
  save?: () => Observable<unknown> | Promise<unknown> | void;
11520
11546
  /** `custom` and `integrations`: false disables "Save & Continue" (read on every render, so it can follow signals). */
11521
11547
  canContinue?: () => boolean;
11548
+ /**
11549
+ * `custom`: id of an element in the app's own step content that explains why "Save & Continue" is off. While `canContinue` is false the button
11550
+ * carries `aria-describedby="<id>"`, so a screen reader announces the reason with the disabled button (the attribute is absent otherwise).
11551
+ */
11552
+ continueHintId?: string;
11553
+ /**
11554
+ * `custom` and `integrations`: read AFTER the step's hook succeeded. When it returns true, "Save & Continue" still runs the hook and moves on, but the step is NOT
11555
+ * marked complete: the progress count leaves it out, the side nav keeps it `upcoming` and the summary shows it as pending (not Done, not Skipped). Use it when the
11556
+ * user has done their part but the result is not usable yet (e.g. a bank account that still has to be verified). Absent / false: the step is marked complete as usual.
11557
+ */
11558
+ continueWithoutComplete?: () => boolean;
11522
11559
  /** `custom`: text of the continue button (default "Save & Continue"). */
11523
11560
  saveLabel?: string;
11524
11561
  /**
@@ -11635,6 +11672,8 @@ export declare const SETUP_DONE_KEY = "done";
11635
11672
  * - `kind: 'integrations'` steps list integrations with Connect / Reconnect — QuickBooks, Twilio, Slack, email and calendar come ready made
11636
11673
  * (`SETUP_INTEGRATIONS` / `setupIntegrations(...)`); an app can add its own;
11637
11674
  * - `kind: 'custom'` steps show the app's own content (`<ng-template uiSetupStep="key">`) with the step's `save` / `canContinue` hooks.
11675
+ * `continueHintId` points the disabled Save & Continue at the app's own hint element (`aria-describedby`); `continueWithoutComplete` lets a step continue
11676
+ * without being marked complete (progress and side nav leave it out, the summary shows it as Pending).
11638
11677
  *
11639
11678
  * <ui-setup-wizard [steps]="steps()" [texts]="{ brand: 'My App Setup' }" (finished)="goToDashboard()" (exited)="goToDashboard()">
11640
11679
  * <ng-template uiSetupStep="profile"> … </ng-template>
@@ -11652,6 +11691,8 @@ export declare class SetupWizardComponent {
11652
11691
  /** An import step with `requireImport` keeps Continue off until something came in (a CSV import or `markCompleted`, e.g. a live sync). */
11653
11692
  /** An integrations step with `requireConnection` keeps Save & Continue off until at least one of its integrations is connected (Skip stays the way past). */
11654
11693
  protected readonly connectBlocked: import("@angular/core").Signal<boolean>;
11694
+ /** A custom step whose Save & Continue is off (`canContinue` false) and that names its hint element (`continueHintId`): the button is described by it. */
11695
+ protected customHintId(): string;
11655
11696
  protected readonly importBlocked: import("@angular/core").Signal<boolean>;
11656
11697
  /** The step's own two parts (`splitLayout`) show as two tabs, one card at a time; this is the open one (it starts on the app's part on every visit). */
11657
11698
  protected readonly splitTab: import("@angular/core").WritableSignal<"main" | "extra">;
@@ -11675,6 +11716,7 @@ export declare class SetupWizardComponent {
11675
11716
  protected readonly stepTemplates: import("@angular/core").Signal<readonly SetupWizardStepDirective[]>;
11676
11717
  protected readonly headerTemplates: import("@angular/core").Signal<readonly SetupWizardStepHeaderDirective[]>;
11677
11718
  private readonly injector;
11719
+ private readonly host;
11678
11720
  private readonly stepTitle;
11679
11721
  protected readonly importers: import("@angular/core").Signal<readonly ImportExportComponent[]>;
11680
11722
  protected readonly t: import("@angular/core").Signal<SetupWizardTexts>;
@@ -11733,6 +11775,8 @@ export declare class SetupWizardComponent {
11733
11775
  private markCompleted;
11734
11776
  /** "Save & Continue" of a custom or integrations step: runs the step's hook, then moves on. */
11735
11777
  saveAndContinue(): Promise<void>;
11778
+ /** `continueWithoutComplete` of a step whose hook just succeeded. A hook that throws counts as false (the save already ran: it is not reported as a failed save). */
11779
+ private withholdsMark;
11736
11780
  private run;
11737
11781
  /** The message to show for a failure: the server's own `{ message }` (or a thrown error's message); never the HTTP client's technical text. */
11738
11782
  private messageOf;