@forgeroute/ui 0.4.46 → 0.4.48

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.48",
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,12 @@ 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;
1271
+ /** The container of the step on screen (Source / Upload / Map Columns / Preview): focused when the step changes, because the control the user pressed is gone. */
1272
+ private readonly stepBox;
1267
1273
  private readonly http;
1268
1274
  /** API root from FORGEROUTE_CONFIG (e.g. a cross-origin prod API); falls back to same-origin `/api`. */
1269
1275
  private readonly apiBase;
@@ -1293,6 +1299,16 @@ export declare class ImportExportComponent {
1293
1299
  warnings: ImportError[];
1294
1300
  } | null;
1295
1301
  get stepIndex(): number;
1302
+ /** The progress list: one entry per step with its number, label and whether it is the current / a finished step. */
1303
+ get stepItems(): {
1304
+ key: ImportStep;
1305
+ num: number;
1306
+ label: string;
1307
+ current: boolean;
1308
+ done: boolean;
1309
+ }[];
1310
+ /** What the persistent status region says once the import has finished (empty before). */
1311
+ get resultAnnouncement(): string;
1296
1312
  get modalTitle(): string;
1297
1313
  openImport(): void;
1298
1314
  onSourceSelected(value: string): void;
@@ -1312,6 +1328,10 @@ export declare class ImportExportComponent {
1312
1328
  goToPreview(): void;
1313
1329
  get mappedFields(): ImportFieldDef[];
1314
1330
  get previewRows(): Record<string, string>[];
1331
+ /** Shows another step and moves focus to its container (the pressed button / focused file input was removed from the page). */
1332
+ goTo(step: ImportStep): void;
1333
+ /** Moves focus to the result summary (the button that had it is gone), so keyboard and screen reader users land on the outcome. */
1334
+ private focusResult;
1315
1335
  private stopImportTimer;
1316
1336
  submitImport(): void;
1317
1337
  static ɵfac: i0.ɵɵFactoryDeclaration<ImportExportComponent, never>;
@@ -2206,7 +2226,7 @@ export declare class ModalComponent implements OnInit, OnDestroy {
2206
2226
  readonly title: import("@angular/core").InputSignal<string>;
2207
2227
  readonly description: import("@angular/core").InputSignal<string>;
2208
2228
  readonly maxWidth: import("@angular/core").InputSignal<string>;
2209
- readonly bodyOverflow: import("@angular/core").InputSignal<"hidden" | "auto" | "visible">;
2229
+ readonly bodyOverflow: import("@angular/core").InputSignal<"hidden" | "visible" | "auto">;
2210
2230
  /** `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
2231
  readonly dialogTestId: import("@angular/core").InputSignal<string>;
2212
2232
  /** 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 +2610,7 @@ export declare class AudioPlayerComponent {
2590
2610
  /** Accessible name of the player. */
2591
2611
  readonly ariaLabel: import("@angular/core").InputSignal<string>;
2592
2612
  /** How much to load before play: 'metadata' (default), 'auto' or 'none'. */
2593
- readonly preload: import("@angular/core").InputSignal<"none" | "auto" | "metadata">;
2613
+ readonly preload: import("@angular/core").InputSignal<"none" | "metadata" | "auto">;
2594
2614
  /** Fires when the browser can't load or decode the source. */
2595
2615
  readonly playbackError: import("@angular/core").OutputEmitterRef<void>;
2596
2616
  protected readonly failed: import("@angular/core").WritableSignal<boolean>;
@@ -2844,7 +2864,7 @@ export declare class CheckboxComponent implements ControlValueAccessor, Validato
2844
2864
  * 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
2865
  * Default null: plain label text, exactly as before. Single mode only.
2846
2866
  */
2847
- readonly headingLevel: import("@angular/core").InputSignal<1 | 2 | 3 | 4 | 5 | 6 | null>;
2867
+ readonly headingLevel: import("@angular/core").InputSignal<1 | 2 | 3 | 5 | 6 | 4 | null>;
2848
2868
  readonly indeterminate: import("@angular/core").InputSignal<boolean>;
2849
2869
  readonly checked: import("@angular/core").ModelSignal<boolean>;
2850
2870
  /**
@@ -3869,7 +3889,7 @@ export declare class ButtonComponent {
3869
3889
  * `ghost-start`: a ghost button for list / section toggles - a full-width row with its content aligned to the start, transparent
3870
3890
  * background, hover tint and the normal focus ring. Pair it with `ariaExpanded` / `ariaPressed`; the label may contain a heading element.
3871
3891
  */
3872
- readonly variant: import("@angular/core").InputSignal<"primary" | "secondary" | "danger" | "warning" | "link" | "ghost" | "ghost-start" | "tab" | "icon" | "icon-danger">;
3892
+ readonly variant: import("@angular/core").InputSignal<"link" | "primary" | "secondary" | "danger" | "warning" | "ghost" | "ghost-start" | "tab" | "icon" | "icon-danger">;
3873
3893
  /** 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
3894
  readonly routerLink: import("@angular/core").InputSignal<string | readonly unknown[] | null>;
3875
3895
  /** Query params of the `routerLink` (e.g. `{ section: 'deal-defaults' }`). */
@@ -3914,7 +3934,7 @@ export declare class ButtonComponent {
3914
3934
  private readonly _narrow;
3915
3935
  readonly color: import("@angular/core").InputSignal<string | undefined>;
3916
3936
  readonly active: import("@angular/core").InputSignal<boolean>;
3917
- readonly size: import("@angular/core").InputSignal<"sm" | "md" | "lg" | "xs">;
3937
+ readonly size: import("@angular/core").InputSignal<"sm" | "md" | "xs" | "lg">;
3918
3938
  readonly type: import("@angular/core").InputSignal<"reset" | "submit" | "button">;
3919
3939
  readonly disabled: import("@angular/core").InputSignal<boolean>;
3920
3940
  readonly loading: import("@angular/core").InputSignal<boolean>;
@@ -4060,6 +4080,10 @@ export interface ToggleBadgeAction {
4060
4080
  * Pill that toggles on / off. Optional `actions` put small icon buttons INSIDE the pill, after the label and a divider, each with its own
4061
4081
  * tooltip; the label button and the icon buttons are separate buttons (never nested). Clicking an icon button emits `(action)` with its id and
4062
4082
  * never `(toggle)`. Content projected into the component (an icon) goes before the label, as before.
4083
+ *
4084
+ * Accessibility: the label button is a toggle button, so it carries `aria-pressed` (true while `active`); on touch devices
4085
+ * (`pointer: coarse`) its hit area, and each icon button's, is 44px (an invisible overlay; it can reach into a neighbouring badge when the
4086
+ * host's gap between badges is smaller than the overlay, see docs/ui-timeline-and-small-additions.md).
4063
4087
  */
4064
4088
  export declare class ToggleBadgeComponent {
4065
4089
  readonly label: import("@angular/core").InputSignal<string>;
@@ -4125,6 +4149,8 @@ export declare class PillTabsComponent {
4125
4149
  /** Accessible name for the tab list (e.g. 'Reporting period'). Omit to leave it unnamed. */
4126
4150
  readonly ariaLabel: import("@angular/core").InputSignal<string | null>;
4127
4151
  readonly name: import("@angular/core").InputSignal<string>;
4152
+ /** 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. */
4153
+ readonly noWrap: import("@angular/core").InputSignal<boolean>;
4128
4154
  readonly tabChange: import("@angular/core").OutputEmitterRef<string>;
4129
4155
  /** True while pills are hidden past the start / end edge of the scroll area (drives the fade hints). */
4130
4156
  protected readonly canScrollStart: import("@angular/core").WritableSignal<boolean>;
@@ -4157,6 +4183,11 @@ export declare class PillTabsComponent {
4157
4183
  "required": false;
4158
4184
  "isSignal": true;
4159
4185
  };
4186
+ "noWrap": {
4187
+ "alias": "noWrap";
4188
+ "required": false;
4189
+ "isSignal": true;
4190
+ };
4160
4191
  }, {
4161
4192
  "tabChange": "tabChange";
4162
4193
  }, never, never, true, never>;
@@ -4720,7 +4751,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
4720
4751
  * `search`, `text`, `none`). Empty (default) = the browser's default for the field, except `type="tel"`, which keeps `tel`.
4721
4752
  * It only picks the keyboard; it does not restrict what can be typed or pasted.
4722
4753
  */
4723
- readonly inputmode: import("@angular/core").InputSignal<"" | "none" | "text" | "search" | "email" | "tel" | "url" | "decimal" | "numeric">;
4754
+ readonly inputmode: import("@angular/core").InputSignal<"" | "text" | "search" | "none" | "email" | "numeric" | "tel" | "url" | "decimal">;
4724
4755
  readonly readonly: import("@angular/core").InputSignal<boolean>;
4725
4756
  readonly hint: import("@angular/core").InputSignal<string>;
4726
4757
  readonly error: import("@angular/core").InputSignal<string>;
@@ -4816,6 +4847,12 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
4816
4847
  registerOnTouched(fn: () => void): void;
4817
4848
  setDisabledState(d: boolean): void;
4818
4849
  protected onInput(event: Event): void;
4850
+ /**
4851
+ * 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
4852
+ * 11-digit number is dropped by the formatting). When the character before the caret was a separator, the caret also moves over the separators
4853
+ * that follow that digit, so deleting the first digit of a group does not throw the caret back in front of ") ".
4854
+ */
4855
+ private static _caretAfterDigits;
4819
4856
  /** Typed text -> number, or null when blank / not a finite number. */
4820
4857
  private static _parse;
4821
4858
  protected onFocus(): void;
@@ -6138,6 +6175,11 @@ export declare class DropdownComponent {
6138
6175
  readonly activeValue: import("@angular/core").InputSignal<string>;
6139
6176
  readonly variant: import("@angular/core").InputSignal<"badge" | "button">;
6140
6177
  readonly menuWidth: import("@angular/core").InputSignal<string>;
6178
+ /**
6179
+ * 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
6180
+ * width whatever label is selected (never wider than its container) and its label and chevron sit at the two ends.
6181
+ */
6182
+ readonly width: import("@angular/core").InputSignal<string>;
6141
6183
  /**
6142
6184
  * Accessible name. Set it when the trigger has no meaningful visible text. Applied as `aria-label` on the
6143
6185
  * trigger and on the menu; when empty (default) no `aria-label` is rendered, the trigger is named by its
@@ -6236,6 +6278,11 @@ export declare class DropdownComponent {
6236
6278
  "required": false;
6237
6279
  "isSignal": true;
6238
6280
  };
6281
+ "width": {
6282
+ "alias": "width";
6283
+ "required": false;
6284
+ "isSignal": true;
6285
+ };
6239
6286
  "ariaLabel": {
6240
6287
  "alias": "ariaLabel";
6241
6288
  "required": false;
@@ -6352,7 +6399,7 @@ export declare class FormRowComponent {
6352
6399
  * child simply takes the full width. Keep a numeric span within the row's `cols` (use `all` for the whole row).
6353
6400
  */
6354
6401
  export declare class FormColSpanDirective {
6355
- readonly uiColSpan: import("@angular/core").InputSignal<"" | "2" | "3" | 2 | 3 | "all">;
6402
+ readonly uiColSpan: import("@angular/core").InputSignal<"" | 2 | 3 | "2" | "3" | "all">;
6356
6403
  protected readonly _class: import("@angular/core").Signal<string>;
6357
6404
  static ɵfac: i0.ɵɵFactoryDeclaration<FormColSpanDirective, never>;
6358
6405
  static ɵdir: i0.ɵɵDirectiveDeclaration<FormColSpanDirective, "[uiColSpan]", never, {
@@ -7379,7 +7426,7 @@ export declare class ChipGroupComponent {
7379
7426
  readonly spaceAbove: import("@angular/core").InputSignal<"none" | "sm" | "md">;
7380
7427
  /** Space below the chip group. */
7381
7428
  readonly spaceBelow: import("@angular/core").InputSignal<"none" | "sm" | "md">;
7382
- protected readonly _gap: import("@angular/core").Signal<"6px" | "12px" | "8px">;
7429
+ protected readonly _gap: import("@angular/core").Signal<"8px" | "6px" | "12px">;
7383
7430
  protected readonly _spaceAbove: import("@angular/core").Signal<"0" | "6px" | "12px">;
7384
7431
  protected readonly _spaceBelow: import("@angular/core").Signal<"0" | "6px" | "12px">;
7385
7432
  static ɵfac: i0.ɵɵFactoryDeclaration<ChipGroupComponent, never>;
@@ -9293,7 +9340,7 @@ export declare class DetailCardComponent {
9293
9340
  /** 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
9341
  readonly uppercaseTitle: import("@angular/core").InputSignal<boolean>;
9295
9342
  /** 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>;
9343
+ readonly headingLevel: import("@angular/core").InputSignal<1 | 2 | 3 | 5 | 6 | 4 | null>;
9297
9344
  /** Optional id for the title text; the card is then labelled by it. Without it the title is the card's aria-label. */
9298
9345
  readonly titleId: import("@angular/core").InputSignal<string>;
9299
9346
  /** Accessible name of the card when the header gives none (no header, or no title). A visible title wins; blank = no name. */
@@ -10210,6 +10257,12 @@ export type ColumnsAlign = 'start' | 'center' | 'stretch';
10210
10257
  * - `collapseAt`: sm (480px) | md (768px) | lg (1024px) | never. Below that viewport width the columns become one.
10211
10258
  * Plain media queries are used (not container queries) because they behave the same in every supported browser.
10212
10259
  * - `align`: start | center | stretch (default start) - how cells of different heights line up.
10260
+ * - `spanLastOdd` (default false): in a 2-column grid, a last cell that would sit alone in its row spans the whole row instead of
10261
+ * leaving an empty half (3 cells -> 2 + 1 full-width; 1 cell -> full width). Only for a grid that has 1 or 2 columns at EVERY width:
10262
+ * `count` 2 and every `countBelow*` tier (after its fallback to the next wider tier) 1 or 2, collapsing included. With a 3 or 4 column tier
10263
+ * at any width, or in `countFrom*` mode, the span is not applied at all (an inline span would break that width's grid). It is applied to the
10264
+ * last VISIBLE element child (a `hidden` / `display: none` cell is skipped), and a last cell that already has its own inline `grid-column`
10265
+ * is left alone. It is re-applied when cells come and go and when a direct child's `hidden`, `style` or `class` attribute changes.
10213
10266
  * - Responsive tiers (optional): `countBelowLg` (viewport <= 1024px), `countBelowMd` (<= 768px) and `countBelowSm` (<= 480px)
10214
10267
  * give a different column count (1-4) at narrower widths. Each tier falls back to the next wider one, then to `count`, so
10215
10268
  * a grid that sets none of them is unchanged. `collapseAt` is applied last: a width at or below it is one column.
@@ -10228,6 +10281,8 @@ export declare class ColumnsComponent {
10228
10281
  readonly gap: import("@angular/core").InputSignal<string>;
10229
10282
  readonly collapseAt: import("@angular/core").InputSignal<ColumnsCollapse>;
10230
10283
  readonly align: import("@angular/core").InputSignal<ColumnsAlign>;
10284
+ /** 2-column grids: an odd last cell spans the full row instead of leaving an empty half. Default false. */
10285
+ readonly spanLastOdd: import("@angular/core").InputSignal<boolean>;
10231
10286
  /** Column count at viewport widths <= 1024px (falls back to `count`). */
10232
10287
  readonly countBelowLg: import("@angular/core").InputSignal<ColumnsCount | null>;
10233
10288
  /** Column count at <= 768px (falls back to `countBelowLg`, then `count`). */
@@ -10254,8 +10309,21 @@ export declare class ColumnsComponent {
10254
10309
  protected readonly fromSm: import("@angular/core").Signal<ColumnsCount | null>;
10255
10310
  protected readonly fromMd: import("@angular/core").Signal<ColumnsCount | null>;
10256
10311
  protected readonly fromLg: import("@angular/core").Signal<ColumnsCount | null>;
10312
+ /** The column count at each width after the tier fallbacks: base (> 1024px), <= 1024, <= 768, <= 480. */
10313
+ private readonly effectiveCols;
10314
+ /** spanLastOdd only when the grid has 2 columns on wide screens and never more than 2 at any width (and is not in countFrom* mode). */
10315
+ protected readonly spanFits: import("@angular/core").Signal<boolean>;
10257
10316
  protected readonly gapCss: import("@angular/core").Signal<string>;
10258
10317
  protected readonly collapseClass: import("@angular/core").Signal<string>;
10318
+ private readonly grid;
10319
+ private readonly destroyRef;
10320
+ private static readonly SPAN_MARK;
10321
+ constructor();
10322
+ /**
10323
+ * Marks the last VISIBLE element child (when it would be alone in its row) with `grid-column: 1 / -1`, and clears a mark left on any other child.
10324
+ * A cell the consumer gave its own inline `grid-column` is never marked or cleared.
10325
+ */
10326
+ private applySpan;
10259
10327
  static ɵfac: i0.ɵɵFactoryDeclaration<ColumnsComponent, never>;
10260
10328
  static ɵcmp: i0.ɵɵComponentDeclaration<ColumnsComponent, "ui-columns", never, {
10261
10329
  "count": {
@@ -10278,6 +10346,11 @@ export declare class ColumnsComponent {
10278
10346
  "required": false;
10279
10347
  "isSignal": true;
10280
10348
  };
10349
+ "spanLastOdd": {
10350
+ "alias": "spanLastOdd";
10351
+ "required": false;
10352
+ "isSignal": true;
10353
+ };
10281
10354
  "countBelowLg": {
10282
10355
  "alias": "countBelowLg";
10283
10356
  "required": false;
@@ -11449,6 +11522,8 @@ export interface SetupIntegration {
11449
11522
  export interface SetupWizardTexts {
11450
11523
  brand: string;
11451
11524
  stepperLabel: string;
11525
+ /** Accessible name of the sidebar landmark (default "Setup steps"). Separate from `brand`, which may be empty or a logo-only heading. */
11526
+ asideLabel: string;
11452
11527
  progress: (done: number, total: number) => string;
11453
11528
  back: string;
11454
11529
  skip: string;
@@ -11480,6 +11555,8 @@ export interface SetupWizardTexts {
11480
11555
  summarySkipped: string;
11481
11556
  summaryPending: string;
11482
11557
  areaCode: string;
11558
+ /** Helper text under the area-code field; also what a disabled Connect button there is described by. */
11559
+ areaCodeHint: string;
11483
11560
  connectIntegrationFailed: (title: string) => string;
11484
11561
  }
11485
11562
  /** An import step: the library import window (CSV / pasted data / competitor sources) with the step's own words around it. */
@@ -11519,6 +11596,17 @@ export interface SetupStep {
11519
11596
  save?: () => Observable<unknown> | Promise<unknown> | void;
11520
11597
  /** `custom` and `integrations`: false disables "Save & Continue" (read on every render, so it can follow signals). */
11521
11598
  canContinue?: () => boolean;
11599
+ /**
11600
+ * `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
11601
+ * carries `aria-describedby="<id>"`, so a screen reader announces the reason with the disabled button (the attribute is absent otherwise).
11602
+ */
11603
+ continueHintId?: string;
11604
+ /**
11605
+ * `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
11606
+ * 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
11607
+ * 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.
11608
+ */
11609
+ continueWithoutComplete?: () => boolean;
11522
11610
  /** `custom`: text of the continue button (default "Save & Continue"). */
11523
11611
  saveLabel?: string;
11524
11612
  /**
@@ -11635,6 +11723,8 @@ export declare const SETUP_DONE_KEY = "done";
11635
11723
  * - `kind: 'integrations'` steps list integrations with Connect / Reconnect — QuickBooks, Twilio, Slack, email and calendar come ready made
11636
11724
  * (`SETUP_INTEGRATIONS` / `setupIntegrations(...)`); an app can add its own;
11637
11725
  * - `kind: 'custom'` steps show the app's own content (`<ng-template uiSetupStep="key">`) with the step's `save` / `canContinue` hooks.
11726
+ * `continueHintId` points the disabled Save & Continue at the app's own hint element (`aria-describedby`); `continueWithoutComplete` lets a step continue
11727
+ * without being marked complete (progress and side nav leave it out, the summary shows it as Pending).
11638
11728
  *
11639
11729
  * <ui-setup-wizard [steps]="steps()" [texts]="{ brand: 'My App Setup' }" (finished)="goToDashboard()" (exited)="goToDashboard()">
11640
11730
  * <ng-template uiSetupStep="profile"> … </ng-template>
@@ -11652,6 +11742,8 @@ export declare class SetupWizardComponent {
11652
11742
  /** An import step with `requireImport` keeps Continue off until something came in (a CSV import or `markCompleted`, e.g. a live sync). */
11653
11743
  /** An integrations step with `requireConnection` keeps Save & Continue off until at least one of its integrations is connected (Skip stays the way past). */
11654
11744
  protected readonly connectBlocked: import("@angular/core").Signal<boolean>;
11745
+ /** A custom step whose Save & Continue is off (`canContinue` false) and that names its hint element (`continueHintId`): the button is described by it. */
11746
+ protected customHintId(): string;
11655
11747
  protected readonly importBlocked: import("@angular/core").Signal<boolean>;
11656
11748
  /** 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
11749
  protected readonly splitTab: import("@angular/core").WritableSignal<"main" | "extra">;
@@ -11675,6 +11767,7 @@ export declare class SetupWizardComponent {
11675
11767
  protected readonly stepTemplates: import("@angular/core").Signal<readonly SetupWizardStepDirective[]>;
11676
11768
  protected readonly headerTemplates: import("@angular/core").Signal<readonly SetupWizardStepHeaderDirective[]>;
11677
11769
  private readonly injector;
11770
+ private readonly host;
11678
11771
  private readonly stepTitle;
11679
11772
  protected readonly importers: import("@angular/core").Signal<readonly ImportExportComponent[]>;
11680
11773
  protected readonly t: import("@angular/core").Signal<SetupWizardTexts>;
@@ -11733,6 +11826,8 @@ export declare class SetupWizardComponent {
11733
11826
  private markCompleted;
11734
11827
  /** "Save & Continue" of a custom or integrations step: runs the step's hook, then moves on. */
11735
11828
  saveAndContinue(): Promise<void>;
11829
+ /** `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). */
11830
+ private withholdsMark;
11736
11831
  private run;
11737
11832
  /** 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
11833
  private messageOf;