@base316/react 0.1.0 → 0.3.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.
- package/CHANGELOG.md +53 -0
- package/README.md +29 -15
- package/dist/index.cjs +4361 -166
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4344 -164
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +1176 -0
- package/dist/src/AcceptInvitation.d.ts +27 -0
- package/dist/src/AcceptInvitation.d.ts.map +1 -0
- package/dist/src/ActiveSessions.d.ts +21 -0
- package/dist/src/ActiveSessions.d.ts.map +1 -0
- package/dist/src/ApiKeyManager.d.ts +22 -0
- package/dist/src/ApiKeyManager.d.ts.map +1 -0
- package/dist/src/Chart.d.ts +42 -0
- package/dist/src/Chart.d.ts.map +1 -0
- package/dist/src/DataTable.d.ts +56 -0
- package/dist/src/DataTable.d.ts.map +1 -0
- package/dist/src/DeviceApproval.d.ts +30 -0
- package/dist/src/DeviceApproval.d.ts.map +1 -0
- package/dist/src/ForgotPassword.d.ts +24 -0
- package/dist/src/ForgotPassword.d.ts.map +1 -0
- package/dist/src/Invoices.d.ts.map +1 -1
- package/dist/src/Kanban.d.ts +40 -0
- package/dist/src/Kanban.d.ts.map +1 -0
- package/dist/src/PasskeyManager.d.ts.map +1 -1
- package/dist/src/PayInvoice.d.ts +41 -0
- package/dist/src/PayInvoice.d.ts.map +1 -0
- package/dist/src/PricingTable.d.ts +43 -11
- package/dist/src/PricingTable.d.ts.map +1 -1
- package/dist/src/PrivacyControls.d.ts +28 -0
- package/dist/src/PrivacyControls.d.ts.map +1 -0
- package/dist/src/RecordDetail.d.ts +31 -0
- package/dist/src/RecordDetail.d.ts.map +1 -0
- package/dist/src/RecordForm.d.ts +32 -0
- package/dist/src/RecordForm.d.ts.map +1 -0
- package/dist/src/RelationPicker.d.ts +23 -0
- package/dist/src/RelationPicker.d.ts.map +1 -0
- package/dist/src/ResetPassword.d.ts +24 -0
- package/dist/src/ResetPassword.d.ts.map +1 -0
- package/dist/src/SignIn.d.ts +20 -2
- package/dist/src/SignIn.d.ts.map +1 -1
- package/dist/src/SignUp.d.ts.map +1 -1
- package/dist/src/SubscriptionManager.d.ts.map +1 -1
- package/dist/src/TeamMembers.d.ts +49 -0
- package/dist/src/TeamMembers.d.ts.map +1 -0
- package/dist/src/TwoFactorManager.d.ts +38 -0
- package/dist/src/TwoFactorManager.d.ts.map +1 -0
- package/dist/src/VerifyEmail.d.ts +24 -0
- package/dist/src/VerifyEmail.d.ts.map +1 -0
- package/dist/src/appearance.d.ts +2 -2
- package/dist/src/appearance.d.ts.map +1 -1
- package/dist/src/confirm.d.ts +32 -0
- package/dist/src/confirm.d.ts.map +1 -0
- package/dist/src/fields.d.ts +44 -0
- package/dist/src/fields.d.ts.map +1 -0
- package/dist/src/manifest.d.ts +84 -0
- package/dist/src/manifest.d.ts.map +1 -0
- package/dist/src/provider.d.ts +13 -1
- package/dist/src/provider.d.ts.map +1 -1
- package/dist/src/test/harness.d.ts +204 -0
- package/dist/src/test/harness.d.ts.map +1 -0
- package/dist/src/test/setup.d.ts +2 -0
- package/dist/src/test/setup.d.ts.map +1 -0
- package/dist/src/useCollection.d.ts +79 -0
- package/dist/src/useCollection.d.ts.map +1 -0
- package/dist/src/usePaymentLink.d.ts +41 -0
- package/dist/src/usePaymentLink.d.ts.map +1 -0
- package/dist/src/usePlans.d.ts +74 -0
- package/dist/src/usePlans.d.ts.map +1 -0
- package/package.json +36 -28
package/dist/src/SignIn.d.ts
CHANGED
|
@@ -1,15 +1,33 @@
|
|
|
1
1
|
import { type CSSProperties } from "react";
|
|
2
2
|
/**
|
|
3
|
-
* Email and password sign-in
|
|
3
|
+
* Email and password sign-in, and — where the application turns them on — a
|
|
4
|
+
* magic link or a code by text message.
|
|
4
5
|
*
|
|
5
6
|
* Handles the MFA branch, because an account with a second factor gets a
|
|
6
7
|
* challenge instead of a session, and a form that ignores that case appears to
|
|
7
8
|
* fail for exactly the users who most need it to work.
|
|
8
9
|
*/
|
|
9
|
-
export declare function SignIn({ onSignedIn, passkeys, className, style, }: {
|
|
10
|
+
export declare function SignIn({ onSignedIn, passkeys, magicLinkRedirectUrl, phone, className, style, }: {
|
|
10
11
|
onSignedIn?: () => void;
|
|
11
12
|
/** Offer passkeys alongside the password. On by default where supported. */
|
|
12
13
|
passkeys?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Where an emailed sign-in link lands. Offering magic link at all requires
|
|
16
|
+
* it, because the link has to point somewhere this application controls —
|
|
17
|
+
* and the URL must be registered on the environment's sign-in page, the same
|
|
18
|
+
* list that governs redirects.
|
|
19
|
+
*
|
|
20
|
+
* The page it names should render this component: arriving with `?token=`
|
|
21
|
+
* redeems it automatically.
|
|
22
|
+
*/
|
|
23
|
+
magicLinkRedirectUrl?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Offer signing in with a code sent by text message.
|
|
26
|
+
*
|
|
27
|
+
* Off by default, because it needs the environment switched on for it and,
|
|
28
|
+
* in production, the environment's own Twilio account.
|
|
29
|
+
*/
|
|
30
|
+
phone?: boolean;
|
|
13
31
|
className?: string;
|
|
14
32
|
style?: CSSProperties;
|
|
15
33
|
}): import("react").JSX.Element;
|
package/dist/src/SignIn.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignIn.d.ts","sourceRoot":"","sources":["../../src/SignIn.tsx"],"names":[],"mappings":"
|
|
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"}
|
package/dist/src/SignUp.d.ts.map
CHANGED
|
@@ -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,+
|
|
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 +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,+
|
|
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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Who is in a team, who has been invited, and the way in and out.
|
|
4
|
+
*
|
|
5
|
+
* One component rather than four, because these are one screen everywhere they
|
|
6
|
+
* appear: a list of people, a list of people who have not arrived yet, a box to
|
|
7
|
+
* add another, and a way to leave. Splitting them would make the common case —
|
|
8
|
+
* a Team settings page — four imports and some layout, which is exactly the
|
|
9
|
+
* assembly work the catalogue exists to remove.
|
|
10
|
+
*
|
|
11
|
+
* What it offers depends on what the viewer may do, and that is the server's
|
|
12
|
+
* answer rather than this component's guess: inviting and removing are gated on
|
|
13
|
+
* a permission the customer's own roles grant, so a member who cannot manage
|
|
14
|
+
* the team simply is not shown those controls.
|
|
15
|
+
*
|
|
16
|
+
* Sending the invitation email is the application's job. The token comes back
|
|
17
|
+
* once from the API and is never recoverable, so `onInvited` is where it goes —
|
|
18
|
+
* without a handler, the link is shown on screen to be copied, which is honest
|
|
19
|
+
* rather than silently losing it.
|
|
20
|
+
*/
|
|
21
|
+
export interface TeamMembersProps {
|
|
22
|
+
/**
|
|
23
|
+
* Which team. Defaults to the only one this person is in.
|
|
24
|
+
*
|
|
25
|
+
* Left out with several, the component says which is which rather than
|
|
26
|
+
* guessing — picking one at random is how somebody invites a colleague into
|
|
27
|
+
* the wrong company.
|
|
28
|
+
*/
|
|
29
|
+
organizationId?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Called with the invitation link after inviting.
|
|
32
|
+
*
|
|
33
|
+
* Where an application sends the email. Without it the link is shown on
|
|
34
|
+
* screen instead, because the token is returned once and cannot be fetched
|
|
35
|
+
* again.
|
|
36
|
+
*/
|
|
37
|
+
onInvited?: (invitation: {
|
|
38
|
+
email: string;
|
|
39
|
+
token: string;
|
|
40
|
+
url?: string;
|
|
41
|
+
}) => void;
|
|
42
|
+
/** Where an invitation link should point. Used to build the URL for `onInvited`. */
|
|
43
|
+
acceptUrl?: string;
|
|
44
|
+
onLeft?: () => void;
|
|
45
|
+
className?: string;
|
|
46
|
+
style?: CSSProperties;
|
|
47
|
+
}
|
|
48
|
+
export declare function TeamMembers({ organizationId, onInvited, acceptUrl, onLeft, className, style, }: TeamMembersProps): import("react").JSX.Element | null;
|
|
49
|
+
//# sourceMappingURL=TeamMembers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TeamMembers.d.ts","sourceRoot":"","sources":["../../src/TeamMembers.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAM7E;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,gBAAgB;IAChC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACjF,oFAAoF;IACpF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,wBAAgB,WAAW,CAAC,EAC3B,cAAc,EACd,SAAS,EACT,SAAS,EACT,MAAM,EACN,SAAS,EACT,KAAK,GACL,EAAE,gBAAgB,sCA0QlB"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Turning on two-factor authentication.
|
|
4
|
+
*
|
|
5
|
+
* Three ways in: an authenticator app, a code to the inbox, and — where the
|
|
6
|
+
* application turns it on — a code by text message. The app is the strongest
|
|
7
|
+
* and is offered first; the other two are the ones people who will not install
|
|
8
|
+
* anything actually use, and a factor somebody turns on beats a stronger one
|
|
9
|
+
* they decline.
|
|
10
|
+
*
|
|
11
|
+
* Three steps, kept separate because the middle one is what stops people
|
|
12
|
+
* locking themselves out: enrolling produces a secret that is useless until a
|
|
13
|
+
* code proves the app actually holds it. Activating on enrolment would mean a
|
|
14
|
+
* QR code that failed to scan leaves somebody unable to sign in, with no way
|
|
15
|
+
* back.
|
|
16
|
+
*
|
|
17
|
+
* The recovery codes are shown once. They are password equivalents, so nothing
|
|
18
|
+
* stores them anywhere they can be read back — which makes "I have saved these"
|
|
19
|
+
* a real step rather than a formality, and the dialog says so.
|
|
20
|
+
*/
|
|
21
|
+
export interface TwoFactorManagerProps {
|
|
22
|
+
/** Whether this account already has a factor. Drives which side is shown. */
|
|
23
|
+
enabled?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Offer a code by text message.
|
|
26
|
+
*
|
|
27
|
+
* Off by default, because it only works once the environment can send one —
|
|
28
|
+
* its own Twilio account in production — and a button that can only fail is
|
|
29
|
+
* worse than no button.
|
|
30
|
+
*/
|
|
31
|
+
allowSms?: boolean;
|
|
32
|
+
onEnabled?: () => void;
|
|
33
|
+
onDisabled?: () => void;
|
|
34
|
+
className?: string;
|
|
35
|
+
style?: CSSProperties;
|
|
36
|
+
}
|
|
37
|
+
export declare function TwoFactorManager({ enabled, allowSms, onEnabled, onDisabled, className, style, }: TwoFactorManagerProps): import("react").JSX.Element | null;
|
|
38
|
+
//# sourceMappingURL=TwoFactorManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TwoFactorManager.d.ts","sourceRoot":"","sources":["../../src/TwoFactorManager.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAMrD;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,qBAAqB;IACrC,6EAA6E;IAC7E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAWD,wBAAgB,gBAAgB,CAAC,EAChC,OAAe,EACf,QAAgB,EAChB,SAAS,EACT,UAAU,EACV,SAAS,EACT,KAAK,GACL,EAAE,qBAAqB,sCA+RvB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Confirming an address from an emailed link.
|
|
4
|
+
*
|
|
5
|
+
* The whole component is one effect: read `?token=`, spend it, say what
|
|
6
|
+
* happened. Two details carry it.
|
|
7
|
+
*
|
|
8
|
+
* The token is removed from the URL before it is spent, so it does not sit in
|
|
9
|
+
* browser history or leak through a referrer. And the effect runs exactly once
|
|
10
|
+
* — the token is single-use, so a re-run in development's double-invoked
|
|
11
|
+
* effects would spend it and then report that it was invalid, which looks like
|
|
12
|
+
* a broken link to everybody who sees it.
|
|
13
|
+
*/
|
|
14
|
+
export interface VerifyEmailProps {
|
|
15
|
+
/** Supply the token directly. Read from `?token=` when omitted. */
|
|
16
|
+
token?: string;
|
|
17
|
+
onVerified?: () => void;
|
|
18
|
+
/** Where to go next. Rendered as a link when given. */
|
|
19
|
+
continueUrl?: string;
|
|
20
|
+
className?: string;
|
|
21
|
+
style?: CSSProperties;
|
|
22
|
+
}
|
|
23
|
+
export declare function VerifyEmail({ token: supplied, onVerified, continueUrl, className, style, }: VerifyEmailProps): import("react").JSX.Element;
|
|
24
|
+
//# sourceMappingURL=VerifyEmail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VerifyEmail.d.ts","sourceRoot":"","sources":["../../src/VerifyEmail.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA+B,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAKxE;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,gBAAgB;IAChC,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACtB;AAID,wBAAgB,WAAW,CAAC,EAC3B,KAAK,EAAE,QAAQ,EACf,UAAU,EACV,WAAW,EACX,SAAS,EACT,KAAK,GACL,EAAE,gBAAgB,+BAiFlB"}
|
package/dist/src/appearance.d.ts
CHANGED
|
@@ -50,7 +50,7 @@ export declare const STYLE_ELEMENT_ID = "base316-components";
|
|
|
50
50
|
* never sets a token still gets a coherent look, and one that sets tokens on a
|
|
51
51
|
* parent still wins through normal inheritance.
|
|
52
52
|
*/
|
|
53
|
-
export declare const STYLESHEET = "\n.b316-root {\n --b316-color-primary: #111827;\n --b316-color-primary-text: #ffffff;\n --b316-color-text: #111827;\n --b316-color-muted: #6b7280;\n --b316-color-background: #ffffff;\n --b316-color-border: #e5e7eb;\n --b316-color-danger: #991b1b;\n --b316-color-danger-bg: #fef2f2;\n --b316-color-success: #166534;\n --b316-radius: 12px;\n --b316-font: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n --b316-font-size: 15px;\n --b316-spacing: 12px;\n\n font-family: var(--b316-font);\n font-size: var(--b316-font-size);\n line-height: 1.5;\n color: var(--b316-color-text);\n}\n\n.b316-card {\n border: 1px solid var(--b316-color-border);\n border-radius: var(--b316-radius);\n padding: calc(var(--b316-spacing) * 1.6);\n background: var(--b316-color-background);\n}\n\n.b316-field { display: flex; flex-direction: column; gap: 4px; margin-bottom: var(--b316-spacing); }\n.b316-label { font-size: 0.87em; color: var(--b316-color-muted); }\n\n.b316-input {\n padding: 9px 11px;\n border: 1px solid var(--b316-color-border);\n border-radius: calc(var(--b316-radius) / 1.6);\n font: inherit;\n color: inherit;\n background: var(--b316-color-background);\n}\n.b316-input:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 1px; }\n\n.b316-button {\n width: 100%;\n padding: 10px 14px;\n border: 0;\n border-radius: calc(var(--b316-radius) / 1.6);\n background: var(--b316-color-primary);\n color: var(--b316-color-primary-text);\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n}\n.b316-button:hover:not([disabled]) { filter: brightness(1.12); }\n.b316-button:active:not([disabled]) { transform: translateY(1px); }\n.b316-button:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 2px; }\n.b316-button[disabled] { opacity: .55; cursor: not-allowed; }\n\n.b316-button-secondary {\n width: auto;\n transition: background-color .12s ease;\n background: var(--b316-color-background);\n color: var(--b316-color-text);\n border: 1px solid var(--b316-color-border);\n font-weight: 500;\n}\n\n.b316-button-link {\n width: auto;\n background: none;\n border: 0;\n padding: 0;\n color: var(--b316-color-primary);\n font: inherit;\n cursor: pointer;\n text-decoration: underline;\n}\n\n.b316-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-muted { color: var(--b316-color-muted); font-size: 0.87em; }\n.b316-success { color: var(--b316-color-success); }\n\n.b316-plans {\n display: grid;\n gap: calc(var(--b316-spacing) * 1.3);\n grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));\n align-items: stretch;\n}\n\n.b316-plan {\n display: flex;\n flex-direction: column;\n padding: 0;\n overflow: hidden;\n}\n\n/* The recommended plan. Lifted rather than merely tinted: on a pricing table\n the eye needs one obvious default, and colour alone does not survive being\n viewed in greyscale or by someone who cannot distinguish the accent. */\n.b316-plan-featured {\n border-color: var(--b316-color-primary);\n box-shadow: 0 0 0 1px var(--b316-color-primary);\n}\n\n.b316-plan-badge {\n display: inline-block;\n background: var(--b316-color-primary);\n color: var(--b316-color-primary-text);\n border-radius: 999px;\n padding: 2px 9px;\n font-size: 0.75em;\n font-weight: 600;\n letter-spacing: .02em;\n margin-bottom: 8px;\n}\n\n/* Occupies the badge's height without drawing anything, so a featured card\n does not push its own price and features out of line with the others. */\n.b316-plan-badge-spacer {\n display: inline-block;\n padding: 2px 9px;\n font-size: 0.75em;\n margin-bottom: 8px;\n visibility: hidden;\n}\n\n.b316-plan-head { padding: calc(var(--b316-spacing) * 1.6); padding-bottom: 0; }\n.b316-plan-name { font-weight: 600; font-size: 1.06em; }\n.b316-plan-desc { color: var(--b316-color-muted); font-size: 0.87em; margin-top: 2px; }\n\n.b316-plan-pricing { padding: 0 calc(var(--b316-spacing) * 1.6) calc(var(--b316-spacing) * 1.4); }\n\n.b316-plan-price {\n font-size: 2.1em;\n font-weight: 640;\n letter-spacing: -.02em;\n margin-top: calc(var(--b316-spacing) * 0.7);\n /* Lining figures of even width, so prices do not shimmer between cards. */\n font-variant-numeric: tabular-nums lining-nums;\n}\n\n.b316-plan-cadence { color: var(--b316-color-muted); font-size: 0.87em; min-height: 1.35em; }\n.b316-plan-trial { color: var(--b316-color-success); font-size: 0.87em; min-height: 1.35em; }\n\n.b316-plan-features {\n list-style: none;\n padding: calc(var(--b316-spacing) * 1.2) calc(var(--b316-spacing) * 1.6);\n margin: 0;\n flex: 1;\n border-top: 1px solid var(--b316-color-border);\n}\n.b316-plan-feature {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n padding: 5px 0;\n font-size: 0.94em;\n}\n.b316-plan-feature-value { color: var(--b316-color-muted); font-variant-numeric: tabular-nums; }\n\n.b316-plan-action {\n padding: calc(var(--b316-spacing) * 1.2) calc(var(--b316-spacing) * 1.6);\n border-top: 1px solid var(--b316-color-border);\n}\n\n/* The plan already held. A faded primary button reads as broken rather than\n as \"you are here\", so this is a flat, quiet, genuinely inert surface. */\n.b316-button-current,\n.b316-button-current[disabled] {\n background: transparent;\n color: var(--b316-color-muted);\n border: 1px solid var(--b316-color-border);\n font-weight: 500;\n opacity: 1;\n cursor: default;\n}\n\n.b316-row { display: flex; justify-content: space-between; gap: 16px; align-items: center; }\n";
|
|
53
|
+
export declare const STYLESHEET = "\n.b316-root {\n --b316-color-primary: #111827;\n --b316-color-primary-text: #ffffff;\n --b316-color-text: #111827;\n --b316-color-muted: #6b7280;\n --b316-color-background: #ffffff;\n --b316-color-border: #e5e7eb;\n --b316-color-danger: #991b1b;\n --b316-color-danger-bg: #fef2f2;\n --b316-color-success: #166534;\n --b316-radius: 12px;\n --b316-font: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n --b316-font-size: 15px;\n --b316-spacing: 12px;\n\n font-family: var(--b316-font);\n font-size: var(--b316-font-size);\n line-height: 1.5;\n color: var(--b316-color-text);\n}\n\n.b316-card {\n border: 1px solid var(--b316-color-border);\n border-radius: var(--b316-radius);\n padding: calc(var(--b316-spacing) * 1.6);\n background: var(--b316-color-background);\n}\n\n.b316-field { display: flex; flex-direction: column; gap: 4px; margin-bottom: var(--b316-spacing); }\n.b316-label { font-size: 0.87em; color: var(--b316-color-muted); }\n\n.b316-input {\n padding: 9px 11px;\n border: 1px solid var(--b316-color-border);\n border-radius: calc(var(--b316-radius) / 1.6);\n font: inherit;\n color: inherit;\n background: var(--b316-color-background);\n}\n.b316-input:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 1px; }\n\n.b316-button {\n width: 100%;\n padding: 10px 14px;\n border: 0;\n border-radius: calc(var(--b316-radius) / 1.6);\n background: var(--b316-color-primary);\n color: var(--b316-color-primary-text);\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n}\n.b316-button:hover:not([disabled]) { filter: brightness(1.12); }\n.b316-button:active:not([disabled]) { transform: translateY(1px); }\n.b316-button:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 2px; }\n.b316-button[disabled] { opacity: .55; cursor: not-allowed; }\n\n.b316-button-secondary {\n width: auto;\n transition: background-color .12s ease;\n background: var(--b316-color-background);\n color: var(--b316-color-text);\n border: 1px solid var(--b316-color-border);\n font-weight: 500;\n}\n\n.b316-button-link {\n width: auto;\n background: none;\n border: 0;\n padding: 0;\n color: var(--b316-color-primary);\n font: inherit;\n cursor: pointer;\n text-decoration: underline;\n}\n\n/*\n * An armed confirmation: the question and its way out, side by side.\n *\n * Inline rather than a dialog, because a sandboxed iframe does not get dialogs\n * and these components are meant to be embedded in one.\n */\n.b316-confirm {\n display: inline-flex;\n gap: .4rem;\n align-items: center;\n}\n\n.b316-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-muted { color: var(--b316-color-muted); font-size: 0.87em; }\n.b316-success { color: var(--b316-color-success); }\n\n.b316-plans {\n display: grid;\n gap: calc(var(--b316-spacing) * 1.3);\n grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));\n align-items: stretch;\n}\n\n/* Messages above the cards span the row rather than taking a card's column. */\n.b316-plans-error,\n.b316-plans-managed { grid-column: 1 / -1; }\n\n.b316-plan {\n display: flex;\n flex-direction: column;\n padding: 0;\n overflow: hidden;\n}\n\n/* The recommended plan. Lifted rather than merely tinted: on a pricing table\n the eye needs one obvious default, and colour alone does not survive being\n viewed in greyscale or by someone who cannot distinguish the accent. */\n.b316-plan-featured {\n border-color: var(--b316-color-primary);\n box-shadow: 0 0 0 1px var(--b316-color-primary);\n}\n\n.b316-plan-badge {\n display: inline-block;\n background: var(--b316-color-primary);\n color: var(--b316-color-primary-text);\n border-radius: 999px;\n padding: 2px 9px;\n font-size: 0.75em;\n font-weight: 600;\n letter-spacing: .02em;\n margin-bottom: 8px;\n}\n\n/* Occupies the badge's height without drawing anything, so a featured card\n does not push its own price and features out of line with the others. */\n.b316-plan-badge-spacer {\n display: inline-block;\n padding: 2px 9px;\n font-size: 0.75em;\n margin-bottom: 8px;\n visibility: hidden;\n}\n\n.b316-plan-head { padding: calc(var(--b316-spacing) * 1.6); padding-bottom: 0; }\n.b316-plan-name { font-weight: 600; font-size: 1.06em; }\n.b316-plan-desc { color: var(--b316-color-muted); font-size: 0.87em; margin-top: 2px; }\n\n.b316-plan-pricing { padding: 0 calc(var(--b316-spacing) * 1.6) calc(var(--b316-spacing) * 1.4); }\n\n.b316-plan-price {\n font-size: 2.1em;\n font-weight: 640;\n letter-spacing: -.02em;\n margin-top: calc(var(--b316-spacing) * 0.7);\n /* Lining figures of even width, so prices do not shimmer between cards. */\n font-variant-numeric: tabular-nums lining-nums;\n}\n\n.b316-plan-cadence { color: var(--b316-color-muted); font-size: 0.87em; min-height: 1.35em; }\n.b316-plan-trial { color: var(--b316-color-success); font-size: 0.87em; min-height: 1.35em; }\n\n.b316-plan-features {\n list-style: none;\n padding: calc(var(--b316-spacing) * 1.2) calc(var(--b316-spacing) * 1.6);\n margin: 0;\n flex: 1;\n border-top: 1px solid var(--b316-color-border);\n}\n.b316-plan-feature {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n padding: 5px 0;\n font-size: 0.94em;\n}\n.b316-plan-feature-value { color: var(--b316-color-muted); font-variant-numeric: tabular-nums; }\n\n.b316-plan-action {\n padding: calc(var(--b316-spacing) * 1.2) calc(var(--b316-spacing) * 1.6);\n border-top: 1px solid var(--b316-color-border);\n}\n\n/* The plan already held. A faded primary button reads as broken rather than\n as \"you are here\", so this is a flat, quiet, genuinely inert surface. */\n.b316-button-current,\n.b316-button-current[disabled] {\n background: transparent;\n color: var(--b316-color-muted);\n border: 1px solid var(--b316-color-border);\n font-weight: 500;\n opacity: 1;\n cursor: default;\n}\n\n.b316-row { display: flex; justify-content: space-between; gap: 16px; align-items: center; }\n\n/* Credential lists. A row is a thing plus the actions on it, and the actions\n stay put as names vary in length, so the eye tracks one column not two. */\n.b316-list { list-style: none; margin: 0; padding: 0; }\n\n.b316-list-item {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n padding: 12px 0;\n border-top: 1px solid var(--b316-color-border);\n}\n\n.b316-list-item:first-child { border-top: none; }\n\n/* Carries a secret shown exactly once, so it has to read as different from the\n rest of the card rather than as another paragraph. */\n.b316-notice {\n border: 1px solid var(--b316-color-border);\n border-radius: var(--b316-radius);\n background: var(--b316-color-subtle, rgba(0,0,0,0.03));\n padding: 12px;\n font-size: 0.93em;\n}\n\n.b316-checkbox {\n display: flex;\n align-items: baseline;\n gap: 8px;\n padding: 4px 0;\n cursor: pointer;\n}\n\n.b316-checkbox input[disabled] { cursor: default; }\n.b316-checkbox.b316-muted { cursor: default; }\n";
|
|
54
54
|
/** Join the component's own class with any the host passed in. */
|
|
55
55
|
export declare function cls(base: string, extra?: string): string;
|
|
56
56
|
/**
|
|
@@ -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-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 emits the invoice alone. Without this the browser would paginate the\n whole application around it, which is not something anyone wants to file. */\n@media print {\n body * { visibility: hidden; }\n .b316-invoice-doc, .b316-invoice-doc * { visibility: visible; }\n .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";
|
|
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";
|
|
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,
|
|
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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Asking "are you sure" without `window.confirm`.
|
|
4
|
+
*
|
|
5
|
+
* These components are embedded in the customer's own page, and a page that
|
|
6
|
+
* embeds them in a sandboxed iframe — which is the recommended way to embed
|
|
7
|
+
* anything — does not get modal dialogs unless `allow-modals` is set. Chrome
|
|
8
|
+
* and Firefox both block the call and return `false`.
|
|
9
|
+
*
|
|
10
|
+
* So `window.confirm` in this package was not a confirmation. It was a silent
|
|
11
|
+
* no: somebody clicked Revoke, the browser suppressed the dialog, the function
|
|
12
|
+
* returned false, and the component did nothing at all. No error, no dialog,
|
|
13
|
+
* nothing — the worst failure shape there is, because the user's next move is
|
|
14
|
+
* to click it again.
|
|
15
|
+
*
|
|
16
|
+
* The replacement asks in the page itself. One click arms it, a second
|
|
17
|
+
* confirms, and anywhere else cancels. No portal, no modal, no dependency on
|
|
18
|
+
* what the embedding page allows.
|
|
19
|
+
*/
|
|
20
|
+
export interface ConfirmButtonProps {
|
|
21
|
+
/** What the button says at rest. */
|
|
22
|
+
children: ReactNode;
|
|
23
|
+
/** What it says once armed. Make it name the consequence. */
|
|
24
|
+
confirmLabel: string;
|
|
25
|
+
onConfirm: () => void | Promise<void>;
|
|
26
|
+
className?: string;
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
/** How long the armed state survives without an answer. */
|
|
29
|
+
timeoutMs?: number;
|
|
30
|
+
}
|
|
31
|
+
export declare function ConfirmButton({ children, confirmLabel, onConfirm, className, disabled, timeoutMs, }: ConfirmButtonProps): import("react").JSX.Element;
|
|
32
|
+
//# sourceMappingURL=confirm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirm.d.ts","sourceRoot":"","sources":["../../src/confirm.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEpE;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,kBAAkB;IAClC,oCAAoC;IACpC,QAAQ,EAAE,SAAS,CAAC;IACpB,6DAA6D;IAC7D,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAQD,wBAAgB,aAAa,CAAC,EAC7B,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,SAAS,EACT,QAAQ,EACR,SAA8B,GAC9B,EAAE,kBAAkB,+BAwDpB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type FieldDescriptor, type FieldValue } from "@base316/sdk";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* How each field type looks, and how each is edited.
|
|
5
|
+
*
|
|
6
|
+
* The other half of the registry. `@base316/sdk`'s `fields.ts` says what a
|
|
7
|
+
* field *is* — groupable, summable, searchable — and this says what it looks
|
|
8
|
+
* like. They are split because the server needs the first and must never
|
|
9
|
+
* import React, and because a customer replacing the rendering should not have
|
|
10
|
+
* to restate the semantics.
|
|
11
|
+
*
|
|
12
|
+
* Every component goes through here rather than switching on types itself.
|
|
13
|
+
* That is what makes a new field type cheap: one entry in the SDK registry,
|
|
14
|
+
* one here, and the table, the form, the detail view and anything built later
|
|
15
|
+
* all understand it without being touched.
|
|
16
|
+
*/
|
|
17
|
+
export interface CellProps {
|
|
18
|
+
value: FieldValue;
|
|
19
|
+
field: FieldDescriptor;
|
|
20
|
+
/** A relation's resolved label, when this field is one. */
|
|
21
|
+
related?: {
|
|
22
|
+
id: string;
|
|
23
|
+
title: string | null;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface InputProps {
|
|
27
|
+
value: FieldValue;
|
|
28
|
+
field: FieldDescriptor;
|
|
29
|
+
onChange: (value: FieldValue) => void;
|
|
30
|
+
/** Rendered under the input. Set when the server rejected this field. */
|
|
31
|
+
error?: string | null;
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/** The cell for one field. Null and empty render as a dash, never as "null". */
|
|
35
|
+
export declare function FieldCell({ value, field, related }: CellProps): ReactNode;
|
|
36
|
+
/**
|
|
37
|
+
* The input for one field.
|
|
38
|
+
*
|
|
39
|
+
* Returns null for a computed field: an AUTONUMBER, LOOKUP or ROLLUP is
|
|
40
|
+
* produced by the server, and offering an input for one invites somebody to
|
|
41
|
+
* type a value that will be silently discarded.
|
|
42
|
+
*/
|
|
43
|
+
export declare function FieldInput({ value, field, onChange, error, disabled }: InputProps): ReactNode;
|
|
44
|
+
//# sourceMappingURL=fields.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../src/fields.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEN,KAAK,eAAe,EACpB,KAAK,UAAU,EAGf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,SAAS;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,eAAe,CAAC;IACvB,2DAA2D;IAC3D,OAAO,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CAC/C;AAED,MAAM,WAAW,UAAU;IAC1B,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAoCD,gFAAgF;AAChF,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,SAAS,GAAG,SAAS,CA8FzE;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,UAAU,GAAG,SAAS,CAwP7F"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What is in this package, described so that something assembling a page does
|
|
3
|
+
* not have to guess.
|
|
4
|
+
*
|
|
5
|
+
* The audience is an agent building an application, and a drag-and-drop canvas
|
|
6
|
+
* later. Both need the same four answers, and none of them can be had by
|
|
7
|
+
* reading a type definition:
|
|
8
|
+
*
|
|
9
|
+
* 1. **What exists.** Otherwise a component gets invented, and the failure is a
|
|
10
|
+
* build error nobody can act on.
|
|
11
|
+
* 2. **What it needs before it works.** This is the big one. Almost everything
|
|
12
|
+
* here renders nothing without a signed-in user — which looks like a broken
|
|
13
|
+
* component rather than a missing precondition, and is the single most
|
|
14
|
+
* expensive way to lose an hour with this package.
|
|
15
|
+
* 3. **Which sibling to reach for.** A table, a board and a chart all bind to a
|
|
16
|
+
* collection and answer different questions.
|
|
17
|
+
* 4. **What the props actually are.** Not their types — TypeScript has those —
|
|
18
|
+
* but what they mean and what happens when they are left out.
|
|
19
|
+
*
|
|
20
|
+
* Every component here takes no required props. That is a rule rather than a
|
|
21
|
+
* coincidence: a thing that cannot be dropped in as `<Thing />` is a thing an
|
|
22
|
+
* agent has to be taught, and the whole point is that it does not.
|
|
23
|
+
*
|
|
24
|
+
* **This file drifts if nobody stops it**, so `manifest.test.ts` fails when an
|
|
25
|
+
* export is added or removed without a matching entry. A manifest that lies is
|
|
26
|
+
* worse than no manifest, because both an agent and a person will believe it.
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* What must already be true, or the component renders nothing useful.
|
|
30
|
+
*
|
|
31
|
+
* Ordered by how often each one is the answer to "why is this blank".
|
|
32
|
+
*/
|
|
33
|
+
export type Requirement =
|
|
34
|
+
/** A signed-in end user. Without one, most of these render nothing at all. */
|
|
35
|
+
"session"
|
|
36
|
+
/** A collection defined in this environment, named by the `collection` prop. */
|
|
37
|
+
| "collection"
|
|
38
|
+
/** At least one published plan in the catalog. */
|
|
39
|
+
| "plans"
|
|
40
|
+
/** A connected payment account, or checkout refuses before a card is asked for. */
|
|
41
|
+
| "paymentAccount"
|
|
42
|
+
/** An API resource defined, so there are credentials to manage. */
|
|
43
|
+
| "apiResource";
|
|
44
|
+
export interface PropEntry {
|
|
45
|
+
name: string;
|
|
46
|
+
/** What it does, and what happens without it. */
|
|
47
|
+
summary: string;
|
|
48
|
+
/** True for none of them, by design. Present so the rule is machine-checkable. */
|
|
49
|
+
required: boolean;
|
|
50
|
+
}
|
|
51
|
+
export interface ManifestEntry {
|
|
52
|
+
name: string;
|
|
53
|
+
kind: "component" | "hook" | "provider";
|
|
54
|
+
/** One line: what this is. */
|
|
55
|
+
summary: string;
|
|
56
|
+
/** When to reach for this one rather than a sibling. */
|
|
57
|
+
useWhen: string;
|
|
58
|
+
requires: Requirement[];
|
|
59
|
+
/** Parameterised by a collection defined at runtime. */
|
|
60
|
+
bindsToCollection?: boolean;
|
|
61
|
+
props: PropEntry[];
|
|
62
|
+
/** What appears when a requirement is not met. The answer to "why is it blank". */
|
|
63
|
+
whenUnmet?: string;
|
|
64
|
+
seeAlso?: string[];
|
|
65
|
+
}
|
|
66
|
+
export declare const MANIFEST: ManifestEntry[];
|
|
67
|
+
/**
|
|
68
|
+
* How the pieces go together.
|
|
69
|
+
*
|
|
70
|
+
* Listed separately from the entries because it is not a fact about any one of
|
|
71
|
+
* them, and it is the thing most often got wrong: a component dropped outside
|
|
72
|
+
* the provider throws, and one dropped on a page with no signed-in user renders
|
|
73
|
+
* nothing and reads as broken. Neither is discoverable from a prop list.
|
|
74
|
+
*/
|
|
75
|
+
export declare const COMPOSITION: {
|
|
76
|
+
readonly rules: readonly ["Everything must be inside Base316Provider. Outside it, hooks throw.", "Most components need a signed-in user. Gate on useSession and render SignIn when there is none — see `requires: session` on each entry.", "A collection must exist before anything can bind to it. Define one in the dashboard under Collections, or through POST /v1/collections with a secret key.", "No component takes a prop you must supply to make it behave. Naming the subject is different: a collection component needs `collection` and a detail view needs `recordId`, because those say *what* to show rather than patch *how* it works. Everything else has a default.", "Each component bound to a collection holds its own data — DataTable, Kanban, Chart, RecordForm, RecordDetail, every one. None of them share a cache, so a write in one leaves the others showing what they already had. Put the form inside the table, where New and Edit refresh it; pass `onChanged` to refresh a sibling such as a Chart; or lift `useCollection` and render your own, which is what the hook is for.", "Next.js App Router: put Base316Provider in a Client Component wrapper used by the root layout. Every component here is a Client Component; none of them run on the server."];
|
|
77
|
+
/** The shape almost every application ends up with. */
|
|
78
|
+
readonly example: string;
|
|
79
|
+
};
|
|
80
|
+
/** Look one up by name. */
|
|
81
|
+
export declare function describeComponent(name: string): ManifestEntry | undefined;
|
|
82
|
+
/** Everything that needs a particular precondition — the "why is this blank" list. */
|
|
83
|
+
export declare function componentsRequiring(requirement: Requirement): ManifestEntry[];
|
|
84
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +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"}
|
package/dist/src/provider.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ interface Base316ContextValue {
|
|
|
25
25
|
refresh: () => Promise<void>;
|
|
26
26
|
signOut: () => Promise<void>;
|
|
27
27
|
}
|
|
28
|
-
export declare function Base316Provider({ publishableKey, baseUrl, token: controlledToken, onTokenChange, appearance, className, children, }: {
|
|
28
|
+
export declare function Base316Provider({ publishableKey, baseUrl, token: controlledToken, onTokenChange, appearance, tenant, className, children, }: {
|
|
29
29
|
publishableKey: string;
|
|
30
30
|
baseUrl?: string;
|
|
31
31
|
/** Supply this to own session storage yourself. */
|
|
@@ -33,6 +33,18 @@ export declare function Base316Provider({ publishableKey, baseUrl, token: contro
|
|
|
33
33
|
onTokenChange?: (token: string | null) => void;
|
|
34
34
|
/** Colours, radius and font, as tokens. See `Base316Appearance`. */
|
|
35
35
|
appearance?: Base316Appearance;
|
|
36
|
+
/**
|
|
37
|
+
* White-label every component under this provider for one tenant: a firm's
|
|
38
|
+
* name, logo and colours on the screens your application shows its clients.
|
|
39
|
+
* Its own branding, then its parent's, then the environment's, field by
|
|
40
|
+
* field. Change it — when the user switches team, say — and the components
|
|
41
|
+
* restyle without a reload. Omit it for the environment's own branding.
|
|
42
|
+
*/
|
|
43
|
+
tenant?: {
|
|
44
|
+
organizationId: string;
|
|
45
|
+
} | {
|
|
46
|
+
organizationExternalId: string;
|
|
47
|
+
} | null;
|
|
36
48
|
/** Your own classes on the wrapper — a Tailwind scope, for instance. */
|
|
37
49
|
className?: string;
|
|
38
50
|
children: ReactNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/provider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,IAAI,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAON,KAAK,SAAS,EACd,MAAM,OAAO,CAAC;AAEf,OAAO,EAKN,KAAK,iBAAiB,EACtB,MAAM,cAAc,CAAC;AAEtB;;;;;;;;;;;GAWG;AAEH,UAAU,mBAAmB;IAC5B,MAAM,EAAE,cAAc,CAAC;IACvB,qEAAqE;IACrE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACzC,OAAO,EAAE,eAAe,GAAG,IAAI,CAAC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AA4BD,wBAAgB,eAAe,CAAC,EAC/B,cAAc,EACd,OAAO,EACP,KAAK,EAAE,eAAe,EACtB,aAAa,EACb,UAAU,EACV,SAAS,EACT,QAAQ,GACR,EAAE;IACF,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/C,oEAAoE;IACpE,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACpB,+
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/provider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,IAAI,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAON,KAAK,SAAS,EACd,MAAM,OAAO,CAAC;AAEf,OAAO,EAKN,KAAK,iBAAiB,EACtB,MAAM,cAAc,CAAC;AAEtB;;;;;;;;;;;GAWG;AAEH,UAAU,mBAAmB;IAC5B,MAAM,EAAE,cAAc,CAAC;IACvB,qEAAqE;IACrE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACzC,OAAO,EAAE,eAAe,GAAG,IAAI,CAAC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AA4BD,wBAAgB,eAAe,CAAC,EAC/B,cAAc,EACd,OAAO,EACP,KAAK,EAAE,eAAe,EACtB,aAAa,EACb,UAAU,EACV,MAAM,EACN,SAAS,EACT,QAAQ,GACR,EAAE;IACF,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/C,oEAAoE;IACpE,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B;;;;;;OAMG;IACH,MAAM,CAAC,EAAE;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,sBAAsB,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAChF,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACpB,+BAyJA;AAED,wBAAgB,UAAU,IAAI,mBAAmB,CAQhD;AAED,oFAAoF;AACpF,wBAAgB,UAAU,IAAI;IAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAGlF"}
|