@forgeroute/ui 0.4.39 → 0.4.41

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.39",
3
+ "version": "0.4.41",
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. */
@@ -1813,7 +1813,7 @@ export declare class SendMessagePanelComponent {
1813
1813
  readonly activeContact: import("@angular/core").WritableSignal<MessageContact | null>;
1814
1814
  /** What the sender should know about the picked contact before sending (why a channel is missing, what to add). */
1815
1815
  readonly contactNotices: import("@angular/core").Signal<string[]>;
1816
- readonly channel: import("@angular/core").WritableSignal<"email" | "text">;
1816
+ readonly channel: import("@angular/core").WritableSignal<"text" | "email">;
1817
1817
  readonly valid: import("@angular/core").WritableSignal<boolean>;
1818
1818
  /** Bumped on every fresh open / new contact — re-creates the email and text forms so no draft carries over. */
1819
1819
  readonly formEpoch: import("@angular/core").WritableSignal<number>;
@@ -1,5 +1,6 @@
1
1
  import * as i0 from "@angular/core";
2
- import { InjectionToken, Provider } from "@angular/core";
2
+ import { DestroyRef, InjectionToken, Provider, WritableSignal } from "@angular/core";
3
+ import { Observable } from "rxjs";
3
4
  /**
4
5
  * The small part of Stripe.js the library calls, written as plain structural types so the library has NO compile-time or run-time
5
6
  * dependency on `@stripe/stripe-js` outside of the lazy loader (`stripe-loader.ts`). The real `Stripe` object satisfies these; so does a hand-written fake.
@@ -1141,4 +1142,247 @@ export declare class MicrodepositVerifyComponent {
1141
1142
  "verifyFailed": "verifyFailed";
1142
1143
  }, never, never, true, never>;
1143
1144
  }
1144
- export type { HandleReturnOptions, MicrodepositStartedBy, MicrodepositStepsContext, MicrodepositType, MicrodepositVerifyData, MicrodepositVerifyEvent, ProvideStripePaymentOptions, StripeA11yMessages, StripeAppearance, StripeBillingDetails, StripeConfirmResult, StripeConfirmedEvent, StripeConnection, StripeCreateIntentFn, StripeDeferredIntent, StripeElementChange, StripeElementsLike, StripeErrorDisplay, StripeErrorLike, StripeErrorMessageOptions, StripeFailure, StripeFailureStage, StripeIntentKind, StripeIntentLike, StripeLike, StripeLikeWithBankSetup, StripeLoadOptions, StripeLoaderFn, StripeMicrodepositNextAction, StripeMicrodepositResult, StripeOutcome, StripePaymentDefaults, StripePaymentElementLike, StripeReadyEvent, StripeReturnParams, StripeReturnResult, StripeVerification };
1145
+ /** What the account-status call answers (the shape of cremo's `GET /organizations/connect/status`). `isComplete` = Stripe accepts charges and payouts. */
1146
+ interface StripeConnectStatus {
1147
+ isComplete: boolean;
1148
+ detailsSubmitted?: boolean;
1149
+ /** The address of Stripe's onboarding page for an unfinished account. */
1150
+ onboardingUrl?: string;
1151
+ }
1152
+ /** What the create-account call answers (cremo's `POST /organizations/connect/create`): the new (or resumed) account and the address of Stripe's onboarding page. */
1153
+ interface StripeConnectAccount {
1154
+ accountId: string;
1155
+ onboardingUrl: string;
1156
+ }
1157
+ /**
1158
+ * What happened after the user pressed a button or the page asked for the state. The flow never shows toasts itself (each app has its own): the host words
1159
+ * each outcome, and decides what follows a finished account (for example switching payment collection on).
1160
+ *
1161
+ * - `complete`: Stripe accepts the account. `source: 'check'` = after "Check Status"; `'resume'` = "Complete Setup" found it already complete; `'return'` =
1162
+ * the state was read again when the user came back to this tab (`refreshOnReturn`).
1163
+ * - `verifying`: the details were submitted and Stripe is reviewing them.
1164
+ * - `incomplete`: "Check Status" found an unfinished onboarding (`onboardingUrl` present).
1165
+ * - `link-unavailable`: the answer had no https Stripe address; nothing was opened.
1166
+ * - `failed`: a call failed (`action` says which); `error` is what it threw.
1167
+ */
1168
+ type StripeConnectOutcome = {
1169
+ kind: 'complete';
1170
+ source: 'check' | 'resume' | 'return';
1171
+ } | {
1172
+ kind: 'verifying';
1173
+ source: 'check' | 'resume' | 'return';
1174
+ } | {
1175
+ kind: 'incomplete';
1176
+ } | {
1177
+ kind: 'link-unavailable';
1178
+ } | {
1179
+ kind: 'failed';
1180
+ action: 'start' | 'check' | 'resume';
1181
+ error: unknown;
1182
+ };
1183
+ /** The state the flow reads and writes: signals owned by the host (or by the card's two-way models). */
1184
+ interface StripeConnectState {
1185
+ accountId: WritableSignal<string | null>;
1186
+ complete: WritableSignal<boolean>;
1187
+ detailsSubmitted: WritableSignal<boolean>;
1188
+ loading: WritableSignal<boolean>;
1189
+ }
1190
+ interface StripeConnectFlowOptions {
1191
+ /** Read at call time, so a host can swap the call. Null = no call yet (`start()` does nothing). */
1192
+ createAccount: () => (() => Observable<StripeConnectAccount>) | null;
1193
+ getStatus: () => (() => Observable<StripeConnectStatus>) | null;
1194
+ state: StripeConnectState;
1195
+ /** Where outcomes go. */
1196
+ emit: (outcome: StripeConnectOutcome) => void;
1197
+ /** The buttons and methods do nothing while this says true (a read-only user). */
1198
+ disabled?: () => boolean;
1199
+ /** How THIS tab is sent to Stripe when the browser refused the new tab (default `window.location.href = url`). */
1200
+ navigate?: (url: string) => void;
1201
+ destroyRef: DestroyRef;
1202
+ }
1203
+ /** Only an https address on stripe.com or a real subdomain (never `evilstripe.com` / `connect.stripe.com.evil.com`, `http:`, `javascript:`). */
1204
+ export declare function isStripeUrl(url: string | undefined): url is string;
1205
+ /**
1206
+ * The Stripe Connect flow of cremo Settings > Payment & Billing, as a plain class: create the account, "Check Status", "Complete Setup", and the "back from Stripe" read.
1207
+ * `ui-stripe-connect` runs it behind its card; a host that has to start the flow from code before any view exists (Settings: the first change-detection pass with
1208
+ * `?connect=return`) creates its own instance over the same state signals. Stripe's page always opens in a NEW tab opened inside the click (a tab opened after the
1209
+ * request is blocked by popup blockers); only an https Stripe address is opened; a failed call closes the empty tab.
1210
+ */
1211
+ export declare class StripeConnectFlow {
1212
+ private readonly o;
1213
+ /** A Stripe tab was opened: the card reads the state again when the user comes back (`refreshOnReturn`). */
1214
+ tabOpened: boolean;
1215
+ constructor(o: StripeConnectFlowOptions);
1216
+ private get blocked();
1217
+ /** Creates (or resumes) the account and opens Stripe's onboarding page in a new tab. */
1218
+ start(): void;
1219
+ /** "Check Status": reads the state; a finished or submitted account updates the card, an unfinished one is reported. */
1220
+ check(): void;
1221
+ /** "Complete Setup": reads the state and opens the onboarding address of an unfinished account in a new tab (a finished or submitted one just updates the card). */
1222
+ resume(): void;
1223
+ /** The state read when the user came back to this tab: silent unless something finished or was submitted. */
1224
+ readStatusOnReturn(): void;
1225
+ private openStripe;
1226
+ /** The empty tab, opened inside the click and cut from this page (`opener`); null when the browser refused. */
1227
+ openBlankTab(): Window | null;
1228
+ /** The browser refused the new tab: Stripe opens in this one. */
1229
+ private navigateCurrentTab;
1230
+ private closeTab;
1231
+ }
1232
+ /**
1233
+ * The default wording of an outcome (the texts cremo Settings has always used), for apps that just want a toast: `{ variant, message }`, or null when
1234
+ * nothing should be said. `completeText` replaces the sentence of a finished account when the host has more to say about what follows.
1235
+ */
1236
+ export declare function stripeConnectNotice(outcome: StripeConnectOutcome): {
1237
+ variant: 'success' | 'info' | 'error';
1238
+ message: string;
1239
+ } | null;
1240
+ /**
1241
+ * "Stripe Connect Account": the card where a business connects the Stripe account it collects payments into (cremo Settings > Payment & Billing, built here
1242
+ * once so every app and the setup wizard show and run the SAME flow). The host owns the data (its two calls and the three state values); the component owns
1243
+ * the screen and the flow:
1244
+ *
1245
+ * - no account yet (`accountId` empty): nothing is shown (the host has its own entry point and calls `start()`), or with `showWhenNoAccount` a card with
1246
+ * "Set Up Payment Account";;
1247
+ * - account, not complete, nothing submitted: warning "Account setup incomplete" with "Complete Setup" (asks the status for the onboarding address and opens it);
1248
+ * - details submitted, not complete: info "Stripe is verifying your account" with "Check Status";
1249
+ * - complete: success "Account setup complete" with the account id and "View Stripe Dashboard".
1250
+ *
1251
+ * Stripe's onboarding page always opens in a NEW tab: the empty tab is opened inside the click (a tab opened after the request is blocked by popup
1252
+ * blockers) and receives the address when it arrives; with the tab refused the address opens in the current tab. Only an https Stripe address is ever opened,
1253
+ * never one an answer made up (`javascript:`, `data:`). A failed call closes the empty tab.
1254
+ *
1255
+ * <ui-stripe-connect [(accountId)]="accountId" [(complete)]="complete" [(detailsSubmitted)]="submitted"
1256
+ * [createAccount]="createAccount" [getStatus]="getStatus" [showWhenNoAccount]="true" (outcome)="onOutcome($event)" />
1257
+ *
1258
+ * where `createAccount = () => http.post<StripeConnectAccount>('/connect/create', {})` and `getStatus = () => http.get<StripeConnectStatus>('/connect/status')`.
1259
+ */
1260
+ export declare class StripeConnectComponent {
1261
+ private readonly destroyRef;
1262
+ /** The call that creates the organization's Stripe account (or resumes it) and answers its id and the onboarding address. Needed for `start()`. */
1263
+ readonly createAccount: import("@angular/core").InputSignal<(() => Observable<StripeConnectAccount>) | null>;
1264
+ /** The call that reads the account's state. Needed for `check()`, `resume()` and `refreshOnReturn`. */
1265
+ readonly getStatus: import("@angular/core").InputSignal<(() => Observable<StripeConnectStatus>) | null>;
1266
+ /** The Stripe account's id (null / empty = no account yet). Two-way: the component sets it when `start()` created the account. */
1267
+ readonly accountId: import("@angular/core").ModelSignal<string | null>;
1268
+ /** Stripe accepts the account (charges and payouts on). Two-way: set by `check()` / `resume()`. */
1269
+ readonly complete: import("@angular/core").ModelSignal<boolean>;
1270
+ /** The details were submitted and Stripe is reviewing them. Two-way: set by `check()` / `resume()`. */
1271
+ readonly detailsSubmitted: import("@angular/core").ModelSignal<boolean>;
1272
+ readonly title: import("@angular/core").InputSignal<string>;
1273
+ /** Shows the card (with "Set Up Payment Account") while there is no account yet. Default false: hosts with their own entry point show nothing and call `start()`. */
1274
+ readonly showWhenNoAccount: import("@angular/core").InputSignal<boolean>;
1275
+ readonly startTitle: import("@angular/core").InputSignal<string>;
1276
+ readonly startText: import("@angular/core").InputSignal<string>;
1277
+ readonly startLabel: import("@angular/core").InputSignal<string>;
1278
+ /** The buttons cannot be pressed (a read-only user). */
1279
+ readonly disabled: import("@angular/core").InputSignal<boolean>;
1280
+ /** After a Stripe tab was opened, the state is read again when this tab becomes visible again (the user came back): `(outcome)` then reports `complete` / `verifying` with source `return`. */
1281
+ readonly refreshOnReturn: import("@angular/core").InputSignal<boolean>;
1282
+ /** The page "View Stripe Dashboard" opens. */
1283
+ readonly dashboardUrl: import("@angular/core").InputSignal<string>;
1284
+ /** What happened (see {@link StripeConnectOutcome}); the host words it. */
1285
+ readonly outcome: import("@angular/core").OutputEmitterRef<StripeConnectOutcome>;
1286
+ /** A request is running: the buttons show "Loading..." / "Checking..." and cannot be pressed again. Two-way, so a host that shows the state elsewhere can read it. */
1287
+ readonly loading: import("@angular/core").ModelSignal<boolean>;
1288
+ /** 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. */
1289
+ readonly navigateTab: import("@angular/core").InputSignal<((url: string) => void) | null>;
1290
+ protected readonly visible: import("@angular/core").Signal<boolean>;
1291
+ private readonly flow;
1292
+ constructor();
1293
+ /** Creates (or resumes) the account and opens Stripe's onboarding page in a new tab. */
1294
+ start(): void;
1295
+ /** "Check Status": reads the state; a finished or submitted account updates the card, an unfinished one is reported. */
1296
+ check(): void;
1297
+ /** "Complete Setup": reads the state and opens the onboarding address of an unfinished account in a new tab. */
1298
+ resume(): void;
1299
+ /** Opens the Stripe dashboard in a new tab. */
1300
+ openDashboard(): void;
1301
+ /** The browser refused the new tab: Stripe opens in this one (through the host's `navigateTab` when it gave one). */
1302
+ protected navigateCurrentTab(url: string): void;
1303
+ static ɵfac: i0.ɵɵFactoryDeclaration<StripeConnectComponent, never>;
1304
+ static ɵcmp: i0.ɵɵComponentDeclaration<StripeConnectComponent, "ui-stripe-connect", never, {
1305
+ "createAccount": {
1306
+ "alias": "createAccount";
1307
+ "required": false;
1308
+ "isSignal": true;
1309
+ };
1310
+ "getStatus": {
1311
+ "alias": "getStatus";
1312
+ "required": false;
1313
+ "isSignal": true;
1314
+ };
1315
+ "accountId": {
1316
+ "alias": "accountId";
1317
+ "required": false;
1318
+ "isSignal": true;
1319
+ };
1320
+ "complete": {
1321
+ "alias": "complete";
1322
+ "required": false;
1323
+ "isSignal": true;
1324
+ };
1325
+ "detailsSubmitted": {
1326
+ "alias": "detailsSubmitted";
1327
+ "required": false;
1328
+ "isSignal": true;
1329
+ };
1330
+ "title": {
1331
+ "alias": "title";
1332
+ "required": false;
1333
+ "isSignal": true;
1334
+ };
1335
+ "showWhenNoAccount": {
1336
+ "alias": "showWhenNoAccount";
1337
+ "required": false;
1338
+ "isSignal": true;
1339
+ };
1340
+ "startTitle": {
1341
+ "alias": "startTitle";
1342
+ "required": false;
1343
+ "isSignal": true;
1344
+ };
1345
+ "startText": {
1346
+ "alias": "startText";
1347
+ "required": false;
1348
+ "isSignal": true;
1349
+ };
1350
+ "startLabel": {
1351
+ "alias": "startLabel";
1352
+ "required": false;
1353
+ "isSignal": true;
1354
+ };
1355
+ "disabled": {
1356
+ "alias": "disabled";
1357
+ "required": false;
1358
+ "isSignal": true;
1359
+ };
1360
+ "refreshOnReturn": {
1361
+ "alias": "refreshOnReturn";
1362
+ "required": false;
1363
+ "isSignal": true;
1364
+ };
1365
+ "dashboardUrl": {
1366
+ "alias": "dashboardUrl";
1367
+ "required": false;
1368
+ "isSignal": true;
1369
+ };
1370
+ "loading": {
1371
+ "alias": "loading";
1372
+ "required": false;
1373
+ "isSignal": true;
1374
+ };
1375
+ "navigateTab": {
1376
+ "alias": "navigateTab";
1377
+ "required": false;
1378
+ "isSignal": true;
1379
+ };
1380
+ }, {
1381
+ "accountId": "accountIdChange";
1382
+ "complete": "completeChange";
1383
+ "detailsSubmitted": "detailsSubmittedChange";
1384
+ "outcome": "outcome";
1385
+ "loading": "loadingChange";
1386
+ }, never, never, true, never>;
1387
+ }
1388
+ export type { HandleReturnOptions, MicrodepositStartedBy, MicrodepositStepsContext, MicrodepositType, MicrodepositVerifyData, MicrodepositVerifyEvent, ProvideStripePaymentOptions, StripeA11yMessages, StripeAppearance, StripeBillingDetails, StripeConfirmResult, StripeConfirmedEvent, StripeConnectAccount, StripeConnectFlowOptions, StripeConnectOutcome, StripeConnectState, StripeConnectStatus, StripeConnection, StripeCreateIntentFn, StripeDeferredIntent, StripeElementChange, StripeElementsLike, StripeErrorDisplay, StripeErrorLike, StripeErrorMessageOptions, StripeFailure, StripeFailureStage, StripeIntentKind, StripeIntentLike, StripeLike, StripeLikeWithBankSetup, StripeLoadOptions, StripeLoaderFn, StripeMicrodepositNextAction, StripeMicrodepositResult, StripeOutcome, StripePaymentDefaults, StripePaymentElementLike, StripeReadyEvent, StripeReturnParams, StripeReturnResult, StripeVerification };