@base316/react 0.3.0 → 0.5.0

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/dist/index.cjs +5295 -3081
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.ts +16 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +4140 -1928
  7. package/dist/index.js.map +1 -1
  8. package/dist/manifest.json +376 -9
  9. package/dist/src/AcceptInvitation.d.ts +15 -1
  10. package/dist/src/AcceptInvitation.d.ts.map +1 -1
  11. package/dist/src/BillingDetailsForm.d.ts +33 -0
  12. package/dist/src/BillingDetailsForm.d.ts.map +1 -0
  13. package/dist/src/BillingPortal.d.ts +45 -0
  14. package/dist/src/BillingPortal.d.ts.map +1 -0
  15. package/dist/src/CreditBalances.d.ts +19 -0
  16. package/dist/src/CreditBalances.d.ts.map +1 -0
  17. package/dist/src/Invoices.d.ts +10 -6
  18. package/dist/src/Invoices.d.ts.map +1 -1
  19. package/dist/src/PaymentMethod.d.ts +25 -0
  20. package/dist/src/PaymentMethod.d.ts.map +1 -0
  21. package/dist/src/PlanChangeReview.d.ts +29 -0
  22. package/dist/src/PlanChangeReview.d.ts.map +1 -0
  23. package/dist/src/PricingTable.d.ts +13 -1
  24. package/dist/src/PricingTable.d.ts.map +1 -1
  25. package/dist/src/SeatManager.d.ts +24 -0
  26. package/dist/src/SeatManager.d.ts.map +1 -0
  27. package/dist/src/SecondFactorStep.d.ts +83 -0
  28. package/dist/src/SecondFactorStep.d.ts.map +1 -0
  29. package/dist/src/SignIn.d.ts +7 -2
  30. package/dist/src/SignIn.d.ts.map +1 -1
  31. package/dist/src/SignUp.d.ts +51 -3
  32. package/dist/src/SignUp.d.ts.map +1 -1
  33. package/dist/src/SubscriptionManager.d.ts +7 -1
  34. package/dist/src/SubscriptionManager.d.ts.map +1 -1
  35. package/dist/src/UpcomingInvoice.d.ts +21 -0
  36. package/dist/src/UpcomingInvoice.d.ts.map +1 -0
  37. package/dist/src/appearance.d.ts +1 -1
  38. package/dist/src/appearance.d.ts.map +1 -1
  39. package/dist/src/manifest.d.ts.map +1 -1
  40. package/dist/src/usePlans.d.ts +9 -0
  41. package/dist/src/usePlans.d.ts.map +1 -1
  42. package/package.json +2 -2
@@ -0,0 +1,29 @@
1
+ import { type CSSProperties } from "react";
2
+ export interface PlanChangeReviewProps {
3
+ /** The plan version being moved to — a `PublicPlan`'s `planVersionId`. */
4
+ planVersionId: string;
5
+ /** Called once the change is made or scheduled. */
6
+ onDone?: (outcome: {
7
+ scheduled: boolean;
8
+ }) => void;
9
+ /** Called when the user backs out. Without it there is no back button. */
10
+ onCancel?: () => void;
11
+ /**
12
+ * Called when a change now needs a card the account does not have. Without
13
+ * it the review offers to start a card update itself.
14
+ */
15
+ onNeedsCard?: () => void;
16
+ className?: string;
17
+ style?: CSSProperties;
18
+ }
19
+ /**
20
+ * The review step before a plan change: what is gained and lost, what it
21
+ * costs, and when it happens — then confirm.
22
+ *
23
+ * The figures are `previewPlanChange`'s, the same function the change runs, so
24
+ * the amount shown is the amount charged. The default timing is the server's
25
+ * (an upgrade now, a downgrade at the renewal); the other is offered when it is
26
+ * open, and the reason is said when it is not.
27
+ */
28
+ export declare function PlanChangeReview({ planVersionId, onDone, onCancel, onNeedsCard, className, style, }: PlanChangeReviewProps): import("react").JSX.Element;
29
+ //# sourceMappingURL=PlanChangeReview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlanChangeReview.d.ts","sourceRoot":"","sources":["../../src/PlanChangeReview.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAoC,KAAK,aAAa,EAAkB,MAAM,OAAO,CAAC;AAuC7F,MAAM,WAAW,qBAAqB;IACrC,0EAA0E;IAC1E,aAAa,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IACnD,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,EAChC,aAAa,EACb,MAAM,EACN,QAAQ,EACR,WAAW,EACX,SAAS,EACT,KAAK,GACL,EAAE,qBAAqB,+BAoPvB"}
@@ -1,5 +1,17 @@
1
1
  import type { PublicPlan } from "@base316/sdk";
2
- import type { CSSProperties } from "react";
2
+ import { type CSSProperties } from "react";
3
+ /**
4
+ * What a plan's trial says on the card, or null when it has none.
5
+ *
6
+ * A `CONVERT` trial is the familiar "14-day free trial": it bills when it
7
+ * ends. A `DOWNGRADE` trial — the reverse trial — does not bill a subscriber
8
+ * who never added a card; it moves them to `trialDowngradePlanVersionId`. The
9
+ * card has to say so, or a visitor reads "free trial" as "then I'm charged"
10
+ * and never starts one. The target is named when it is among the published
11
+ * plans (it usually is: the Free plan); otherwise the label says what keeps
12
+ * the plan instead of guessing at a name.
13
+ */
14
+ export declare function describeTrial(plan: PublicPlan, plans: readonly PublicPlan[]): string | null;
3
15
  /**
4
16
  * The plans, as an end user picks them.
5
17
  *
@@ -1 +1 @@
1
- {"version":3,"file":"PricingTable.d.ts","sourceRoot":"","sources":["../../src/PricingTable.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AA4B3C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,YAAY,CAAC,EAC5B,YAAY,EACZ,oBAAoB,EACpB,eAAe,EACf,SAAS,EACT,SAAS,EACT,KAAK,GACL,EAAE;IACF;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB,+BA8JA"}
1
+ {"version":3,"file":"PricingTable.d.ts","sourceRoot":"","sources":["../../src/PricingTable.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,KAAK,aAAa,EAAY,MAAM,OAAO,CAAC;AA4BrD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,GAAG,IAAI,CAkB3F;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,YAAY,CAAC,EAC5B,YAAY,EACZ,oBAAoB,EACpB,eAAe,EACf,SAAS,EACT,SAAS,EACT,KAAK,GACL,EAAE;IACF;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB,+BAqLA"}
@@ -0,0 +1,24 @@
1
+ import type { QuantityChangeOutcome } from "@base316/sdk";
2
+ import { type CSSProperties } from "react";
3
+ export interface SeatManagerProps {
4
+ /** What a unit is called, plural. "seats" by default. */
5
+ unitLabel?: string;
6
+ /** Called after a change is made, with what it did. */
7
+ onChange?: (outcome: QuantityChangeOutcome) => void;
8
+ className?: string;
9
+ style?: CSSProperties;
10
+ }
11
+ /**
12
+ * Let the signed-in user change how many seats their subscription is for —
13
+ * with the price shown before anything is charged.
14
+ *
15
+ * Preview, then confirm. The preview is the server's own calculation: adding
16
+ * seats is charged now for the part of the period that is left, removing them
17
+ * takes effect at the period end and refunds nothing. The user only chooses the
18
+ * number — how the change is paid for is the application's policy, not theirs.
19
+ *
20
+ * A client company whose plan a firm pays for is told so instead: resizing the
21
+ * firm's subscription would reach every other client it has.
22
+ */
23
+ export declare function SeatManager({ unitLabel, onChange, className, style }: SeatManagerProps): import("react").JSX.Element;
24
+ //# sourceMappingURL=SeatManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SeatManager.d.ts","sourceRoot":"","sources":["../../src/SeatManager.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAyB,MAAM,cAAc,CAAC;AACjF,OAAO,EAAoC,KAAK,aAAa,EAAkB,MAAM,OAAO,CAAC;AA6C7F,MAAM,WAAW,gBAAgB;IAChC,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,EAAE,SAAmB,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,gBAAgB,+BAuOhG"}
@@ -0,0 +1,83 @@
1
+ import { type SignInPending } from "@base316/sdk";
2
+ import { type CSSProperties } from "react";
3
+ /**
4
+ * The second half of a sign-in that owes a second factor.
5
+ *
6
+ * Two shapes, decided by the server rather than guessed here:
7
+ *
8
+ * - **A challenge** (`enroll: false`): a code box for the factor the person
9
+ * already has — their authenticator app, or the code just sent to their inbox
10
+ * or phone — or one of their recovery codes.
11
+ * - **An enrolment** (`enroll: true`): the environment requires a second factor
12
+ * and this person has none, so there is nothing a code box could check. They
13
+ * choose one of `enrollMethods`, prove it with its first code, and are shown
14
+ * their recovery codes once before the session is handed over.
15
+ *
16
+ * The enrolment branch is what used to be missing. `SignIn` showed "from your
17
+ * authenticator app" to somebody who had never set one up, and `SignUp`
18
+ * silently stopped — so under a required policy nobody new could ever get in.
19
+ *
20
+ * Every visible string comes from `labels`, so a translated application passes
21
+ * its own and nothing here needs forking.
22
+ */
23
+ export interface SecondFactorLabels {
24
+ challengeTitle: string;
25
+ codeLabel: string;
26
+ /** Under the code box when the code went to an inbox or phone. */
27
+ codeSentTo: (destinationHint: string) => string;
28
+ /** Under the code box when it comes from an authenticator app. */
29
+ codeFromApp: string;
30
+ verify: string;
31
+ resend: string;
32
+ resent: string;
33
+ enrollTitle: string;
34
+ enrollIntro: string;
35
+ methodTotp: string;
36
+ methodTotpHint: string;
37
+ methodEmail: string;
38
+ methodEmailHint: string;
39
+ methodSms: string;
40
+ methodSmsHint: string;
41
+ totpInstructions: string;
42
+ qrAlt: string;
43
+ manualKey: string;
44
+ openInApp: string;
45
+ sixDigitCode: string;
46
+ /** Under the code box while enrolling a factor whose first code was sent. */
47
+ enrollCodeSentTo: (destinationHint: string) => string;
48
+ confirm: string;
49
+ phoneLabel: string;
50
+ phoneHint: string;
51
+ sendCode: string;
52
+ chooseAnother: string;
53
+ codesTitle: string;
54
+ codesIntro: string;
55
+ copy: string;
56
+ copied: string;
57
+ download: string;
58
+ /** The file the codes download as. */
59
+ downloadName: string;
60
+ savedConfirm: string;
61
+ continue: string;
62
+ working: string;
63
+ startOver: string;
64
+ /** A failure the server did not word. */
65
+ genericError: string;
66
+ }
67
+ export declare const DEFAULT_SECOND_FACTOR_LABELS: SecondFactorLabels;
68
+ export interface SecondFactorStepProps {
69
+ /** What `signIn`, `magicLink.verify` or `phone.verify` returned with `mfaRequired`. */
70
+ pending: SignInPending;
71
+ /** Called once the session has been handed to the provider. */
72
+ onSignedIn?: () => void;
73
+ /**
74
+ * Back to the start of the sign-in, for a challenge that has expired or been
75
+ * used up. Without it, no "Start over" button is drawn.
76
+ */
77
+ onRestart?: () => void;
78
+ labels?: Partial<SecondFactorLabels>;
79
+ className?: string;
80
+ style?: CSSProperties;
81
+ }
82
+ export declare function SecondFactorStep({ pending, onSignedIn, onRestart, labels: overrides, className, style, }: SecondFactorStepProps): import("react").JSX.Element;
83
+ //# sourceMappingURL=SecondFactorStep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SecondFactorStep.d.ts","sourceRoot":"","sources":["../../src/SecondFactorStep.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIN,KAAK,aAAa,EAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EAA+B,KAAK,aAAa,EAAkB,MAAM,OAAO,CAAC;AAKxF;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,kBAAkB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,UAAU,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,MAAM,CAAC;IAChD,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,gBAAgB,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,MAAM,CAAC;IACtD,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,4BAA4B,EAAE,kBAyC1C,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACrC,uFAAuF;IACvF,OAAO,EAAE,aAAa,CAAC;IACvB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAuBD,wBAAgB,gBAAgB,CAAC,EAChC,OAAO,EACP,UAAU,EACV,SAAS,EACT,MAAM,EAAE,SAAS,EACjB,SAAS,EACT,KAAK,GACL,EAAE,qBAAqB,+BA8ZvB"}
@@ -1,13 +1,16 @@
1
1
  import { type CSSProperties } from "react";
2
+ import { type SecondFactorLabels } from "./SecondFactorStep";
2
3
  /**
3
4
  * Email and password sign-in, and — where the application turns them on — a
4
5
  * magic link or a code by text message.
5
6
  *
6
7
  * Handles the MFA branch, because an account with a second factor gets a
7
8
  * challenge instead of a session, and a form that ignores that case appears to
8
- * fail for exactly the users who most need it to work.
9
+ * fail for exactly the users who most need it to work. That includes the case
10
+ * where the environment requires a factor and the person has none: they enrol
11
+ * one here (`SecondFactorStep`), see their recovery codes, and are signed in.
9
12
  */
10
- export declare function SignIn({ onSignedIn, passkeys, magicLinkRedirectUrl, phone, className, style, }: {
13
+ export declare function SignIn({ onSignedIn, passkeys, magicLinkRedirectUrl, phone, secondFactorLabels, className, style, }: {
11
14
  onSignedIn?: () => void;
12
15
  /** Offer passkeys alongside the password. On by default where supported. */
13
16
  passkeys?: boolean;
@@ -28,6 +31,8 @@ export declare function SignIn({ onSignedIn, passkeys, magicLinkRedirectUrl, pho
28
31
  * in production, the environment's own Twilio account.
29
32
  */
30
33
  phone?: boolean;
34
+ /** Override the second-factor step's wording, for translation. */
35
+ secondFactorLabels?: Partial<SecondFactorLabels>;
31
36
  className?: string;
32
37
  style?: CSSProperties;
33
38
  }): import("react").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"SignIn.d.ts","sourceRoot":"","sources":["../../src/SignIn.tsx"],"names":[],"mappings":"AAQA,OAAO,EAA+B,KAAK,aAAa,EAAkB,MAAM,OAAO,CAAC;AAKxF;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,EACtB,UAAU,EACV,QAAe,EACf,oBAAoB,EACpB,KAAa,EACb,SAAS,EACT,KAAK,GACL,EAAE;IACF,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB,+BAwbA"}
1
+ {"version":3,"file":"SignIn.d.ts","sourceRoot":"","sources":["../../src/SignIn.tsx"],"names":[],"mappings":"AASA,OAAO,EAA+B,KAAK,aAAa,EAAkB,MAAM,OAAO,CAAC;AAIxF,OAAO,EAAoB,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE/E;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,EACtB,UAAU,EACV,QAAe,EACf,oBAAoB,EACpB,KAAa,EACb,kBAAkB,EAClB,SAAS,EACT,KAAK,GACL,EAAE;IACF,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kEAAkE;IAClE,kBAAkB,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB,+BAmbA"}
@@ -1,4 +1,5 @@
1
1
  import { type CSSProperties } from "react";
2
+ import { type SecondFactorLabels } from "./SecondFactorStep";
2
3
  /**
3
4
  * Create an account.
4
5
  *
@@ -8,11 +9,58 @@ import { type CSSProperties } from "react";
8
9
  *
9
10
  * Sign-up does not itself produce a session, since the account still has to
10
11
  * verify its email. The form signs in straight afterwards so the common case
11
- * does not make people type their password twice.
12
+ * does not make people type their password twice — and when that sign-in owes
13
+ * a second factor, including enrolling one under a policy that requires it,
14
+ * the form carries on into that step rather than stopping with nothing on
15
+ * screen.
16
+ *
17
+ * The password rules shown are the environment's own, read from the API, and a
18
+ * refusal is the server's sentence for the rule that was missed.
19
+ *
20
+ * On a page reached from an invitation (`?invitation=`, or `invitationToken`)
21
+ * the token rides along with the sign-up. The account is then created straight
22
+ * into the inviting team — no personal workspace — with its address counted as
23
+ * verified, because the token reached that mailbox. The form says which team
24
+ * and fills in the address the invitation went to.
12
25
  */
13
- export declare function SignUp({ onSignedUp, className, style, }: {
26
+ export interface SignUpLabels {
27
+ name: string;
28
+ email: string;
29
+ password: string;
30
+ submit: string;
31
+ working: string;
32
+ /** Rules under the password box, joined by the component. */
33
+ ruleMinLength: (count: number) => string;
34
+ ruleUppercase: string;
35
+ ruleLowercase: string;
36
+ ruleNumber: string;
37
+ ruleSymbol: string;
38
+ ruleBreached: string;
39
+ /** Account made, but the environment wants the address confirmed first. */
40
+ confirmEmailTitle: string;
41
+ confirmEmail: (email: string) => string;
42
+ /** Account made, but signing in straight after failed for another reason. */
43
+ createdSignInFailed: (reason: string) => string;
44
+ /** A failure the server did not word. */
45
+ genericError: string;
46
+ /** Above the form when the page came from an invitation. */
47
+ joining: (organizationName: string, roleName: string) => string;
48
+ }
49
+ export declare const DEFAULT_SIGN_UP_LABELS: SignUpLabels;
50
+ export interface SignUpProps {
14
51
  onSignedUp?: () => void;
52
+ /**
53
+ * The invitation this sign-up accepts. Read from `?invitation=` when
54
+ * omitted; pass `null` to ignore the URL.
55
+ */
56
+ invitationToken?: string | null;
57
+ /** Called with the team's id when the sign-up accepted an invitation. */
58
+ onJoined?: (organizationId: string) => void;
59
+ labels?: Partial<SignUpLabels>;
60
+ /** Override the second-factor step's wording, for translation. */
61
+ secondFactorLabels?: Partial<SecondFactorLabels>;
15
62
  className?: string;
16
63
  style?: CSSProperties;
17
- }): import("react").JSX.Element;
64
+ }
65
+ export declare function SignUp({ onSignedUp, invitationToken: suppliedInvitation, onJoined, labels: overrides, secondFactorLabels, className, style, }: SignUpProps): import("react").JSX.Element;
18
66
  //# sourceMappingURL=SignUp.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SignUp.d.ts","sourceRoot":"","sources":["../../src/SignUp.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,aAAa,EAAkB,MAAM,OAAO,CAAC;AAKrE;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,CAAC,EACtB,UAAU,EACV,SAAS,EACT,KAAK,GACL,EAAE;IACF,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB,+BAyFA"}
1
+ {"version":3,"file":"SignUp.d.ts","sourceRoot":"","sources":["../../src/SignUp.tsx"],"names":[],"mappings":"AASA,OAAO,EAAuB,KAAK,aAAa,EAAkB,MAAM,OAAO,CAAC;AAIhF,OAAO,EAAoB,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,6EAA6E;IAC7E,mBAAmB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAChD,yCAAyC;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,OAAO,EAAE,CAAC,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;CAChE;AAED,eAAO,MAAM,sBAAsB,EAAE,YAoBpC,CAAC;AAEF,MAAM,WAAW,WAAW;IAC3B,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,yEAAyE;IACzE,QAAQ,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,kEAAkE;IAClE,kBAAkB,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAiBD,wBAAgB,MAAM,CAAC,EACtB,UAAU,EACV,eAAe,EAAE,kBAAkB,EACnC,QAAQ,EACR,MAAM,EAAE,SAAS,EACjB,kBAAkB,EAClB,SAAS,EACT,KAAK,GACL,EAAE,WAAW,+BA+Nb"}
@@ -6,7 +6,13 @@ import { type CSSProperties } from "react";
6
6
  * whoever the session says it is, so one user cannot be pointed at another's
7
7
  * billing by changing a prop.
8
8
  */
9
- export declare function SubscriptionManager({ className, style, }: {
9
+ export declare function SubscriptionManager({ onChange, className, style, }: {
10
+ /**
11
+ * Called after a cancel, a resume or an undone plan change, so a sibling
12
+ * showing the same subscription — an upcoming invoice, a plan picker — can
13
+ * refresh. `BillingPortal` uses it to keep its pieces in step.
14
+ */
15
+ onChange?: () => void;
10
16
  className?: string;
11
17
  style?: CSSProperties;
12
18
  }): import("react").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"SubscriptionManager.d.ts","sourceRoot":"","sources":["../../src/SubscriptionManager.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAU7E;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,EACnC,SAAS,EACT,KAAK,GACL,EAAE;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB,+BAoIA"}
1
+ {"version":3,"file":"SubscriptionManager.d.ts","sourceRoot":"","sources":["../../src/SubscriptionManager.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAW7E;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,EACnC,QAAQ,EACR,SAAS,EACT,KAAK,GACL,EAAE;IACF;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB,+BAkMA"}
@@ -0,0 +1,21 @@
1
+ import { type CSSProperties } from "react";
2
+ /**
3
+ * The signed-in user's next bill: when it arrives, what is on it, and what it
4
+ * comes to.
5
+ *
6
+ * The figures are the billing engine's own — usage so far, the plan fee,
7
+ * addons, one-off charges, discount, tax and wallet balance — computed on
8
+ * request and stored nowhere, so showing this costs the user nothing and can
9
+ * never disagree with the invoice that follows, except by usage that arrives
10
+ * in between.
11
+ *
12
+ * A client company whose plan a firm pays for sees a line saying so rather
13
+ * than the firm's invoice, which lists every other client's usage too.
14
+ */
15
+ export declare function UpcomingInvoice({ showLines, className, style, }: {
16
+ /** Show the breakdown. Off gives one line: the amount and the date. */
17
+ showLines?: boolean;
18
+ className?: string;
19
+ style?: CSSProperties;
20
+ }): import("react").JSX.Element;
21
+ //# sourceMappingURL=UpcomingInvoice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UpcomingInvoice.d.ts","sourceRoot":"","sources":["../../src/UpcomingInvoice.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAuB,KAAK,aAAa,EAAkB,MAAM,OAAO,CAAC;AAsChF;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,EAC/B,SAAgB,EAChB,SAAS,EACT,KAAK,GACL,EAAE;IACF,uEAAuE;IACvE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB,+BA+JA"}
@@ -59,5 +59,5 @@ export declare function cls(base: string, extra?: string): string;
59
59
  * Appended as a second block so the print rules stay next to the invoice they
60
60
  * apply to, rather than being buried in the middle of the component styles.
61
61
  */
62
- export declare const STYLESHEET_EXTRA = "\n.b316-pay__element { margin-bottom: var(--b316-spacing); min-height: 40px; }\n\n.b316-pay__submit {\n width: 100%;\n padding: 11px 14px;\n border: 0;\n border-radius: calc(var(--b316-radius) / 1.6);\n background: var(--b316-color-primary);\n color: #fff;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n}\n\n.b316-pay__submit[disabled] { opacity: 0.55; cursor: progress; }\n\n.b316-pay__error {\n background: var(--b316-color-danger-bg);\n color: var(--b316-color-danger);\n padding: 8px 10px;\n border-radius: calc(var(--b316-radius) / 2);\n font-size: 0.9em;\n margin-bottom: var(--b316-spacing);\n}\n\n.b316-pay__done {\n background: var(--b316-color-success-bg, #f0fdf4);\n color: var(--b316-color-success);\n padding: 12px 14px;\n border-radius: calc(var(--b316-radius) / 2);\n text-align: center;\n margin: 0;\n}\n\n.b316-tabs { display: flex; gap: 4px; margin-bottom: 16px; border-bottom: 1px solid var(--b316-color-border); }\n.b316-tab {\n flex: 1; padding: 8px 4px; background: none; border: 0; cursor: pointer;\n font: inherit; font-size: .95em; color: var(--b316-color-muted);\n border-bottom: 2px solid transparent; margin-bottom: -1px;\n}\n.b316-tab-on { color: var(--b316-color-text); border-bottom-color: var(--b316-color-primary); }\n.b316-branding { display: flex; flex-direction: column; gap: 4px; }\n.b316-branding-logo { max-height: 40px; width: auto; align-self: flex-start; }\n.b316-branding-name { font-size: 1.5em; font-weight: 650; letter-spacing: -.01em; }\n.b316-branding-tagline { color: var(--b316-color-muted); }\n\n.b316-invoice-table { width: 100%; border-collapse: collapse; font-size: 0.94em; }\n.b316-invoice-table th {\n text-align: left;\n font-weight: 500;\n color: var(--b316-color-muted);\n font-size: 0.85em;\n padding: 0 0 6px;\n border-bottom: 1px solid var(--b316-color-border);\n}\n.b316-invoice-table td { padding: 9px 0; border-bottom: 1px solid var(--b316-color-border); }\n/* Columns need breathing room or the amount runs straight into the action \u2014\n \"$49.00View\" \u2014 which is what happens when only the row has padding. */\n.b316-invoice-table th + th,\n.b316-invoice-table td + td { padding-left: 16px; }\n.b316-invoice-table td:last-child,\n.b316-invoice-table th:last-child { text-align: right; width: 1%; white-space: nowrap; }\n.b316-invoice-table tr:last-child td { border-bottom: 0; }\n.b316-num { text-align: right; font-variant-numeric: tabular-nums; }\n\n.b316-invoice-view {\n margin-top: calc(var(--b316-spacing) * 1.4);\n border-top: 1px solid var(--b316-color-border);\n padding-top: calc(var(--b316-spacing) * 1.4);\n}\n.b316-invoice-actions { display: flex; gap: 8px; justify-content: flex-end; margin-bottom: var(--b316-spacing); }\n.b316-invoice-doc { display: flex; flex-direction: column; gap: calc(var(--b316-spacing) * 1.4); }\n.b316-invoice-meta { display: grid; grid-template-columns: 1fr 1fr; gap: var(--b316-spacing); }\n.b316-invoice-totals { display: flex; flex-direction: column; gap: 6px; margin-left: auto; min-width: 240px; }\n.b316-invoice-total { font-weight: 650; border-top: 1px solid var(--b316-color-border); padding-top: 6px; }\n\n/* Printing an invoice emits the invoice alone, and printing anything else is\n none of this package's business.\n\n This used to start with a bare \"body * { visibility: hidden }\", which is the\n usual recipe for printing one element \u2014 and it is scoped to the document,\n not to us. The stylesheet is injected into the host page's head the first\n time any Base316 component mounts, so from that moment every print in the\n host application came out blank unless the content happened to sit inside\n .b316-invoice-doc. A customer printing their own page had no way to connect\n it back to us.\n\n Scoped to a root the invoice sets on <html> while it is being printed\n instead, so nothing applies unless an invoice asked for it. */\n@media print {\n [data-b316-printing] body * { visibility: hidden; }\n [data-b316-printing] .b316-invoice-doc,\n [data-b316-printing] .b316-invoice-doc * { visibility: visible; }\n [data-b316-printing] .b316-invoice-doc {\n position: absolute;\n inset: 0 auto auto 0;\n width: 100%;\n padding: 24px;\n }\n .b316-invoice-actions { display: none; }\n}\n\n/* --- Collections: tables, forms and detail views ------------------------- */\n\n.b316-table-wrap { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-table-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--b316-spacing); flex-wrap: wrap; }\n.b316-table-actions { display: flex; align-items: center; gap: var(--b316-spacing); }\n\n/* The table scrolls inside its own box rather than pushing the page sideways:\n a collection with twenty fields is normal, and a horizontally scrolling page\n makes every other component on it unreachable. */\n.b316-table-scroll { overflow-x: auto; border: 1px solid var(--b316-color-border); border-radius: var(--b316-radius); }\n.b316-table { width: 100%; border-collapse: collapse; font-size: 0.95em; }\n.b316-table th, .b316-table td { padding: 10px 12px; text-align: left; vertical-align: top; white-space: nowrap; }\n.b316-table thead th { background: var(--b316-color-surface-muted, rgba(0,0,0,.03)); font-weight: 600; font-size: 0.87em; color: var(--b316-color-muted); border-bottom: 1px solid var(--b316-color-border); }\n.b316-table tbody tr + tr td { border-top: 1px solid var(--b316-color-border); }\n.b316-row-clickable { cursor: pointer; }\n.b316-row-clickable:hover td { background: var(--b316-color-surface-muted, rgba(0,0,0,.02)); }\n.b316-table-rowactions { text-align: right; white-space: nowrap; }\n.b316-table-more { display: flex; justify-content: center; }\n\n.b316-sort { background: none; border: 0; padding: 0; font: inherit; color: inherit; cursor: pointer; }\n.b316-sort:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 2px; }\n\n.b316-empty { padding: calc(var(--b316-spacing) * 2); text-align: center; color: var(--b316-color-muted); }\n\n.b316-button-quiet {\n background: none;\n border: 0;\n padding: 4px 6px;\n font: inherit;\n font-size: 0.9em;\n color: var(--b316-color-primary);\n cursor: pointer;\n border-radius: calc(var(--b316-radius) / 2);\n}\n.b316-button-quiet:hover:not([disabled]) { background: var(--b316-color-surface-muted, rgba(0,0,0,.05)); }\n.b316-button-quiet:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 1px; }\n.b316-button-quiet[disabled] { opacity: .55; cursor: not-allowed; }\n.b316-danger { color: var(--b316-color-danger, #b42318); }\n\n.b316-chip {\n display: inline-block;\n padding: 2px 8px;\n border-radius: 999px;\n background: var(--b316-color-surface-muted, rgba(0,0,0,.05));\n font-size: 0.87em;\n}\n.b316-chips { display: inline-flex; gap: 4px; flex-wrap: wrap; }\n\n.b316-form { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-form-title { margin: 0; font-size: 1.05em; }\n.b316-form-actions { display: flex; justify-content: flex-end; gap: 8px; }\n.b316-field { display: flex; flex-direction: column; gap: 4px; }\n.b316-hint { font-size: 0.82em; color: var(--b316-color-muted); }\n.b316-input-invalid { border-color: var(--b316-color-danger, #b42318); }\n.b316-choices { display: flex; flex-wrap: wrap; gap: 10px; }\n.b316-choice { display: inline-flex; align-items: center; gap: 6px; font-size: 0.95em; }\n.b316-suffixed { display: flex; align-items: center; gap: 8px; }\n.b316-address { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }\n\n.b316-relation-chosen { display: flex; align-items: center; gap: 8px; }\n.b316-relation-results {\n list-style: none;\n margin: 4px 0 0;\n padding: 4px;\n border: 1px solid var(--b316-color-border);\n border-radius: var(--b316-radius);\n max-height: 220px;\n overflow-y: auto;\n background: var(--b316-color-surface, #fff);\n}\n.b316-relation-result { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 6px 8px; font: inherit; cursor: pointer; border-radius: calc(var(--b316-radius) / 2); }\n.b316-relation-result:hover, .b316-relation-result:focus-visible { background: var(--b316-color-surface-muted, rgba(0,0,0,.05)); outline: none; }\n.b316-relation-empty { padding: 6px 8px; }\n\n.b316-detail { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-detail-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--b316-spacing); }\n.b316-detail-title { margin: 0; font-size: 1.1em; }\n.b316-detail-actions { display: flex; gap: 4px; }\n.b316-detail-fields { display: grid; grid-template-columns: minmax(120px, 200px) 1fr; gap: 8px var(--b316-spacing); margin: 0; }\n.b316-detail-row { display: contents; }\n.b316-detail-fields dd { margin: 0; }\n\n/* One column on a narrow screen. A label column of 200px beside a value leaves\n nothing for the value on a phone. */\n/* --- Teams --------------------------------------------------------------- */\n\n.b316-team { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-team-title { margin: 0; font-size: 1em; font-weight: 600; }\n.b316-team-subtitle { margin: 0; font-size: .9em; font-weight: 600; color: var(--b316-color-muted); }\n.b316-team-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }\n.b316-team-member { display: flex; align-items: center; justify-content: space-between; gap: var(--b316-spacing); }\n.b316-team-member-side { display: flex; align-items: center; gap: 8px; }\n.b316-team-invite { display: flex; flex-direction: column; gap: 4px; }\n.b316-team-invite-row { display: flex; gap: 8px; }\n.b316-team-invite-row input { flex: 1; }\n/* Selectable and wrapping: this is copied by hand and pasted into an email. */\n.b316-team-link { display: flex; flex-direction: column; gap: 4px; }\n.b316-team-link code { word-break: break-all; user-select: all; padding: 8px; border: 1px solid var(--b316-color-border); border-radius: var(--b316-radius); }\n\n.b316-invitation { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-invitation-actions { display: flex; align-items: center; gap: var(--b316-spacing); }\n\n/* --- Sessions, two-factor and the password flows ------------------------- */\n\n.b316-sessions { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-sessions-head { display: flex; align-items: center; justify-content: space-between; gap: var(--b316-spacing); flex-wrap: wrap; }\n.b316-sessions-title, .b316-mfa-title { margin: 0; font-size: 1em; font-weight: 600; }\n.b316-sessions-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }\n.b316-session { display: flex; flex-direction: column; gap: 2px; }\n.b316-session-device { display: flex; align-items: center; gap: 6px; font-size: 0.95em; }\n\n.b316-device { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-device-title { margin: 0; font-size: 1em; font-weight: 600; }\n/* What is being granted, listed rather than run together: somebody is deciding\n on this, and a comma-separated line is read as one thing. */\n.b316-device-scopes { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }\n.b316-device-scopes li { padding: 2px 8px; border-radius: 999px; font-size: 0.85em; background: var(--b316-color-surface-muted, rgba(0,0,0,.05)); }\n.b316-device-actions { display: flex; gap: 8px; }\n\n.b316-privacy { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-privacy-title { margin: 0; font-size: 1em; font-weight: 600; }\n/* Wraps rather than squeezes: the explanation beside each control is the part\n that matters, and on a narrow screen it belongs above the button. */\n.b316-privacy-row { display: flex; flex-wrap: wrap; align-items: start; justify-content: space-between; gap: 10px; }\n.b316-privacy-row p { margin: 0; }\n.b316-privacy-confirm { display: flex; flex-direction: column; gap: 8px; }\n.b316-privacy-actions { display: flex; justify-content: flex-end; gap: 8px; }\n\n.b316-mfa { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-mfa-enrol, .b316-mfa-codes, .b316-mfa-on, .b316-mfa-off { display: flex; flex-direction: column; gap: 10px; }\n.b316-mfa-actions { display: flex; justify-content: flex-end; gap: 8px; }\n/* Selectable and wrapping: this is copied by hand on the device that cannot\n scan its own screen. */\n.b316-mfa-secret code {\n display: block;\n padding: 10px;\n border: 1px solid var(--b316-color-border);\n border-radius: var(--b316-radius);\n font-size: 1.05em;\n letter-spacing: .08em;\n word-break: break-all;\n user-select: all;\n}\n.b316-mfa-uri { font-size: 0.9em; }\n.b316-mfa-code-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }\n.b316-mfa-code-list code { user-select: all; }\n\n@media (max-width: 560px) {\n .b316-mfa-code-list { grid-template-columns: 1fr; }\n .b316-detail-fields { grid-template-columns: 1fr; }\n .b316-detail-row { display: block; margin-bottom: 10px; }\n .b316-address { grid-template-columns: 1fr; }\n}\n\n/* --- Board --------------------------------------------------------------- */\n\n.b316-board-wrap { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n/* The board scrolls sideways inside itself. Six columns is normal and a page\n that scrolls horizontally puts everything else on it out of reach. */\n.b316-board { display: flex; gap: var(--b316-spacing); overflow-x: auto; align-items: flex-start; padding-bottom: 4px; }\n.b316-board-column {\n flex: 0 0 260px;\n background: var(--b316-color-surface-muted, rgba(0,0,0,.03));\n border: 1px solid transparent;\n border-radius: var(--b316-radius);\n padding: 10px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.b316-board-over { border-color: var(--b316-color-primary); }\n.b316-board-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }\n.b316-board-title { font-weight: 600; font-size: 0.92em; }\n.b316-board-cards { display: flex; flex-direction: column; gap: 8px; min-height: 40px; }\n.b316-board-card {\n background: var(--b316-color-surface, #fff);\n border: 1px solid var(--b316-color-border);\n border-radius: calc(var(--b316-radius) * .8);\n padding: 10px;\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: 0.9em;\n}\n.b316-board-card[draggable=\"true\"] { cursor: grab; }\n.b316-board-card-title { font-weight: 600; }\n.b316-board-card-field { display: flex; justify-content: space-between; gap: 8px; }\n.b316-board-move { display: flex; align-items: center; gap: 6px; margin-top: 2px; }\n.b316-board-move select { flex: 1; font-size: 0.9em; padding: 2px 4px; }\n.b316-board-empty { color: var(--b316-color-muted); font-size: 0.87em; padding: 6px 2px; }\n\n/* --- Chart --------------------------------------------------------------- */\n\n.b316-chart { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-chart-title { font-weight: 600; font-size: 0.95em; }\n.b316-chart-plot { display: flex; align-items: flex-end; gap: 4px; overflow-x: auto; }\n.b316-chart-col { flex: 1 0 24px; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; gap: 4px; }\n.b316-chart-bar { width: 100%; background: var(--b316-color-primary); border-radius: 3px 3px 0 0; min-height: 2px; }\n.b316-chart-label { font-size: 0.7em; color: var(--b316-color-muted); white-space: nowrap; transform: rotate(-45deg); transform-origin: top left; height: 1.6em; }\n.b316-chart-data summary { cursor: pointer; font-size: 0.87em; color: var(--b316-color-muted); }\n.b316-chart-data table { margin-top: 8px; }\n";
62
+ export declare const STYLESHEET_EXTRA = "\n.b316-pay__element { margin-bottom: var(--b316-spacing); min-height: 40px; }\n\n.b316-pay__submit {\n width: 100%;\n padding: 11px 14px;\n border: 0;\n border-radius: calc(var(--b316-radius) / 1.6);\n background: var(--b316-color-primary);\n color: #fff;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n}\n\n.b316-pay__submit[disabled] { opacity: 0.55; cursor: progress; }\n\n.b316-pay__error {\n background: var(--b316-color-danger-bg);\n color: var(--b316-color-danger);\n padding: 8px 10px;\n border-radius: calc(var(--b316-radius) / 2);\n font-size: 0.9em;\n margin-bottom: var(--b316-spacing);\n}\n\n.b316-pay__done {\n background: var(--b316-color-success-bg, #f0fdf4);\n color: var(--b316-color-success);\n padding: 12px 14px;\n border-radius: calc(var(--b316-radius) / 2);\n text-align: center;\n margin: 0;\n}\n\n.b316-tabs { display: flex; gap: 4px; margin-bottom: 16px; border-bottom: 1px solid var(--b316-color-border); }\n.b316-tab {\n flex: 1; padding: 8px 4px; background: none; border: 0; cursor: pointer;\n font: inherit; font-size: .95em; color: var(--b316-color-muted);\n border-bottom: 2px solid transparent; margin-bottom: -1px;\n}\n.b316-tab-on { color: var(--b316-color-text); border-bottom-color: var(--b316-color-primary); }\n.b316-branding { display: flex; flex-direction: column; gap: 4px; }\n.b316-branding-logo { max-height: 40px; width: auto; align-self: flex-start; }\n.b316-branding-name { font-size: 1.5em; font-weight: 650; letter-spacing: -.01em; }\n.b316-branding-tagline { color: var(--b316-color-muted); }\n\n.b316-invoice-table { width: 100%; border-collapse: collapse; font-size: 0.94em; }\n.b316-invoice-table th {\n text-align: left;\n font-weight: 500;\n color: var(--b316-color-muted);\n font-size: 0.85em;\n padding: 0 0 6px;\n border-bottom: 1px solid var(--b316-color-border);\n}\n.b316-invoice-table td { padding: 9px 0; border-bottom: 1px solid var(--b316-color-border); }\n/* Columns need breathing room or the amount runs straight into the action \u2014\n \"$49.00View\" \u2014 which is what happens when only the row has padding. */\n.b316-invoice-table th + th,\n.b316-invoice-table td + td { padding-left: 16px; }\n.b316-invoice-table td:last-child,\n.b316-invoice-table th:last-child { text-align: right; width: 1%; white-space: nowrap; }\n.b316-invoice-table tr:last-child td { border-bottom: 0; }\n.b316-num { text-align: right; font-variant-numeric: tabular-nums; }\n\n.b316-invoice-view {\n margin-top: calc(var(--b316-spacing) * 1.4);\n border-top: 1px solid var(--b316-color-border);\n padding-top: calc(var(--b316-spacing) * 1.4);\n}\n.b316-invoice-actions { display: flex; gap: 8px; justify-content: flex-end; margin-bottom: var(--b316-spacing); }\n.b316-invoice-doc { display: flex; flex-direction: column; gap: calc(var(--b316-spacing) * 1.4); }\n.b316-invoice-meta { display: grid; grid-template-columns: 1fr 1fr; gap: var(--b316-spacing); }\n.b316-invoice-totals { display: flex; flex-direction: column; gap: 6px; margin-left: auto; min-width: 240px; }\n.b316-invoice-total { font-weight: 650; border-top: 1px solid var(--b316-color-border); padding-top: 6px; }\n\n/* Printing an invoice emits the invoice alone, and printing anything else is\n none of this package's business.\n\n This used to start with a bare \"body * { visibility: hidden }\", which is the\n usual recipe for printing one element \u2014 and it is scoped to the document,\n not to us. The stylesheet is injected into the host page's head the first\n time any Base316 component mounts, so from that moment every print in the\n host application came out blank unless the content happened to sit inside\n .b316-invoice-doc. A customer printing their own page had no way to connect\n it back to us.\n\n Scoped to a root the invoice sets on <html> while it is being printed\n instead, so nothing applies unless an invoice asked for it. */\n@media print {\n [data-b316-printing] body * { visibility: hidden; }\n [data-b316-printing] .b316-invoice-doc,\n [data-b316-printing] .b316-invoice-doc * { visibility: visible; }\n [data-b316-printing] .b316-invoice-doc {\n position: absolute;\n inset: 0 auto auto 0;\n width: 100%;\n padding: 24px;\n }\n .b316-invoice-actions { display: none; }\n}\n\n/* --- Collections: tables, forms and detail views ------------------------- */\n\n.b316-table-wrap { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-table-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--b316-spacing); flex-wrap: wrap; }\n.b316-table-actions { display: flex; align-items: center; gap: var(--b316-spacing); }\n\n/* The table scrolls inside its own box rather than pushing the page sideways:\n a collection with twenty fields is normal, and a horizontally scrolling page\n makes every other component on it unreachable. */\n.b316-table-scroll { overflow-x: auto; border: 1px solid var(--b316-color-border); border-radius: var(--b316-radius); }\n.b316-table { width: 100%; border-collapse: collapse; font-size: 0.95em; }\n.b316-table th, .b316-table td { padding: 10px 12px; text-align: left; vertical-align: top; white-space: nowrap; }\n.b316-table thead th { background: var(--b316-color-surface-muted, rgba(0,0,0,.03)); font-weight: 600; font-size: 0.87em; color: var(--b316-color-muted); border-bottom: 1px solid var(--b316-color-border); }\n.b316-table tbody tr + tr td { border-top: 1px solid var(--b316-color-border); }\n.b316-row-clickable { cursor: pointer; }\n.b316-row-clickable:hover td { background: var(--b316-color-surface-muted, rgba(0,0,0,.02)); }\n.b316-table-rowactions { text-align: right; white-space: nowrap; }\n.b316-table-more { display: flex; justify-content: center; }\n\n.b316-sort { background: none; border: 0; padding: 0; font: inherit; color: inherit; cursor: pointer; }\n.b316-sort:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 2px; }\n\n.b316-empty { padding: calc(var(--b316-spacing) * 2); text-align: center; color: var(--b316-color-muted); }\n\n.b316-button-quiet {\n background: none;\n border: 0;\n padding: 4px 6px;\n font: inherit;\n font-size: 0.9em;\n color: var(--b316-color-primary);\n cursor: pointer;\n border-radius: calc(var(--b316-radius) / 2);\n}\n.b316-button-quiet:hover:not([disabled]) { background: var(--b316-color-surface-muted, rgba(0,0,0,.05)); }\n.b316-button-quiet:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 1px; }\n.b316-button-quiet[disabled] { opacity: .55; cursor: not-allowed; }\n.b316-danger { color: var(--b316-color-danger, #b42318); }\n\n.b316-chip {\n display: inline-block;\n padding: 2px 8px;\n border-radius: 999px;\n background: var(--b316-color-surface-muted, rgba(0,0,0,.05));\n font-size: 0.87em;\n}\n.b316-chips { display: inline-flex; gap: 4px; flex-wrap: wrap; }\n\n.b316-form { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-form-title { margin: 0; font-size: 1.05em; }\n.b316-form-actions { display: flex; justify-content: flex-end; gap: 8px; }\n.b316-field { display: flex; flex-direction: column; gap: 4px; }\n.b316-hint { font-size: 0.82em; color: var(--b316-color-muted); }\n.b316-input-invalid { border-color: var(--b316-color-danger, #b42318); }\n.b316-choices { display: flex; flex-wrap: wrap; gap: 10px; }\n.b316-choice { display: inline-flex; align-items: center; gap: 6px; font-size: 0.95em; }\n.b316-suffixed { display: flex; align-items: center; gap: 8px; }\n.b316-address { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }\n\n.b316-relation-chosen { display: flex; align-items: center; gap: 8px; }\n.b316-relation-results {\n list-style: none;\n margin: 4px 0 0;\n padding: 4px;\n border: 1px solid var(--b316-color-border);\n border-radius: var(--b316-radius);\n max-height: 220px;\n overflow-y: auto;\n background: var(--b316-color-surface, #fff);\n}\n.b316-relation-result { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 6px 8px; font: inherit; cursor: pointer; border-radius: calc(var(--b316-radius) / 2); }\n.b316-relation-result:hover, .b316-relation-result:focus-visible { background: var(--b316-color-surface-muted, rgba(0,0,0,.05)); outline: none; }\n.b316-relation-empty { padding: 6px 8px; }\n\n.b316-detail { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-detail-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--b316-spacing); }\n.b316-detail-title { margin: 0; font-size: 1.1em; }\n.b316-detail-actions { display: flex; gap: 4px; }\n.b316-detail-fields { display: grid; grid-template-columns: minmax(120px, 200px) 1fr; gap: 8px var(--b316-spacing); margin: 0; }\n.b316-detail-row { display: contents; }\n.b316-detail-fields dd { margin: 0; }\n\n/* One column on a narrow screen. A label column of 200px beside a value leaves\n nothing for the value on a phone. */\n/* --- Teams --------------------------------------------------------------- */\n\n.b316-team { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-team-title { margin: 0; font-size: 1em; font-weight: 600; }\n.b316-team-subtitle { margin: 0; font-size: .9em; font-weight: 600; color: var(--b316-color-muted); }\n.b316-team-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }\n.b316-team-member { display: flex; align-items: center; justify-content: space-between; gap: var(--b316-spacing); }\n.b316-team-member-side { display: flex; align-items: center; gap: 8px; }\n.b316-team-invite { display: flex; flex-direction: column; gap: 4px; }\n.b316-team-invite-row { display: flex; gap: 8px; }\n.b316-team-invite-row input { flex: 1; }\n/* Selectable and wrapping: this is copied by hand and pasted into an email. */\n.b316-team-link { display: flex; flex-direction: column; gap: 4px; }\n.b316-team-link code { word-break: break-all; user-select: all; padding: 8px; border: 1px solid var(--b316-color-border); border-radius: var(--b316-radius); }\n\n.b316-invitation { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-invitation-actions { display: flex; align-items: center; gap: var(--b316-spacing); }\n\n/* --- Sessions, two-factor and the password flows ------------------------- */\n\n.b316-sessions { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-sessions-head { display: flex; align-items: center; justify-content: space-between; gap: var(--b316-spacing); flex-wrap: wrap; }\n.b316-sessions-title, .b316-mfa-title { margin: 0; font-size: 1em; font-weight: 600; }\n.b316-sessions-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }\n.b316-session { display: flex; flex-direction: column; gap: 2px; }\n.b316-session-device { display: flex; align-items: center; gap: 6px; font-size: 0.95em; }\n\n.b316-device { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-device-title { margin: 0; font-size: 1em; font-weight: 600; }\n/* What is being granted, listed rather than run together: somebody is deciding\n on this, and a comma-separated line is read as one thing. */\n.b316-device-scopes { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }\n.b316-device-scopes li { padding: 2px 8px; border-radius: 999px; font-size: 0.85em; background: var(--b316-color-surface-muted, rgba(0,0,0,.05)); }\n.b316-device-actions { display: flex; gap: 8px; }\n\n.b316-privacy { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-privacy-title { margin: 0; font-size: 1em; font-weight: 600; }\n/* Wraps rather than squeezes: the explanation beside each control is the part\n that matters, and on a narrow screen it belongs above the button. */\n.b316-privacy-row { display: flex; flex-wrap: wrap; align-items: start; justify-content: space-between; gap: 10px; }\n.b316-privacy-row p { margin: 0; }\n.b316-privacy-confirm { display: flex; flex-direction: column; gap: 8px; }\n.b316-privacy-actions { display: flex; justify-content: flex-end; gap: 8px; }\n\n.b316-mfa { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-mfa-enrol, .b316-mfa-codes, .b316-mfa-on, .b316-mfa-off { display: flex; flex-direction: column; gap: 10px; }\n.b316-mfa-actions { display: flex; justify-content: flex-end; gap: 8px; }\n/* Selectable and wrapping: this is copied by hand on the device that cannot\n scan its own screen. */\n.b316-mfa-secret code {\n display: block;\n padding: 10px;\n border: 1px solid var(--b316-color-border);\n border-radius: var(--b316-radius);\n font-size: 1.05em;\n letter-spacing: .08em;\n word-break: break-all;\n user-select: all;\n}\n.b316-mfa-uri { font-size: 0.9em; }\n.b316-mfa-code-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }\n.b316-mfa-code-list code { user-select: all; }\n/* The enrolment choices: whole-width buttons with their explanation inside,\n so the explanation is part of what a screen reader announces. */\n.b316-mfa-methods { display: flex; flex-direction: column; gap: 8px; border: 0; margin: 0; padding: 0; min-width: 0; }\n.b316-mfa-method { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%; text-align: left; }\n.b316-mfa-method .b316-muted { font-weight: 400; }\n/* Always on white with a margin: a QR code on a dark theme does not scan. */\n.b316-mfa-qr { align-self: center; width: 180px; height: 180px; padding: 8px; background: #fff; border-radius: var(--b316-radius); }\n\n@media (max-width: 560px) {\n .b316-mfa-code-list { grid-template-columns: 1fr; }\n .b316-detail-fields { grid-template-columns: 1fr; }\n .b316-detail-row { display: block; margin-bottom: 10px; }\n .b316-address { grid-template-columns: 1fr; }\n}\n\n/* --- Board --------------------------------------------------------------- */\n\n.b316-board-wrap { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n/* The board scrolls sideways inside itself. Six columns is normal and a page\n that scrolls horizontally puts everything else on it out of reach. */\n.b316-board { display: flex; gap: var(--b316-spacing); overflow-x: auto; align-items: flex-start; padding-bottom: 4px; }\n.b316-board-column {\n flex: 0 0 260px;\n background: var(--b316-color-surface-muted, rgba(0,0,0,.03));\n border: 1px solid transparent;\n border-radius: var(--b316-radius);\n padding: 10px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.b316-board-over { border-color: var(--b316-color-primary); }\n.b316-board-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }\n.b316-board-title { font-weight: 600; font-size: 0.92em; }\n.b316-board-cards { display: flex; flex-direction: column; gap: 8px; min-height: 40px; }\n.b316-board-card {\n background: var(--b316-color-surface, #fff);\n border: 1px solid var(--b316-color-border);\n border-radius: calc(var(--b316-radius) * .8);\n padding: 10px;\n display: flex;\n flex-direction: column;\n gap: 6px;\n font-size: 0.9em;\n}\n.b316-board-card[draggable=\"true\"] { cursor: grab; }\n.b316-board-card-title { font-weight: 600; }\n.b316-board-card-field { display: flex; justify-content: space-between; gap: 8px; }\n.b316-board-move { display: flex; align-items: center; gap: 6px; margin-top: 2px; }\n.b316-board-move select { flex: 1; font-size: 0.9em; padding: 2px 4px; }\n.b316-board-empty { color: var(--b316-color-muted); font-size: 0.87em; padding: 6px 2px; }\n\n/* --- Chart --------------------------------------------------------------- */\n\n.b316-chart { display: flex; flex-direction: column; gap: var(--b316-spacing); }\n.b316-chart-title { font-weight: 600; font-size: 0.95em; }\n.b316-chart-plot { display: flex; align-items: flex-end; gap: 4px; overflow-x: auto; }\n.b316-chart-col { flex: 1 0 24px; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; gap: 4px; }\n.b316-chart-bar { width: 100%; background: var(--b316-color-primary); border-radius: 3px 3px 0 0; min-height: 2px; }\n.b316-chart-label { font-size: 0.7em; color: var(--b316-color-muted); white-space: nowrap; transform: rotate(-45deg); transform-origin: top left; height: 1.6em; }\n.b316-chart-data summary { cursor: pointer; font-size: 0.87em; color: var(--b316-color-muted); }\n.b316-chart-data table { margin-top: 8px; }\n\n/* --- Billing portal ------------------------------------------------------ */\n\n.b316-billing-portal { display: grid; gap: var(--b316-spacing); }\n.b316-billing-portal-section-title { font-weight: 600; font-size: 1em; margin: 0 0 8px; }\n.b316-billing-portal .b316-plans { margin: 0; }\n.b316-invoice-row-actions { white-space: nowrap; text-align: right; }\n.b316-invoice-row-actions .b316-button-link + .b316-button-link { margin-left: 8px; }\n.b316-review-table { width: 100%; border-collapse: collapse; font-size: 0.92em; margin: 8px 0; }\n.b316-review-table th, .b316-review-table td { text-align: left; padding: 6px 4px; border-top: 1px solid var(--b316-color-border, #e5e7eb); }\n.b316-review-table th { color: var(--b316-color-muted); font-weight: 500; border-top: 0; }\n.b316-review-gain { color: #065f46; }\n.b316-review-loss { color: var(--b316-color-danger); }\n.b316-review-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }\n@media (max-width: 560px) {\n .b316-invoice-table th:nth-child(2), .b316-invoice-table td:nth-child(2) { display: none; }\n .b316-review-actions .b316-button { flex: 1 1 100%; }\n}\n";
63
63
  //# sourceMappingURL=appearance.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"appearance.d.ts","sourceRoot":"","sources":["../../src/appearance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,MAAM,WAAW,iBAAiB;IACjC,mCAAmC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAkBD,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,UAAU,CAAC,EAAE,iBAAiB,GAAG,aAAa,CAgB/E;AAED,eAAO,MAAM,gBAAgB,uBAAuB,CAAC;AAErD;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,yiOA8OtB,CAAC;AAEF,kEAAkE;AAClE,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,+gfAgT5B,CAAC"}
1
+ {"version":3,"file":"appearance.d.ts","sourceRoot":"","sources":["../../src/appearance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,MAAM,WAAW,iBAAiB;IACjC,mCAAmC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAkBD,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,UAAU,CAAC,EAAE,iBAAiB,GAAG,aAAa,CAgB/E;AAED,eAAO,MAAM,gBAAgB,uBAAuB,CAAC;AAErD;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,yiOA8OtB,CAAC;AAEF,kEAAkE;AAClE,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,8xiBAyU5B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH;;;;GAIG;AACH,MAAM,MAAM,WAAW;AACtB,8EAA8E;AAC5E,SAAS;AACX,gFAAgF;GAC9E,YAAY;AACd,kDAAkD;GAChD,OAAO;AACT,mFAAmF;GACjF,gBAAgB;AAClB,mEAAmE;GACjE,aAAa,CAAC;AAEjB,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,UAAU,CAAC;IACxC,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAOD,eAAO,MAAM,QAAQ,EAAE,aAAa,EAymBnC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW;aACvB,KAAK,YACJ,qEAAqE,EACrE,yIAAyI,EACzI,2JAA2J,EAC3J,+QAA+Q,EAC/Q,0ZAA0Z,EAC1Z,4KAA4K;IAE7K,uDAAuD;aACvD,OAAO;CAyBE,CAAC;AAEX,2BAA2B;AAC3B,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAEzE;AAED,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,WAAW,GAAG,aAAa,EAAE,CAE7E"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH;;;;GAIG;AACH,MAAM,MAAM,WAAW;AACtB,8EAA8E;AAC5E,SAAS;AACX,gFAAgF;GAC9E,YAAY;AACd,kDAAkD;GAChD,OAAO;AACT,mFAAmF;GACjF,gBAAgB;AAClB,mEAAmE;GACjE,aAAa,CAAC;AAEjB,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,UAAU,CAAC;IACxC,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,wDAAwD;IACxD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAOD,eAAO,MAAM,QAAQ,EAAE,aAAa,EAo3BnC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW;aACvB,KAAK,YACJ,qEAAqE,EACrE,yIAAyI,EACzI,2JAA2J,EAC3J,+QAA+Q,EAC/Q,0ZAA0Z,EAC1Z,4KAA4K;IAE7K,uDAAuD;aACvD,OAAO;CAyBE,CAAC;AAEX,2BAA2B;AAC3B,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAEzE;AAED,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,WAAW,GAAG,aAAa,EAAE,CAE7E"}
@@ -20,6 +20,15 @@ import type { PublicPlan } from "@base316/sdk";
20
20
  export type SelectPlanOutcome = {
21
21
  status: "changed";
22
22
  planVersionId: string;
23
+ }
24
+ /**
25
+ * A downgrade, scheduled for the renewal rather than made now: the user
26
+ * keeps the plan they paid for until `effectiveAt`, so it stays current.
27
+ */
28
+ | {
29
+ status: "scheduled";
30
+ planVersionId: string;
31
+ effectiveAt: string | null;
23
32
  } | {
24
33
  status: "checkout";
25
34
  url: string;
@@ -1 +1 @@
1
- {"version":3,"file":"usePlans.d.ts","sourceRoot":"","sources":["../../src/usePlans.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAK/C;;;;;;;;;;;;;;;;GAgBG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,iBAAiB,GAC1B;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,MAAM,EAAE,eAAe,CAAA;CAAE,GAC3B;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC,MAAM,WAAW,eAAe;IAC/B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,cAAc;IAC9B,+DAA+D;IAC/D,KAAK,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,sDAAsD;IACtD,KAAK,EAAE,OAAO,CAAC;IACf,yDAAyD;IACzD,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,sEAAsE;IACtE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,6EAA6E;IAC7E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,0CAA0C;IAC1C,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1C,UAAU,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC7D,MAAM,EAAE,MAAM,IAAI,CAAC;CACnB;AAaD,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,cAAc,CAwJtE"}
1
+ {"version":3,"file":"usePlans.d.ts","sourceRoot":"","sources":["../../src/usePlans.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAK/C;;;;;;;;;;;;;;;;GAgBG;AAEH,4EAA4E;AAC5E,MAAM,MAAM,iBAAiB,GAC1B;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE;AAC9C;;;GAGG;GACD;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC1E;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,MAAM,EAAE,eAAe,CAAA;CAAE,GAC3B;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC,MAAM,WAAW,eAAe;IAC/B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,cAAc;IAC9B,+DAA+D;IAC/D,KAAK,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,sDAAsD;IACtD,KAAK,EAAE,OAAO,CAAC;IACf,yDAAyD;IACzD,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,sEAAsE;IACtE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,6EAA6E;IAC7E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,0CAA0C;IAC1C,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1C,UAAU,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC7D,MAAM,EAAE,MAAM,IAAI,CAAC;CACnB;AAaD,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,cAAc,CAoKtE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@base316/react",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Drop-in React components for Base316 authentication and billing.",
5
5
  "homepage": "https://base316.com",
6
6
  "bugs": "https://github.com/ThinkfleetAI/base316/issues",
@@ -32,7 +32,7 @@
32
32
  "access": "public"
33
33
  },
34
34
  "dependencies": {
35
- "@base316/sdk": "0.3.0"
35
+ "@base316/sdk": "0.6.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@testing-library/dom": "^10.4.2",