@base316/react 0.5.2 → 0.7.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/dist/index.cjs CHANGED
@@ -63,6 +63,7 @@ __export(index_exports, {
63
63
  SecondFactorStep: () => SecondFactorStep,
64
64
  SignIn: () => SignIn,
65
65
  SignUp: () => SignUp,
66
+ SocialSignIn: () => SocialSignIn,
66
67
  SubscriptionManager: () => SubscriptionManager,
67
68
  TeamMembers: () => TeamMembers,
68
69
  TwoFactorManager: () => TwoFactorManager,
@@ -397,6 +398,23 @@ var STYLESHEET_EXTRA = `
397
398
  border-bottom: 2px solid transparent; margin-bottom: -1px;
398
399
  }
399
400
  .b316-tab-on { color: var(--b316-color-text); border-bottom-color: var(--b316-color-primary); }
401
+ .b316-social { display: flex; flex-direction: column; gap: 8px; }
402
+ .b316-social-button {
403
+ display: flex; align-items: center; justify-content: center; gap: 10px;
404
+ width: 100%; min-height: 40px; padding: 9px 14px;
405
+ border: 1px solid; border-radius: calc(var(--b316-radius) / 1.6);
406
+ font: inherit; font-weight: 500; cursor: pointer;
407
+ }
408
+ .b316-social-button:hover:not([disabled]) { filter: brightness(.96); }
409
+ .b316-social-button:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 2px; }
410
+ .b316-social-button[disabled] { opacity: .55; cursor: not-allowed; }
411
+ .b316-social-icon { display: inline-flex; width: 18px; height: 18px; flex: none; }
412
+ .b316-social-icon svg { width: 18px; height: 18px; }
413
+ .b316-divider {
414
+ display: flex; align-items: center; gap: 10px; margin: 14px 0;
415
+ color: var(--b316-color-muted); font-size: .87em;
416
+ }
417
+ .b316-divider::before, .b316-divider::after { content: ""; flex: 1; border-top: 1px solid var(--b316-color-border); }
400
418
  .b316-branding { display: flex; flex-direction: column; gap: 4px; }
401
419
  .b316-branding-logo { max-height: 40px; width: auto; align-self: flex-start; }
402
420
  .b316-branding-name { font-size: 1.5em; font-weight: 650; letter-spacing: -.01em; }
@@ -714,12 +732,13 @@ function Base316Provider({
714
732
  onTokenChange,
715
733
  appearance: appearance2,
716
734
  tenant,
735
+ organizationId,
717
736
  className,
718
737
  children
719
738
  }) {
720
739
  const client = (0, import_react.useMemo)(
721
- () => new import_sdk.Base316Browser({ publishableKey, baseUrl }),
722
- [publishableKey, baseUrl]
740
+ () => new import_sdk.Base316Browser({ publishableKey, baseUrl, organizationId: organizationId ?? void 0 }),
741
+ [publishableKey, baseUrl, organizationId]
723
742
  );
724
743
  (0, import_react.useEffect)(() => {
725
744
  if (document.getElementById(STYLE_ELEMENT_ID)) {
@@ -1672,8 +1691,8 @@ function BillingDetailsForm({
1672
1691
  }
1673
1692
 
1674
1693
  // src/SignIn.tsx
1675
- var import_sdk3 = require("@base316/sdk");
1676
- var import_react7 = require("react");
1694
+ var import_sdk4 = require("@base316/sdk");
1695
+ var import_react8 = require("react");
1677
1696
 
1678
1697
  // src/SecondFactorStep.tsx
1679
1698
  var import_sdk2 = require("@base316/sdk");
@@ -2062,33 +2081,230 @@ function SecondFactorStep({
2062
2081
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: cls("b316-mfa", className), style, children: body });
2063
2082
  }
2064
2083
 
2065
- // src/SignIn.tsx
2084
+ // src/sign-in-methods.ts
2085
+ var import_sdk3 = require("@base316/sdk");
2086
+ var import_react7 = require("react");
2087
+ var cache = /* @__PURE__ */ new WeakMap();
2088
+ function loadSignInMethods(client) {
2089
+ let pending = cache.get(client);
2090
+ if (!pending) {
2091
+ pending = client.auth.methods();
2092
+ cache.set(client, pending);
2093
+ pending.catch(() => cache.delete(client));
2094
+ }
2095
+ return pending;
2096
+ }
2097
+ function useSignInMethods(client) {
2098
+ const [state, setState] = (0, import_react7.useState)({ status: "loading", methods: null });
2099
+ (0, import_react7.useEffect)(() => {
2100
+ let cancelled = false;
2101
+ loadSignInMethods(client).then((methods) => {
2102
+ if (!cancelled) setState({ status: "ready", methods });
2103
+ }).catch(() => {
2104
+ if (!cancelled) setState({ status: "unavailable", methods: null });
2105
+ });
2106
+ return () => {
2107
+ cancelled = true;
2108
+ };
2109
+ }, [client]);
2110
+ return state;
2111
+ }
2112
+ function resolveMethods(methods, props, currentPage) {
2113
+ if (!methods) {
2114
+ return {
2115
+ password: props.password !== false,
2116
+ passkeys: props.passkeys !== false,
2117
+ magicLink: props.magicLink !== false ? props.magicLinkRedirectUrl ?? null : null,
2118
+ phone: props.phone === true,
2119
+ social: [],
2120
+ sso: false,
2121
+ signUp: true,
2122
+ hostedUrl: void 0
2123
+ };
2124
+ }
2125
+ const redirect = props.socialRedirectUrl;
2126
+ const only = Array.isArray(props.social) ? new Set(props.social.map((entry) => entry.toLowerCase())) : null;
2127
+ return {
2128
+ password: methods.password && props.password !== false,
2129
+ passkeys: methods.passkeys && props.passkeys !== false,
2130
+ magicLink: methods.magicLink && props.magicLink !== false ? props.magicLinkRedirectUrl ?? currentPage : null,
2131
+ phone: methods.phone && props.phone !== false,
2132
+ social: redirect && props.social !== false ? methods.social.filter(
2133
+ (option) => !only || only.has(option.slug.toLowerCase()) || only.has(option.provider.toLowerCase())
2134
+ ) : [],
2135
+ sso: Boolean(redirect) && methods.sso && props.sso !== false,
2136
+ signUp: methods.signUp,
2137
+ hostedUrl: methods.hostedUrl
2138
+ };
2139
+ }
2140
+ function beginRedirect(build, appState) {
2141
+ const { state, nonce } = (0, import_sdk3.createOAuthState)(appState);
2142
+ const secure = window.location.protocol === "https:" ? "; Secure" : "";
2143
+ document.cookie = `${import_sdk3.OAUTH_STATE_COOKIE}=${nonce}; Path=/; Max-Age=600; SameSite=Lax${secure}`;
2144
+ window.location.assign(build(state));
2145
+ }
2146
+ function currentPageUrl() {
2147
+ if (typeof window === "undefined") {
2148
+ return null;
2149
+ }
2150
+ return `${window.location.origin}${window.location.pathname}`;
2151
+ }
2152
+
2153
+ // src/social-icons.ts
2154
+ var PROVIDER_ICON = {
2155
+ GOOGLE: `<svg viewBox="0 0 18 18" aria-hidden="true"><path fill="#4285F4" d="M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.7-1.57 2.68-3.88 2.68-6.62Z"/><path fill="#34A853" d="M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.8.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.03-3.7H.96v2.33A9 9 0 0 0 9 18Z"/><path fill="#FBBC05" d="M3.97 10.72a5.4 5.4 0 0 1 0-3.44V4.95H.96a9 9 0 0 0 0 8.1l3.01-2.33Z"/><path fill="#EA4335" d="M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.58C13.46.9 11.43 0 9 0A9 9 0 0 0 .96 4.95l3.01 2.33C4.68 5.16 6.66 3.58 9 3.58Z"/></svg>`,
2156
+ FACEBOOK: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M24 12.07C24 5.4 18.63 0 12 0S0 5.4 0 12.07C0 18.1 4.39 23.1 10.13 24v-8.44H7.08v-3.49h3.05V9.41c0-3.02 1.79-4.69 4.53-4.69 1.31 0 2.68.24 2.68.24v2.96h-1.51c-1.49 0-1.96.93-1.96 1.89v2.26h3.33l-.53 3.49h-2.8V24C19.61 23.1 24 18.1 24 12.07Z"/></svg>`,
2157
+ APPLE: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M17.05 12.54c-.03-2.74 2.24-4.06 2.34-4.12-1.28-1.86-3.26-2.12-3.96-2.15-1.69-.17-3.29 1-4.14 1-.85 0-2.17-.98-3.57-.95-1.83.03-3.53 1.07-4.47 2.71-1.91 3.31-.49 8.2 1.37 10.88.91 1.31 1.99 2.78 3.42 2.73 1.37-.06 1.89-.89 3.55-.89 1.66 0 2.13.89 3.58.86 1.48-.03 2.41-1.34 3.31-2.65 1.04-1.52 1.47-2.99 1.5-3.07-.03-.01-2.88-1.1-2.91-4.37ZM14.3 4.44c.75-.92 1.26-2.19 1.12-3.44-1.08.04-2.4.72-3.18 1.63-.7.81-1.31 2.11-1.15 3.35 1.21.09 2.45-.61 3.21-1.54Z"/></svg>`,
2158
+ MICROSOFT: `<svg viewBox="0 0 23 23" aria-hidden="true"><path fill="#f25022" d="M1 1h10v10H1z"/><path fill="#7fba00" d="M12 1h10v10H12z"/><path fill="#00a4ef" d="M1 12h10v10H1z"/><path fill="#ffb900" d="M12 12h10v10H12z"/></svg>`,
2159
+ GITHUB: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M12 .3a12 12 0 0 0-3.8 23.4c.6.1.8-.3.8-.6v-2c-3.3.7-4-1.6-4-1.6-.6-1.4-1.4-1.8-1.4-1.8-1-.7.1-.7.1-.7 1.2.1 1.8 1.2 1.8 1.2 1 1.8 2.8 1.3 3.5 1 0-.8.4-1.3.7-1.6-2.7-.3-5.5-1.3-5.5-5.9 0-1.3.5-2.4 1.2-3.2 0-.4-.5-1.6.2-3.2 0 0 1-.3 3.3 1.2a11.5 11.5 0 0 1 6 0C17.4 4.6 18.4 5 18.4 5c.7 1.6.2 2.8.1 3.2.8.8 1.2 1.9 1.2 3.2 0 4.6-2.8 5.6-5.5 5.9.5.4.9 1.1.9 2.2v3.3c0 .3.2.7.8.6A12 12 0 0 0 12 .3Z"/></svg>`,
2160
+ GITLAB: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#e24329" d="m12 22.5-3.7-11.3h7.4L12 22.5Z"/><path fill="#fc6d26" d="M12 22.5 8.3 11.2H3.1L12 22.5Z"/><path fill="#fca326" d="M3.1 11.2 2 14.7a.8.8 0 0 0 .3.8l9.7 7-8.9-11.3Z"/><path fill="#e24329" d="M3.1 11.2h5.2L6.1 4.3a.4.4 0 0 0-.8 0l-2.2 6.9Z"/><path fill="#fc6d26" d="M12 22.5l3.7-11.3h5.2L12 22.5Z"/><path fill="#fca326" d="m20.9 11.2 1.1 3.5a.8.8 0 0 1-.3.8l-9.7 7 8.9-11.3Z"/><path fill="#e24329" d="M20.9 11.2h-5.2l2.2-6.9a.4.4 0 0 1 .8 0l2.2 6.9Z"/></svg>`,
2161
+ LINKEDIN: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M20.45 20.45h-3.56v-5.57c0-1.33-.02-3.04-1.85-3.04-1.85 0-2.14 1.45-2.14 2.94v5.67H9.35V9h3.41v1.56h.05a3.74 3.74 0 0 1 3.37-1.85c3.6 0 4.27 2.37 4.27 5.46v6.28ZM5.34 7.43a2.07 2.07 0 1 1 0-4.13 2.07 2.07 0 0 1 0 4.13Zm1.78 13.02H3.55V9h3.57v11.45ZM22.22 0H1.77C.79 0 0 .77 0 1.72v20.56C0 23.23.79 24 1.77 24h20.45c.98 0 1.78-.77 1.78-1.72V1.72C24 .77 23.2 0 22.22 0Z"/></svg>`,
2162
+ // The four below are the Simple Icons marks (CC0), https://simpleicons.org.
2163
+ DISCORD: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"/></svg>`,
2164
+ TWITTER: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z"/></svg>`,
2165
+ TWITCH: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z"/></svg>`,
2166
+ ROBLOX: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M18.926 23.998 0 18.892 5.075.002 24 5.108ZM15.348 10.09l-5.282-1.453-1.414 5.273 5.282 1.453z"/></svg>`,
2167
+ SLACK: `<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="#e01e5a" d="M5.04 15.17a2.53 2.53 0 1 1-2.52-2.53h2.52v2.53Zm1.27 0a2.53 2.53 0 1 1 5.05 0v6.31a2.53 2.53 0 1 1-5.05 0v-6.31Z"/><path fill="#36c5f0" d="M8.83 5.04a2.53 2.53 0 1 1 2.53-2.52v2.52H8.83Zm0 1.28a2.53 2.53 0 1 1 0 5.05H2.52a2.53 2.53 0 1 1 0-5.05h6.31Z"/><path fill="#2eb67d" d="M18.96 8.83a2.53 2.53 0 1 1 2.52 2.53h-2.52V8.83Zm-1.27 0a2.53 2.53 0 1 1-5.05 0V2.52a2.53 2.53 0 1 1 5.05 0v6.31Z"/><path fill="#ecb22e" d="M15.17 18.96a2.53 2.53 0 1 1-2.53 2.52v-2.52h2.53Zm0-1.27a2.53 2.53 0 1 1 0-5.05h6.31a2.53 2.53 0 1 1 0 5.05h-6.31Z"/></svg>`
2168
+ };
2169
+
2170
+ // src/SocialButtons.tsx
2066
2171
  var import_jsx_runtime8 = require("react/jsx-runtime");
2172
+ function SocialButtons({
2173
+ options,
2174
+ continueWith,
2175
+ disabled,
2176
+ onChoose
2177
+ }) {
2178
+ if (options.length === 0) {
2179
+ return null;
2180
+ }
2181
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "b316-social", children: options.map((option) => {
2182
+ const icon = PROVIDER_ICON[option.provider];
2183
+ const light = /^#f{3}(f{3})?$/i.test(option.buttonColor);
2184
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2185
+ "button",
2186
+ {
2187
+ type: "button",
2188
+ className: "b316-social-button",
2189
+ "data-provider": option.slug,
2190
+ disabled,
2191
+ style: {
2192
+ background: option.buttonColor,
2193
+ color: option.buttonTextColor,
2194
+ borderColor: light ? "#747775" : option.buttonColor
2195
+ },
2196
+ onClick: () => onChoose(option),
2197
+ children: [
2198
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2199
+ "span",
2200
+ {
2201
+ className: "b316-social-icon",
2202
+ "aria-hidden": "true",
2203
+ dangerouslySetInnerHTML: { __html: icon }
2204
+ }
2205
+ ) : null,
2206
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: continueWith(option.name, option.provider) })
2207
+ ]
2208
+ },
2209
+ option.slug
2210
+ );
2211
+ }) });
2212
+ }
2213
+
2214
+ // src/SignIn.tsx
2215
+ var import_jsx_runtime9 = require("react/jsx-runtime");
2216
+ var DEFAULT_SIGN_IN_LABELS = {
2217
+ email: "Email",
2218
+ password: "Password",
2219
+ mobileNumber: "Mobile number",
2220
+ code: "Code",
2221
+ tabPassword: "Password",
2222
+ tabMagicLink: "Magic link",
2223
+ tabPhone: "Text message",
2224
+ submit: "Sign in",
2225
+ working: "Working\u2026",
2226
+ emailMeALink: "Email me a link",
2227
+ textMeACode: "Text me a code",
2228
+ includeCountryCode: "Include the country code.",
2229
+ codeSent: (destination) => `We sent a code to ${destination}. It expires in ten minutes.`,
2230
+ useDifferentNumber: "Use a different number",
2231
+ or: "or",
2232
+ passkey: "Sign in with a passkey",
2233
+ continueWith: (name) => `Continue with ${name}`,
2234
+ sso: "Sign in with SSO",
2235
+ ssoEmail: "Work email",
2236
+ ssoContinue: "Continue",
2237
+ back: "Back",
2238
+ checkEmailTitle: "Check your email",
2239
+ checkEmail: (email) => `If an account exists for ${email}, a sign-in link is on its way. It expires shortly and can be used once.`,
2240
+ backToSignIn: "Back to sign in",
2241
+ wrongPassword: "That email and password did not match.",
2242
+ passkeyFailed: "That passkey did not work.",
2243
+ linkInvalid: "That sign-in link is no longer valid. Ask for a new one.",
2244
+ linkFailed: "We could not send that link. Try again.",
2245
+ wrongCode: "That code did not work. Check it, or ask for a new one.",
2246
+ codeFailed: "We could not send a code. Try again.",
2247
+ noMethods: "Signing in is not available right now."
2248
+ };
2067
2249
  function SignIn({
2068
2250
  onSignedIn,
2069
- passkeys = true,
2251
+ password: passwordProp,
2252
+ passkeys: passkeysProp,
2253
+ magicLink: magicLinkProp,
2070
2254
  magicLinkRedirectUrl,
2071
- phone = false,
2255
+ phone: phoneProp,
2256
+ social: socialProp,
2257
+ sso: ssoProp,
2258
+ socialRedirectUrl,
2259
+ socialState,
2260
+ labels: overrides,
2072
2261
  secondFactorLabels,
2073
2262
  className,
2074
2263
  style
2075
2264
  }) {
2265
+ const labels = { ...DEFAULT_SIGN_IN_LABELS, ...overrides };
2076
2266
  const { client, setToken } = useBase316();
2077
- const [email, setEmail] = (0, import_react7.useState)("");
2078
- const [password, setPassword] = (0, import_react7.useState)("");
2079
- const [code, setCode] = (0, import_react7.useState)("");
2080
- const [pending, setPending] = (0, import_react7.useState)(null);
2267
+ const loaded = useSignInMethods(client);
2268
+ const [currentPage, setCurrentPage] = (0, import_react8.useState)(null);
2269
+ const [email, setEmail] = (0, import_react8.useState)("");
2270
+ const [password, setPassword] = (0, import_react8.useState)("");
2271
+ const [code, setCode] = (0, import_react8.useState)("");
2272
+ const [pending, setPending] = (0, import_react8.useState)(null);
2081
2273
  const pendingChallenge = pending?.challengeToken ?? null;
2082
- const [phoneNumber, setPhoneNumber] = (0, import_react7.useState)("");
2083
- const [phoneChallenge, setPhoneChallenge] = (0, import_react7.useState)(
2274
+ const [phoneNumber, setPhoneNumber] = (0, import_react8.useState)("");
2275
+ const [phoneChallenge, setPhoneChallenge] = (0, import_react8.useState)(
2084
2276
  null
2085
2277
  );
2086
- const [error, setError] = (0, import_react7.useState)(null);
2087
- const [busy, setBusy] = (0, import_react7.useState)(false);
2088
- const [passkeyReady, setPasskeyReady] = (0, import_react7.useState)(false);
2089
- const [mode, setMode] = (0, import_react7.useState)("password");
2090
- const [linkSent, setLinkSent] = (0, import_react7.useState)(false);
2091
- const abortRef = (0, import_react7.useRef)(null);
2278
+ const [error, setError] = (0, import_react8.useState)(null);
2279
+ const [busy, setBusy] = (0, import_react8.useState)(false);
2280
+ const [passkeyReady, setPasskeyReady] = (0, import_react8.useState)(false);
2281
+ const [chosenMode, setMode] = (0, import_react8.useState)(null);
2282
+ const [linkSent, setLinkSent] = (0, import_react8.useState)(false);
2283
+ const abortRef = (0, import_react8.useRef)(null);
2284
+ (0, import_react8.useEffect)(() => {
2285
+ setCurrentPage(currentPageUrl());
2286
+ }, []);
2287
+ const offered = resolveMethods(
2288
+ loaded.methods,
2289
+ {
2290
+ password: passwordProp,
2291
+ passkeys: passkeysProp,
2292
+ magicLink: magicLinkProp,
2293
+ magicLinkRedirectUrl,
2294
+ phone: phoneProp,
2295
+ social: socialProp,
2296
+ sso: ssoProp,
2297
+ socialRedirectUrl
2298
+ },
2299
+ currentPage
2300
+ );
2301
+ const tabs = [
2302
+ ...offered.password ? ["password"] : [],
2303
+ ...offered.magicLink ? ["magic"] : [],
2304
+ ...offered.phone ? ["phone"] : []
2305
+ ];
2306
+ const mode = chosenMode && (chosenMode === "sso" ? offered.sso : tabs.includes(chosenMode)) ? chosenMode : tabs[0] ?? null;
2307
+ const passkeysWanted = loaded.status !== "loading" && offered.passkeys;
2092
2308
  const signInWithPasskey = async (conditional, signal) => {
2093
2309
  if (!conditional) {
2094
2310
  setBusy(true);
@@ -2102,11 +2318,11 @@ function SignIn({
2102
2318
  if (cause instanceof DOMException && (cause.name === "NotAllowedError" || cause.name === "AbortError")) {
2103
2319
  return;
2104
2320
  }
2105
- if (cause instanceof import_sdk3.Base316Error && cause.reason === "EMAIL_NOT_VERIFIED") {
2321
+ if (cause instanceof import_sdk4.Base316Error && cause.reason === "EMAIL_NOT_VERIFIED") {
2106
2322
  setError(cause.message);
2107
2323
  } else if (!conditional) {
2108
2324
  console.error("[base316] passkey sign-in failed", cause);
2109
- setError("That passkey did not work.");
2325
+ setError(labels.passkeyFailed);
2110
2326
  }
2111
2327
  } finally {
2112
2328
  if (!conditional) {
@@ -2114,14 +2330,15 @@ function SignIn({
2114
2330
  }
2115
2331
  }
2116
2332
  };
2117
- (0, import_react7.useEffect)(() => {
2118
- if (!passkeys || !(0, import_sdk3.isPasskeySupported)() || pendingChallenge) {
2333
+ (0, import_react8.useEffect)(() => {
2334
+ if (!passkeysWanted || !(0, import_sdk4.isPasskeySupported)() || pendingChallenge) {
2335
+ setPasskeyReady(false);
2119
2336
  return;
2120
2337
  }
2121
2338
  setPasskeyReady(true);
2122
2339
  const controller = new AbortController();
2123
2340
  abortRef.current = controller;
2124
- void (0, import_sdk3.isPasskeyAutofillAvailable)().then((available) => {
2341
+ void (0, import_sdk4.isPasskeyAutofillAvailable)().then((available) => {
2125
2342
  if (available && !controller.signal.aborted) {
2126
2343
  void signInWithPasskey(true, controller.signal);
2127
2344
  }
@@ -2129,8 +2346,8 @@ function SignIn({
2129
2346
  return () => {
2130
2347
  controller.abort();
2131
2348
  };
2132
- }, [passkeys, pendingChallenge]);
2133
- (0, import_react7.useEffect)(() => {
2349
+ }, [passkeysWanted, pendingChallenge]);
2350
+ (0, import_react8.useEffect)(() => {
2134
2351
  if (typeof window === "undefined") {
2135
2352
  return;
2136
2353
  }
@@ -2146,7 +2363,7 @@ function SignIn({
2146
2363
  if (cancelled) {
2147
2364
  return;
2148
2365
  }
2149
- if ((0, import_sdk3.needsSecondFactor)(result)) {
2366
+ if ((0, import_sdk4.needsSecondFactor)(result)) {
2150
2367
  setPending(result);
2151
2368
  return;
2152
2369
  }
@@ -2154,7 +2371,7 @@ function SignIn({
2154
2371
  onSignedIn?.();
2155
2372
  }).catch(() => {
2156
2373
  if (!cancelled) {
2157
- setError("That sign-in link is no longer valid. Ask for a new one.");
2374
+ setError(labels.linkInvalid);
2158
2375
  }
2159
2376
  });
2160
2377
  return () => {
@@ -2162,23 +2379,44 @@ function SignIn({
2162
2379
  };
2163
2380
  }, []);
2164
2381
  async function sendLink() {
2165
- if (!magicLinkRedirectUrl) {
2382
+ if (!offered.magicLink) {
2166
2383
  return;
2167
2384
  }
2168
2385
  setBusy(true);
2169
2386
  setError(null);
2170
2387
  try {
2171
- await client.auth.magicLink.request({ email, redirectUrl: magicLinkRedirectUrl });
2388
+ await client.auth.magicLink.request({ email, redirectUrl: offered.magicLink });
2172
2389
  setLinkSent(true);
2173
2390
  } catch (cause) {
2174
2391
  console.error("[base316] magic link request failed", cause);
2175
- setError("We could not send that link. Try again.");
2392
+ setError(
2393
+ cause instanceof import_sdk4.Base316Error && cause.code === "INVALID_REQUEST" && cause.message ? cause.message : labels.linkFailed
2394
+ );
2176
2395
  } finally {
2177
2396
  setBusy(false);
2178
2397
  }
2179
2398
  }
2399
+ function leaveForSso() {
2400
+ if (!socialRedirectUrl) {
2401
+ return;
2402
+ }
2403
+ setBusy(true);
2404
+ beginRedirect(
2405
+ (state) => client.ssoSignInUrl({
2406
+ email,
2407
+ redirectUri: socialRedirectUrl,
2408
+ state,
2409
+ hostedUrl: offered.hostedUrl
2410
+ }),
2411
+ socialState
2412
+ );
2413
+ }
2180
2414
  async function submit(event) {
2181
2415
  event.preventDefault();
2416
+ if (mode === "sso") {
2417
+ leaveForSso();
2418
+ return;
2419
+ }
2182
2420
  setBusy(true);
2183
2421
  setError(null);
2184
2422
  try {
@@ -2196,7 +2434,7 @@ function SignIn({
2196
2434
  challengeToken: phoneChallenge.token,
2197
2435
  code
2198
2436
  });
2199
- if ((0, import_sdk3.needsSecondFactor)(signedIn)) {
2437
+ if ((0, import_sdk4.needsSecondFactor)(signedIn)) {
2200
2438
  setPending(signedIn);
2201
2439
  setCode("");
2202
2440
  return;
@@ -2206,7 +2444,7 @@ function SignIn({
2206
2444
  return;
2207
2445
  }
2208
2446
  const result = await client.auth.signIn({ email, password });
2209
- if ((0, import_sdk3.needsSecondFactor)(result)) {
2447
+ if ((0, import_sdk4.needsSecondFactor)(result)) {
2210
2448
  setPending(result);
2211
2449
  return;
2212
2450
  }
@@ -2215,25 +2453,23 @@ function SignIn({
2215
2453
  } catch (cause) {
2216
2454
  console.error("[base316] sign-in failed", cause);
2217
2455
  setError(
2218
- mode === "phone" ? phoneChallenge ? "That code did not work. Check it, or ask for a new one." : (
2456
+ mode === "phone" ? phoneChallenge ? labels.wrongCode : (
2219
2457
  // Why a text could not be sent is worth saying — a number in the
2220
2458
  // wrong format, or too many requests — and the server words it
2221
2459
  // without saying anything about accounts.
2222
- cause instanceof Error && cause.message ? cause.message : "We could not send a code. Try again."
2460
+ cause instanceof Error && cause.message ? cause.message : labels.codeFailed
2223
2461
  ) : (
2224
2462
  // An unconfirmed address and a throttle are worth naming; the
2225
2463
  // server words both without saying whether an account exists.
2226
- cause instanceof import_sdk3.Base316Error && (cause.reason === "EMAIL_NOT_VERIFIED" || cause.code === "RATE_LIMITED") ? cause.message : "That email and password did not match."
2464
+ cause instanceof import_sdk4.Base316Error && (cause.reason === "EMAIL_NOT_VERIFIED" || cause.code === "RATE_LIMITED") ? cause.message : labels.wrongPassword
2227
2465
  )
2228
2466
  );
2229
2467
  } finally {
2230
2468
  setBusy(false);
2231
2469
  }
2232
2470
  }
2233
- const magicAvailable = Boolean(magicLinkRedirectUrl) && !pendingChallenge;
2234
- const tabsShown = (magicAvailable || phone) && !pendingChallenge;
2235
2471
  if (pending) {
2236
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2472
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2237
2473
  SecondFactorStep,
2238
2474
  {
2239
2475
  pending,
@@ -2249,59 +2485,68 @@ function SignIn({
2249
2485
  ) });
2250
2486
  }
2251
2487
  if (linkSent) {
2252
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: cls("b316-card", className), style, children: [
2253
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { fontWeight: 600, marginBottom: 6 }, children: "Check your email" }),
2254
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "b316-muted", children: [
2255
- "If an account exists for ",
2256
- email,
2257
- ", a sign-in link is on its way. It expires shortly and can be used once."
2258
- ] }),
2259
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2488
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: cls("b316-card", className), style, children: [
2489
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { fontWeight: 600, marginBottom: 6 }, children: labels.checkEmailTitle }),
2490
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "b316-muted", children: labels.checkEmail(email) }),
2491
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2260
2492
  "button",
2261
2493
  {
2262
2494
  type: "button",
2263
2495
  className: "b316-button b316-button-secondary",
2264
2496
  style: { marginTop: 16 },
2265
2497
  onClick: () => setLinkSent(false),
2266
- children: "Back to sign in"
2498
+ children: labels.backToSignIn
2267
2499
  }
2268
2500
  )
2269
2501
  ] });
2270
2502
  }
2271
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
2272
- error ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
2273
- tabsShown ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "b316-tabs", children: [
2274
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2275
- "button",
2503
+ const hasForm = mode !== null;
2504
+ const hasButtons = offered.social.length > 0 || passkeyReady || offered.sso && mode !== "sso";
2505
+ if (!hasForm && !hasButtons) {
2506
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "b316-error", role: "alert", children: error ?? labels.noMethods }) });
2507
+ }
2508
+ const tabsShown = tabs.length > 1 && mode !== "sso";
2509
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
2510
+ error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
2511
+ offered.social.length > 0 && mode !== "sso" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
2512
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2513
+ SocialButtons,
2276
2514
  {
2277
- type: "button",
2278
- className: cls("b316-tab", mode === "password" ? "b316-tab-on" : void 0),
2279
- onClick: () => setMode("password"),
2280
- children: "Password"
2515
+ options: offered.social,
2516
+ continueWith: labels.continueWith,
2517
+ disabled: busy,
2518
+ onChoose: (option) => {
2519
+ if (!socialRedirectUrl) {
2520
+ return;
2521
+ }
2522
+ setBusy(true);
2523
+ beginRedirect(
2524
+ (state) => client.socialSignInUrl({
2525
+ provider: option.slug,
2526
+ redirectUri: socialRedirectUrl,
2527
+ state,
2528
+ hostedUrl: offered.hostedUrl
2529
+ }),
2530
+ socialState
2531
+ );
2532
+ }
2281
2533
  }
2282
2534
  ),
2283
- magicAvailable ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2284
- "button",
2285
- {
2286
- type: "button",
2287
- className: cls("b316-tab", mode === "magic" ? "b316-tab-on" : void 0),
2288
- onClick: () => setMode("magic"),
2289
- children: "Magic link"
2290
- }
2291
- ) : null,
2292
- phone ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2293
- "button",
2294
- {
2295
- type: "button",
2296
- className: cls("b316-tab", mode === "phone" ? "b316-tab-on" : void 0),
2297
- onClick: () => setMode("phone"),
2298
- children: "Text message"
2299
- }
2300
- ) : null
2535
+ hasForm ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "b316-divider", children: labels.or }) : null
2301
2536
  ] }) : null,
2302
- mode === "phone" ? phoneChallenge ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "b316-field", children: [
2303
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "b316-label", htmlFor: "b316-phone-code", children: "Code" }),
2304
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2537
+ tabsShown ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "b316-tabs", children: tabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2538
+ "button",
2539
+ {
2540
+ type: "button",
2541
+ className: cls("b316-tab", mode === tab ? "b316-tab-on" : void 0),
2542
+ onClick: () => setMode(tab),
2543
+ children: tab === "password" ? labels.tabPassword : tab === "magic" ? labels.tabMagicLink : labels.tabPhone
2544
+ },
2545
+ tab
2546
+ )) }) : null,
2547
+ mode === "phone" ? phoneChallenge ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "b316-field", children: [
2548
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "b316-label", htmlFor: "b316-phone-code", children: labels.code }),
2549
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2305
2550
  "input",
2306
2551
  {
2307
2552
  id: "b316-phone-code",
@@ -2313,12 +2558,10 @@ function SignIn({
2313
2558
  required: true
2314
2559
  }
2315
2560
  ),
2316
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "b316-muted", children: [
2317
- "We sent a code to ",
2318
- phoneChallenge.hint,
2319
- ". It expires in ten minutes.",
2561
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "b316-muted", children: [
2562
+ labels.codeSent(phoneChallenge.hint),
2320
2563
  " ",
2321
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2564
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2322
2565
  "button",
2323
2566
  {
2324
2567
  type: "button",
@@ -2327,13 +2570,13 @@ function SignIn({
2327
2570
  setPhoneChallenge(null);
2328
2571
  setCode("");
2329
2572
  },
2330
- children: "Use a different number"
2573
+ children: labels.useDifferentNumber
2331
2574
  }
2332
2575
  )
2333
2576
  ] })
2334
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "b316-field", children: [
2335
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "b316-label", htmlFor: "b316-phone", children: "Mobile number" }),
2336
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2577
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "b316-field", children: [
2578
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "b316-label", htmlFor: "b316-phone", children: labels.mobileNumber }),
2579
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2337
2580
  "input",
2338
2581
  {
2339
2582
  id: "b316-phone",
@@ -2346,11 +2589,11 @@ function SignIn({
2346
2589
  required: true
2347
2590
  }
2348
2591
  ),
2349
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "b316-muted", children: "Include the country code." })
2350
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
2351
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "b316-field", children: [
2352
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "b316-label", htmlFor: "b316-email", children: "Email" }),
2353
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2592
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "b316-muted", children: labels.includeCountryCode })
2593
+ ] }) : mode !== null ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
2594
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "b316-field", children: [
2595
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "b316-label", htmlFor: "b316-email", children: mode === "sso" ? labels.ssoEmail : labels.email }),
2596
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2354
2597
  "input",
2355
2598
  {
2356
2599
  id: "b316-email",
@@ -2358,14 +2601,14 @@ function SignIn({
2358
2601
  type: "email",
2359
2602
  value: email,
2360
2603
  onChange: (event) => setEmail(event.target.value),
2361
- autoComplete: passkeyReady ? "email webauthn" : "email",
2604
+ autoComplete: passkeyReady && mode !== "sso" ? "email webauthn" : "email",
2362
2605
  required: true
2363
2606
  }
2364
2607
  )
2365
2608
  ] }),
2366
- mode === "password" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "b316-field", children: [
2367
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "b316-label", htmlFor: "b316-password", children: "Password" }),
2368
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2609
+ mode === "password" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "b316-field", children: [
2610
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "b316-label", htmlFor: "b316-password", children: labels.password }),
2611
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2369
2612
  "input",
2370
2613
  {
2371
2614
  id: "b316-password",
@@ -2378,31 +2621,98 @@ function SignIn({
2378
2621
  }
2379
2622
  )
2380
2623
  ] }) : null
2381
- ] }),
2382
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { className: "b316-button", type: "submit", disabled: busy, children: busy ? "Working\u2026" : mode === "magic" ? "Email me a link" : mode === "phone" && !phoneChallenge ? "Text me a code" : "Sign in" }),
2383
- passkeyReady && !pendingChallenge ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
2384
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "b316-muted", style: { textAlign: "center", margin: "10px 0" }, children: "or" }),
2385
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2624
+ ] }) : null,
2625
+ mode !== null ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { className: "b316-button", type: "submit", disabled: busy, children: busy ? labels.working : mode === "magic" ? labels.emailMeALink : mode === "phone" && !phoneChallenge ? labels.textMeACode : mode === "sso" ? labels.ssoContinue : labels.submit }) : null,
2626
+ mode === "sso" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2627
+ "button",
2628
+ {
2629
+ type: "button",
2630
+ className: "b316-button b316-button-secondary",
2631
+ style: { marginTop: 10, width: "100%" },
2632
+ disabled: busy,
2633
+ onClick: () => setMode(null),
2634
+ children: labels.back
2635
+ }
2636
+ ) : null,
2637
+ (passkeyReady || offered.sso) && mode !== "sso" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
2638
+ hasForm ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "b316-divider", children: labels.or }) : null,
2639
+ passkeyReady ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2386
2640
  "button",
2387
2641
  {
2388
2642
  type: "button",
2389
2643
  className: "b316-button b316-button-secondary",
2644
+ style: { width: "100%" },
2390
2645
  disabled: busy,
2391
2646
  onClick: () => {
2392
2647
  abortRef.current?.abort();
2393
2648
  void signInWithPasskey(false);
2394
2649
  },
2395
- children: "Sign in with a passkey"
2650
+ children: labels.passkey
2396
2651
  }
2397
- )
2652
+ ) : null,
2653
+ offered.sso ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2654
+ "button",
2655
+ {
2656
+ type: "button",
2657
+ className: "b316-button b316-button-secondary",
2658
+ style: { width: "100%", marginTop: passkeyReady ? 8 : 0 },
2659
+ disabled: busy,
2660
+ onClick: () => {
2661
+ abortRef.current?.abort();
2662
+ setError(null);
2663
+ setMode("sso");
2664
+ },
2665
+ children: labels.sso
2666
+ }
2667
+ ) : null
2398
2668
  ] }) : null
2399
2669
  ] });
2400
2670
  }
2401
2671
 
2672
+ // src/SocialSignIn.tsx
2673
+ var import_jsx_runtime10 = require("react/jsx-runtime");
2674
+ function SocialSignIn({
2675
+ socialRedirectUrl,
2676
+ socialState,
2677
+ social,
2678
+ intent = "sign-in",
2679
+ divider = false,
2680
+ labels
2681
+ }) {
2682
+ const { client } = useBase316();
2683
+ const loaded = useSignInMethods(client);
2684
+ if (!loaded.methods || intent === "sign-up" && !loaded.methods.signUp) {
2685
+ return null;
2686
+ }
2687
+ const offered = resolveMethods(loaded.methods, { social, socialRedirectUrl }, null);
2688
+ if (!socialRedirectUrl || offered.social.length === 0) {
2689
+ return null;
2690
+ }
2691
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
2692
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2693
+ SocialButtons,
2694
+ {
2695
+ options: offered.social,
2696
+ continueWith: labels?.continueWith ?? ((name) => `Continue with ${name}`),
2697
+ onChoose: (option) => beginRedirect(
2698
+ (state) => client.socialSignInUrl({
2699
+ provider: option.slug,
2700
+ redirectUri: socialRedirectUrl,
2701
+ state,
2702
+ hostedUrl: offered.hostedUrl
2703
+ }),
2704
+ socialState
2705
+ )
2706
+ }
2707
+ ),
2708
+ divider ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "b316-divider", children: labels?.or ?? "or" }) : null
2709
+ ] });
2710
+ }
2711
+
2402
2712
  // src/SignUp.tsx
2403
- var import_sdk4 = require("@base316/sdk");
2404
- var import_react8 = require("react");
2405
- var import_jsx_runtime9 = require("react/jsx-runtime");
2713
+ var import_sdk5 = require("@base316/sdk");
2714
+ var import_react9 = require("react");
2715
+ var import_jsx_runtime11 = require("react/jsx-runtime");
2406
2716
  var DEFAULT_SIGN_UP_LABELS = {
2407
2717
  name: "Name",
2408
2718
  email: "Email",
@@ -2419,7 +2729,10 @@ var DEFAULT_SIGN_UP_LABELS = {
2419
2729
  confirmEmail: (email) => `Your account is ready. We sent a confirmation link to ${email} \u2014 open it, then sign in.`,
2420
2730
  createdSignInFailed: (reason) => `Your account was created, but we could not sign you in: ${reason}`,
2421
2731
  genericError: "We could not create that account. Try again.",
2422
- joining: (organizationName, roleName) => `You are joining ${organizationName} as ${roleName}. Sign up with the address the invitation was sent to.`
2732
+ joining: (organizationName, roleName) => `You are joining ${organizationName} as ${roleName}. Sign up with the address the invitation was sent to.`,
2733
+ continueWith: (name) => `Continue with ${name}`,
2734
+ or: "or",
2735
+ closed: "This application is not accepting new accounts right now."
2423
2736
  };
2424
2737
  function describeRules(policy, labels) {
2425
2738
  const extras = [
@@ -2438,30 +2751,35 @@ function SignUp({
2438
2751
  onJoined,
2439
2752
  labels: overrides,
2440
2753
  secondFactorLabels,
2754
+ social,
2755
+ socialRedirectUrl,
2756
+ socialState,
2441
2757
  className,
2442
2758
  style
2443
2759
  }) {
2444
2760
  const labels = { ...DEFAULT_SIGN_UP_LABELS, ...overrides };
2445
2761
  const { client, setToken } = useBase316();
2446
- const [name, setName] = (0, import_react8.useState)("");
2447
- const [email, setEmail] = (0, import_react8.useState)("");
2448
- const [password, setPassword] = (0, import_react8.useState)("");
2449
- const [error, setError] = (0, import_react8.useState)(null);
2450
- const [busy, setBusy] = (0, import_react8.useState)(false);
2451
- const [policy, setPolicy] = (0, import_react8.useState)(null);
2452
- const [pending, setPending] = (0, import_react8.useState)(null);
2453
- const [confirmEmail, setConfirmEmail] = (0, import_react8.useState)(false);
2454
- const [urlInvitation, setUrlInvitation] = (0, import_react8.useState)(null);
2455
- const [loaded, setLoaded] = (0, import_react8.useState)(null);
2762
+ const methodsState = useSignInMethods(client);
2763
+ const offered = resolveMethods(methodsState.methods, { social, socialRedirectUrl }, null);
2764
+ const [name, setName] = (0, import_react9.useState)("");
2765
+ const [email, setEmail] = (0, import_react9.useState)("");
2766
+ const [password, setPassword] = (0, import_react9.useState)("");
2767
+ const [error, setError] = (0, import_react9.useState)(null);
2768
+ const [busy, setBusy] = (0, import_react9.useState)(false);
2769
+ const [policy, setPolicy] = (0, import_react9.useState)(null);
2770
+ const [pending, setPending] = (0, import_react9.useState)(null);
2771
+ const [confirmEmail, setConfirmEmail] = (0, import_react9.useState)(false);
2772
+ const [urlInvitation, setUrlInvitation] = (0, import_react9.useState)(null);
2773
+ const [loaded, setLoaded] = (0, import_react9.useState)(null);
2456
2774
  const invitation = suppliedInvitation === void 0 ? urlInvitation : suppliedInvitation;
2457
2775
  const preview = loaded && loaded.token === invitation ? loaded.preview : null;
2458
- (0, import_react8.useEffect)(() => {
2776
+ (0, import_react9.useEffect)(() => {
2459
2777
  if (suppliedInvitation !== void 0 || typeof window === "undefined") {
2460
2778
  return;
2461
2779
  }
2462
2780
  setUrlInvitation(new URL(window.location.href).searchParams.get("invitation"));
2463
2781
  }, [suppliedInvitation]);
2464
- (0, import_react8.useEffect)(() => {
2782
+ (0, import_react9.useEffect)(() => {
2465
2783
  if (!invitation) {
2466
2784
  return;
2467
2785
  }
@@ -2476,7 +2794,7 @@ function SignUp({
2476
2794
  cancelled = true;
2477
2795
  };
2478
2796
  }, [client, invitation]);
2479
- (0, import_react8.useEffect)(() => {
2797
+ (0, import_react9.useEffect)(() => {
2480
2798
  let cancelled = false;
2481
2799
  client.auth.passwordPolicy().then((loaded2) => {
2482
2800
  if (!cancelled) {
@@ -2504,14 +2822,14 @@ function SignUp({
2504
2822
  } catch (cause) {
2505
2823
  console.error("[base316] sign-up failed", cause);
2506
2824
  setError(
2507
- cause instanceof import_sdk4.Base316Error && (cause.code === "INVALID_REQUEST" || cause.code === "RATE_LIMITED" || cause.code === "CONFLICT") && cause.message ? cause.message : labels.genericError
2825
+ cause instanceof import_sdk5.Base316Error && (cause.code === "INVALID_REQUEST" || cause.code === "RATE_LIMITED" || cause.code === "CONFLICT") && cause.message ? cause.message : labels.genericError
2508
2826
  );
2509
2827
  setBusy(false);
2510
2828
  return;
2511
2829
  }
2512
2830
  try {
2513
2831
  const signedIn = await client.auth.signIn({ email, password });
2514
- if ((0, import_sdk4.needsSecondFactor)(signedIn)) {
2832
+ if ((0, import_sdk5.needsSecondFactor)(signedIn)) {
2515
2833
  setPending(signedIn);
2516
2834
  return;
2517
2835
  }
@@ -2519,14 +2837,14 @@ function SignUp({
2519
2837
  onSignedUp?.();
2520
2838
  } catch (cause) {
2521
2839
  console.error("[base316] sign-in after sign-up failed", cause);
2522
- if (cause instanceof import_sdk4.Base316Error && cause.reason === "EMAIL_NOT_VERIFIED") {
2840
+ if (cause instanceof import_sdk5.Base316Error && cause.reason === "EMAIL_NOT_VERIFIED") {
2523
2841
  setConfirmEmail(true);
2524
2842
  onSignedUp?.();
2525
2843
  return;
2526
2844
  }
2527
2845
  setError(
2528
2846
  labels.createdSignInFailed(
2529
- cause instanceof import_sdk4.Base316Error && cause.message ? cause.message : labels.genericError
2847
+ cause instanceof import_sdk5.Base316Error && cause.message ? cause.message : labels.genericError
2530
2848
  )
2531
2849
  );
2532
2850
  } finally {
@@ -2534,86 +2852,118 @@ function SignUp({
2534
2852
  }
2535
2853
  }
2536
2854
  if (pending) {
2537
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SecondFactorStep, { pending, labels: secondFactorLabels, onSignedIn: onSignedUp }) });
2855
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SecondFactorStep, { pending, labels: secondFactorLabels, onSignedIn: onSignedUp }) });
2538
2856
  }
2539
2857
  if (confirmEmail) {
2540
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: cls("b316-card", className), style, children: [
2541
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h3", { className: "b316-form-title", children: labels.confirmEmailTitle }),
2542
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("output", { className: "b316-muted", children: labels.confirmEmail(email) })
2858
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: cls("b316-card", className), style, children: [
2859
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { className: "b316-form-title", children: labels.confirmEmailTitle }),
2860
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("output", { className: "b316-muted", children: labels.confirmEmail(email) })
2543
2861
  ] });
2544
2862
  }
2545
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
2546
- preview ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "b316-muted", children: labels.joining(preview.organizationName, preview.roleName) }) : null,
2547
- error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
2548
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "b316-field", children: [
2549
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "b316-label", htmlFor: "b316-name", children: labels.name }),
2550
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2551
- "input",
2552
- {
2553
- id: "b316-name",
2554
- className: "b316-input",
2555
- value: name,
2556
- onChange: (event) => setName(event.target.value),
2557
- autoComplete: "name"
2558
- }
2559
- )
2560
- ] }),
2561
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "b316-field", children: [
2562
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "b316-label", htmlFor: "b316-signup-email", children: labels.email }),
2563
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2564
- "input",
2565
- {
2566
- id: "b316-signup-email",
2567
- className: "b316-input",
2568
- type: "email",
2569
- value: email,
2570
- onChange: (event) => setEmail(event.target.value),
2571
- autoComplete: "email",
2572
- required: true
2573
- }
2574
- )
2575
- ] }),
2576
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "b316-field", children: [
2577
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "b316-label", htmlFor: "b316-signup-password", children: labels.password }),
2578
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2579
- "input",
2863
+ if (!offered.signUp && !invitation) {
2864
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("output", { className: "b316-muted", children: labels.closed }) });
2865
+ }
2866
+ const socialOptions = invitation ? [] : offered.social;
2867
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
2868
+ socialOptions.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2869
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2870
+ SocialButtons,
2580
2871
  {
2581
- id: "b316-signup-password",
2582
- className: "b316-input",
2583
- type: "password",
2584
- value: password,
2585
- onChange: (event) => setPassword(event.target.value),
2586
- autoComplete: "new-password",
2587
- minLength: policy?.minLength,
2588
- maxLength: policy?.maxLength,
2589
- "aria-describedby": policy ? "b316-signup-password-rules" : void 0,
2590
- required: true
2872
+ options: socialOptions,
2873
+ continueWith: labels.continueWith,
2874
+ disabled: busy,
2875
+ onChoose: (option) => {
2876
+ if (!socialRedirectUrl) {
2877
+ return;
2878
+ }
2879
+ setBusy(true);
2880
+ beginRedirect(
2881
+ (state) => client.socialSignInUrl({
2882
+ provider: option.slug,
2883
+ redirectUri: socialRedirectUrl,
2884
+ state,
2885
+ hostedUrl: offered.hostedUrl
2886
+ }),
2887
+ socialState
2888
+ );
2889
+ }
2591
2890
  }
2592
2891
  ),
2593
- policy ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: "b316-signup-password-rules", className: "b316-muted", children: describeRules(policy, labels) }) : null
2594
- ] }),
2595
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { className: "b316-button", type: "submit", disabled: busy, children: busy ? labels.working : labels.submit })
2892
+ offered.password ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "b316-divider", children: labels.or }) : null
2893
+ ] }) : null,
2894
+ preview ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "b316-muted", children: labels.joining(preview.organizationName, preview.roleName) }) : null,
2895
+ error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
2896
+ offered.password || socialOptions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2897
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "b316-field", children: [
2898
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "b316-label", htmlFor: "b316-name", children: labels.name }),
2899
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2900
+ "input",
2901
+ {
2902
+ id: "b316-name",
2903
+ className: "b316-input",
2904
+ value: name,
2905
+ onChange: (event) => setName(event.target.value),
2906
+ autoComplete: "name"
2907
+ }
2908
+ )
2909
+ ] }),
2910
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "b316-field", children: [
2911
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "b316-label", htmlFor: "b316-signup-email", children: labels.email }),
2912
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2913
+ "input",
2914
+ {
2915
+ id: "b316-signup-email",
2916
+ className: "b316-input",
2917
+ type: "email",
2918
+ value: email,
2919
+ onChange: (event) => setEmail(event.target.value),
2920
+ autoComplete: "email",
2921
+ required: true
2922
+ }
2923
+ )
2924
+ ] }),
2925
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "b316-field", children: [
2926
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: "b316-label", htmlFor: "b316-signup-password", children: labels.password }),
2927
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2928
+ "input",
2929
+ {
2930
+ id: "b316-signup-password",
2931
+ className: "b316-input",
2932
+ type: "password",
2933
+ value: password,
2934
+ onChange: (event) => setPassword(event.target.value),
2935
+ autoComplete: "new-password",
2936
+ minLength: policy?.minLength,
2937
+ maxLength: policy?.maxLength,
2938
+ "aria-describedby": policy ? "b316-signup-password-rules" : void 0,
2939
+ required: true
2940
+ }
2941
+ ),
2942
+ policy ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { id: "b316-signup-password-rules", className: "b316-muted", children: describeRules(policy, labels) }) : null
2943
+ ] }),
2944
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { className: "b316-button", type: "submit", disabled: busy, children: busy ? labels.working : labels.submit })
2945
+ ] }) : null
2596
2946
  ] });
2597
2947
  }
2598
2948
 
2599
2949
  // src/UserProfile.tsx
2600
- var import_jsx_runtime10 = require("react/jsx-runtime");
2950
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2601
2951
  function UserProfile({ className, style }) {
2602
2952
  const { session, loading, signOut } = useBase316();
2603
2953
  if (loading) {
2604
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
2954
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
2605
2955
  }
2606
2956
  if (!session) {
2607
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: cls("b316-card", className), style, children: "Not signed in." });
2957
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cls("b316-card", className), style, children: "Not signed in." });
2608
2958
  }
2609
2959
  const user = session.user ?? {};
2610
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "b316-row", children: [
2611
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
2612
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { fontWeight: 600 }, children: user.name || user.email || "Signed in" }),
2613
- user.name && user.email ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "b316-muted", children: user.email }) : null,
2614
- user.emailVerified === false ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "b316-muted", children: "Email not verified" }) : null
2960
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "b316-row", children: [
2961
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
2962
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: { fontWeight: 600 }, children: user.name || user.email || "Signed in" }),
2963
+ user.name && user.email ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "b316-muted", children: user.email }) : null,
2964
+ user.emailVerified === false ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "b316-muted", children: "Email not verified" }) : null
2615
2965
  ] }),
2616
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2966
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2617
2967
  "button",
2618
2968
  {
2619
2969
  type: "button",
@@ -2626,12 +2976,12 @@ function UserProfile({ className, style }) {
2626
2976
  }
2627
2977
 
2628
2978
  // src/PasskeyManager.tsx
2629
- var import_sdk5 = require("@base316/sdk");
2630
- var import_react10 = require("react");
2979
+ var import_sdk6 = require("@base316/sdk");
2980
+ var import_react11 = require("react");
2631
2981
 
2632
2982
  // src/confirm.tsx
2633
- var import_react9 = require("react");
2634
- var import_jsx_runtime11 = require("react/jsx-runtime");
2983
+ var import_react10 = require("react");
2984
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2635
2985
  var DEFAULT_TIMEOUT_MS = 5e3;
2636
2986
  function ConfirmButton({
2637
2987
  children,
@@ -2641,9 +2991,9 @@ function ConfirmButton({
2641
2991
  disabled,
2642
2992
  timeoutMs = DEFAULT_TIMEOUT_MS
2643
2993
  }) {
2644
- const [armed, setArmed] = (0, import_react9.useState)(false);
2645
- const confirmRef = (0, import_react9.useRef)(null);
2646
- (0, import_react9.useEffect)(() => {
2994
+ const [armed, setArmed] = (0, import_react10.useState)(false);
2995
+ const confirmRef = (0, import_react10.useRef)(null);
2996
+ (0, import_react10.useEffect)(() => {
2647
2997
  if (!armed) {
2648
2998
  return;
2649
2999
  }
@@ -2652,7 +3002,7 @@ function ConfirmButton({
2652
3002
  return () => clearTimeout(timer);
2653
3003
  }, [armed, timeoutMs]);
2654
3004
  if (!armed) {
2655
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3005
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2656
3006
  "button",
2657
3007
  {
2658
3008
  type: "button",
@@ -2666,8 +3016,8 @@ function ConfirmButton({
2666
3016
  return (
2667
3017
  // No `role="group"`: both buttons already say what they do, and the
2668
3018
  // grouping would only repeat the question a screen reader has just read.
2669
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "b316-confirm", children: [
2670
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3019
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "b316-confirm", children: [
3020
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2671
3021
  "button",
2672
3022
  {
2673
3023
  ref: confirmRef,
@@ -2681,7 +3031,7 @@ function ConfirmButton({
2681
3031
  children: confirmLabel
2682
3032
  }
2683
3033
  ),
2684
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3034
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2685
3035
  "button",
2686
3036
  {
2687
3037
  type: "button",
@@ -2695,19 +3045,19 @@ function ConfirmButton({
2695
3045
  }
2696
3046
 
2697
3047
  // src/PasskeyManager.tsx
2698
- var import_jsx_runtime12 = require("react/jsx-runtime");
3048
+ var import_jsx_runtime14 = require("react/jsx-runtime");
2699
3049
  function PasskeyManager({
2700
3050
  className,
2701
3051
  style,
2702
3052
  title = "Passkeys"
2703
3053
  }) {
2704
3054
  const { client, token, session } = useBase316();
2705
- const [passkeys, setPasskeys] = (0, import_react10.useState)(null);
2706
- const [busy, setBusy] = (0, import_react10.useState)(false);
2707
- const [error, setError] = (0, import_react10.useState)(null);
2708
- const [name, setName] = (0, import_react10.useState)("");
2709
- const [supported, setSupported] = (0, import_react10.useState)(false);
2710
- const load = (0, import_react10.useCallback)(async () => {
3055
+ const [passkeys, setPasskeys] = (0, import_react11.useState)(null);
3056
+ const [busy, setBusy] = (0, import_react11.useState)(false);
3057
+ const [error, setError] = (0, import_react11.useState)(null);
3058
+ const [name, setName] = (0, import_react11.useState)("");
3059
+ const [supported, setSupported] = (0, import_react11.useState)(false);
3060
+ const load = (0, import_react11.useCallback)(async () => {
2711
3061
  if (!token) {
2712
3062
  return;
2713
3063
  }
@@ -2720,8 +3070,8 @@ function PasskeyManager({
2720
3070
  setPasskeys(null);
2721
3071
  }
2722
3072
  }, [client, token]);
2723
- (0, import_react10.useEffect)(() => {
2724
- if (!(0, import_sdk5.isPasskeySupported)()) {
3073
+ (0, import_react11.useEffect)(() => {
3074
+ if (!(0, import_sdk6.isPasskeySupported)()) {
2725
3075
  return;
2726
3076
  }
2727
3077
  setSupported(true);
@@ -2756,18 +3106,18 @@ function PasskeyManager({
2756
3106
  setError(caught instanceof Error ? caught.message : "That did not work.");
2757
3107
  }
2758
3108
  };
2759
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: cls("b316-card", className), style, children: [
2760
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: { fontWeight: 600, marginBottom: 4 }, children: title }),
2761
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "b316-muted", style: { marginBottom: 12 }, children: "Sign in with your fingerprint, face or a security key \u2014 nothing to type and nothing to remember." }),
2762
- passkeys === null ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "b316-muted", children: "Loading\u2026" }) : passkeys.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "b316-muted", children: "No passkeys yet." }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: passkeys.map((passkey) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("li", { className: "b316-row", style: { padding: "8px 0" }, children: [
2763
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
2764
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { children: passkey.name || "Passkey" }),
2765
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "b316-muted", children: [
3109
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: cls("b316-card", className), style, children: [
3110
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontWeight: 600, marginBottom: 4 }, children: title }),
3111
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "b316-muted", style: { marginBottom: 12 }, children: "Sign in with your fingerprint, face or a security key \u2014 nothing to type and nothing to remember." }),
3112
+ passkeys === null ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "b316-muted", children: "Loading\u2026" }) : passkeys.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "b316-muted", children: "No passkeys yet." }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: passkeys.map((passkey) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("li", { className: "b316-row", style: { padding: "8px 0" }, children: [
3113
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { children: [
3114
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { children: passkey.name || "Passkey" }),
3115
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "b316-muted", children: [
2766
3116
  passkey.lastUsedAt ? `Last used ${formatDate(passkey.lastUsedAt)}` : `Added ${formatDate(passkey.createdAt)}`,
2767
3117
  passkey.backedUp ? "" : " \xB7 this device only"
2768
3118
  ] })
2769
3119
  ] }),
2770
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3120
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2771
3121
  ConfirmButton,
2772
3122
  {
2773
3123
  className: "b316-button b316-button-secondary",
@@ -2777,9 +3127,9 @@ function PasskeyManager({
2777
3127
  }
2778
3128
  )
2779
3129
  ] }, passkey.id)) }),
2780
- error ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "b316-error", role: "alert", style: { marginTop: 12 }, children: error }) : null,
2781
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "b316-row", style: { marginTop: 12, gap: 8 }, children: [
2782
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3130
+ error ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "b316-error", role: "alert", style: { marginTop: 12 }, children: error }) : null,
3131
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "b316-row", style: { marginTop: 12, gap: 8 }, children: [
3132
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2783
3133
  "input",
2784
3134
  {
2785
3135
  className: "b316-input",
@@ -2788,7 +3138,7 @@ function PasskeyManager({
2788
3138
  onChange: (event) => setName(event.target.value)
2789
3139
  }
2790
3140
  ),
2791
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: () => void add(), children: busy ? "Waiting\u2026" : "Add a passkey" })
3141
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: () => void add(), children: busy ? "Waiting\u2026" : "Add a passkey" })
2792
3142
  ] })
2793
3143
  ] });
2794
3144
  }
@@ -2798,8 +3148,8 @@ function formatDate(value) {
2798
3148
  }
2799
3149
 
2800
3150
  // src/ActiveSessions.tsx
2801
- var import_react11 = require("react");
2802
- var import_jsx_runtime13 = require("react/jsx-runtime");
3151
+ var import_react12 = require("react");
3152
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2803
3153
  function describeDevice(userAgent) {
2804
3154
  if (!userAgent) {
2805
3155
  return null;
@@ -2817,10 +3167,10 @@ function when(value) {
2817
3167
  }
2818
3168
  function ActiveSessions({ onRevoked, className, style }) {
2819
3169
  const { client, token } = useBase316();
2820
- const [sessions, setSessions] = (0, import_react11.useState)(null);
2821
- const [error, setError] = (0, import_react11.useState)(null);
2822
- const [busy, setBusy] = (0, import_react11.useState)(false);
2823
- const load = (0, import_react11.useCallback)(() => {
3170
+ const [sessions, setSessions] = (0, import_react12.useState)(null);
3171
+ const [error, setError] = (0, import_react12.useState)(null);
3172
+ const [busy, setBusy] = (0, import_react12.useState)(false);
3173
+ const load = (0, import_react12.useCallback)(() => {
2824
3174
  if (!token) {
2825
3175
  return;
2826
3176
  }
@@ -2831,15 +3181,15 @@ function ActiveSessions({ onRevoked, className, style }) {
2831
3181
  setError(cause instanceof Error ? cause.message : "Could not load your sessions.");
2832
3182
  });
2833
3183
  }, [client, token]);
2834
- (0, import_react11.useEffect)(load, [load]);
3184
+ (0, import_react12.useEffect)(load, [load]);
2835
3185
  if (!token) {
2836
3186
  return null;
2837
3187
  }
2838
3188
  if (error) {
2839
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
3189
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
2840
3190
  }
2841
3191
  if (!sessions) {
2842
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
3192
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
2843
3193
  }
2844
3194
  async function revokeOthers() {
2845
3195
  setBusy(true);
@@ -2853,32 +3203,32 @@ function ActiveSessions({ onRevoked, className, style }) {
2853
3203
  setBusy(false);
2854
3204
  }
2855
3205
  }
2856
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: cls("b316-card b316-sessions", className), style, children: [
2857
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "b316-sessions-head", children: [
2858
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h3", { className: "b316-sessions-title", children: "Where you are signed in" }),
2859
- sessions.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: revokeOthers, children: busy ? "Ending\u2026" : "Sign out other devices" }) : null
3206
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: cls("b316-card b316-sessions", className), style, children: [
3207
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-sessions-head", children: [
3208
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h3", { className: "b316-sessions-title", children: "Where you are signed in" }),
3209
+ sessions.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: revokeOthers, children: busy ? "Ending\u2026" : "Sign out other devices" }) : null
2860
3210
  ] }),
2861
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("ul", { className: "b316-sessions-list", children: sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("li", { className: "b316-session", children: [
2862
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "b316-session-device", children: [
3211
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("ul", { className: "b316-sessions-list", children: sessions.map((session) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("li", { className: "b316-session", children: [
3212
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-session-device", children: [
2863
3213
  describeDevice(session.userAgent) ?? "Unknown device",
2864
3214
  session.impersonatedBy ? (
2865
3215
  // Worth saying loudly: somebody is acting as this account.
2866
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "b316-chip", children: " Support access" })
3216
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "b316-chip", children: " Support access" })
2867
3217
  ) : null
2868
3218
  ] }),
2869
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "b316-muted", children: [
3219
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-muted", children: [
2870
3220
  session.ipAddress ? `${session.ipAddress} \xB7 ` : "",
2871
3221
  "last used ",
2872
3222
  when(session.lastSeenAt)
2873
3223
  ] })
2874
3224
  ] }, session.id)) }),
2875
- sessions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "b316-muted", children: "No active sessions." }) : null
3225
+ sessions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "b316-muted", children: "No active sessions." }) : null
2876
3226
  ] });
2877
3227
  }
2878
3228
 
2879
3229
  // src/DeviceApproval.tsx
2880
- var import_react12 = require("react");
2881
- var import_jsx_runtime14 = require("react/jsx-runtime");
3230
+ var import_react13 = require("react");
3231
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2882
3232
  function DeviceApproval({
2883
3233
  userCode = "",
2884
3234
  onDecided,
@@ -2886,11 +3236,11 @@ function DeviceApproval({
2886
3236
  style
2887
3237
  }) {
2888
3238
  const { client, token } = useBase316();
2889
- const [code, setCode] = (0, import_react12.useState)(userCode);
2890
- const [request, setRequest] = (0, import_react12.useState)(null);
2891
- const [decided, setDecided] = (0, import_react12.useState)(null);
2892
- const [error, setError] = (0, import_react12.useState)(null);
2893
- const [busy, setBusy] = (0, import_react12.useState)(false);
3239
+ const [code, setCode] = (0, import_react13.useState)(userCode);
3240
+ const [request, setRequest] = (0, import_react13.useState)(null);
3241
+ const [decided, setDecided] = (0, import_react13.useState)(null);
3242
+ const [error, setError] = (0, import_react13.useState)(null);
3243
+ const [busy, setBusy] = (0, import_react13.useState)(false);
2894
3244
  if (!token) {
2895
3245
  return null;
2896
3246
  }
@@ -2923,25 +3273,25 @@ function DeviceApproval({
2923
3273
  }
2924
3274
  }
2925
3275
  if (decided !== null) {
2926
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: cls("b316-card b316-device", className), style, children: [
2927
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: "b316-device-title", children: decided ? "You're all set" : "Not approved" }),
2928
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "b316-muted", children: decided ? "You can close this page and go back to your device." : "Nothing was granted. You can close this page." })
3276
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: cls("b316-card b316-device", className), style, children: [
3277
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h3", { className: "b316-device-title", children: decided ? "You're all set" : "Not approved" }),
3278
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "b316-muted", children: decided ? "You can close this page and go back to your device." : "Nothing was granted. You can close this page." })
2929
3279
  ] });
2930
3280
  }
2931
3281
  if (request) {
2932
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: cls("b316-card b316-device", className), style, children: [
2933
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("h3", { className: "b316-device-title", children: [
3282
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: cls("b316-card b316-device", className), style, children: [
3283
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("h3", { className: "b316-device-title", children: [
2934
3284
  "Sign in to ",
2935
3285
  request.clientName
2936
3286
  ] }),
2937
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { className: "b316-muted", children: [
3287
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("p", { className: "b316-muted", children: [
2938
3288
  request.clientName,
2939
3289
  " is asking to sign in as you."
2940
3290
  ] }),
2941
- request.scopes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("ul", { className: "b316-device-scopes", children: request.scopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("li", { children: scope }, scope)) }) : null,
2942
- error ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
2943
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "b316-device-actions", children: [
2944
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3291
+ request.scopes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("ul", { className: "b316-device-scopes", children: request.scopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("li", { children: scope }, scope)) }) : null,
3292
+ error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3293
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "b316-device-actions", children: [
3294
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2945
3295
  "button",
2946
3296
  {
2947
3297
  type: "button",
@@ -2951,7 +3301,7 @@ function DeviceApproval({
2951
3301
  children: busy ? "Approving\u2026" : "Approve"
2952
3302
  }
2953
3303
  ),
2954
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3304
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2955
3305
  "button",
2956
3306
  {
2957
3307
  type: "button",
@@ -2964,11 +3314,11 @@ function DeviceApproval({
2964
3314
  ] })
2965
3315
  ] });
2966
3316
  }
2967
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("form", { className: cls("b316-card b316-device", className), style, onSubmit: lookUp, children: [
2968
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: "b316-device-title", children: "Connect your device" }),
2969
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "b316-muted", children: "Enter the code shown on your device." }),
2970
- error ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
2971
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3317
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("form", { className: cls("b316-card b316-device", className), style, onSubmit: lookUp, children: [
3318
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h3", { className: "b316-device-title", children: "Connect your device" }),
3319
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "b316-muted", children: "Enter the code shown on your device." }),
3320
+ error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3321
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2972
3322
  "input",
2973
3323
  {
2974
3324
  className: "b316-input",
@@ -2981,13 +3331,13 @@ function DeviceApproval({
2981
3331
  "aria-label": "Device code"
2982
3332
  }
2983
3333
  ),
2984
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || code.trim().length < 4, children: busy ? "Checking\u2026" : "Continue" })
3334
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || code.trim().length < 4, children: busy ? "Checking\u2026" : "Continue" })
2985
3335
  ] });
2986
3336
  }
2987
3337
 
2988
3338
  // src/PrivacyControls.tsx
2989
- var import_react13 = require("react");
2990
- var import_jsx_runtime15 = require("react/jsx-runtime");
3339
+ var import_react14 = require("react");
3340
+ var import_jsx_runtime17 = require("react/jsx-runtime");
2991
3341
  function PrivacyControls({
2992
3342
  confirmWord = "DELETE",
2993
3343
  onErased,
@@ -2995,10 +3345,10 @@ function PrivacyControls({
2995
3345
  style
2996
3346
  }) {
2997
3347
  const { client, token } = useBase316();
2998
- const [confirming, setConfirming] = (0, import_react13.useState)(false);
2999
- const [typed, setTyped] = (0, import_react13.useState)("");
3000
- const [error, setError] = (0, import_react13.useState)(null);
3001
- const [busy, setBusy] = (0, import_react13.useState)(false);
3348
+ const [confirming, setConfirming] = (0, import_react14.useState)(false);
3349
+ const [typed, setTyped] = (0, import_react14.useState)("");
3350
+ const [error, setError] = (0, import_react14.useState)(null);
3351
+ const [busy, setBusy] = (0, import_react14.useState)(false);
3002
3352
  if (!token) {
3003
3353
  return null;
3004
3354
  }
@@ -3033,22 +3383,22 @@ function PrivacyControls({
3033
3383
  setBusy(false);
3034
3384
  }
3035
3385
  }
3036
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: cls("b316-card b316-privacy", className), style, children: [
3037
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h3", { className: "b316-privacy-title", children: "Your data" }),
3038
- error ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3039
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-privacy-row", children: [
3040
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
3041
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { children: "Download a copy" }),
3042
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "b316-muted", children: "Everything we hold about you, as a file. Passwords and security keys are not included \u2014 they are what protect the account rather than anything you can use." })
3386
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: cls("b316-card b316-privacy", className), style, children: [
3387
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { className: "b316-privacy-title", children: "Your data" }),
3388
+ error ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3389
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-privacy-row", children: [
3390
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
3391
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { children: "Download a copy" }),
3392
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "b316-muted", children: "Everything we hold about you, as a file. Passwords and security keys are not included \u2014 they are what protect the account rather than anything you can use." })
3043
3393
  ] }),
3044
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", className: "b316-button-quiet", disabled: busy, onClick: download, children: busy ? "Preparing\u2026" : "Download" })
3394
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", className: "b316-button-quiet", disabled: busy, onClick: download, children: busy ? "Preparing\u2026" : "Download" })
3045
3395
  ] }),
3046
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-privacy-row", children: [
3047
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
3048
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { children: "Delete your account" }),
3049
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "b316-muted", children: "Permanent. Invoices already raised are kept, because the law requires it; everything that identifies you is removed from them." })
3396
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-privacy-row", children: [
3397
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
3398
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { children: "Delete your account" }),
3399
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "b316-muted", children: "Permanent. Invoices already raised are kept, because the law requires it; everything that identifies you is removed from them." })
3050
3400
  ] }),
3051
- confirming ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3401
+ confirming ? null : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3052
3402
  "button",
3053
3403
  {
3054
3404
  type: "button",
@@ -3059,13 +3409,13 @@ function PrivacyControls({
3059
3409
  }
3060
3410
  )
3061
3411
  ] }),
3062
- confirming ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-privacy-confirm", children: [
3063
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "b316-label", htmlFor: "b316-privacy-confirm", children: [
3412
+ confirming ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-privacy-confirm", children: [
3413
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("label", { className: "b316-label", htmlFor: "b316-privacy-confirm", children: [
3064
3414
  "Type ",
3065
3415
  confirmWord,
3066
3416
  " to confirm"
3067
3417
  ] }),
3068
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3418
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3069
3419
  "input",
3070
3420
  {
3071
3421
  id: "b316-privacy-confirm",
@@ -3075,8 +3425,8 @@ function PrivacyControls({
3075
3425
  onChange: (event) => setTyped(event.target.value)
3076
3426
  }
3077
3427
  ),
3078
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-privacy-actions", children: [
3079
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3428
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-privacy-actions", children: [
3429
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3080
3430
  "button",
3081
3431
  {
3082
3432
  type: "button",
@@ -3088,7 +3438,7 @@ function PrivacyControls({
3088
3438
  children: "Cancel"
3089
3439
  }
3090
3440
  ),
3091
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3441
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3092
3442
  "button",
3093
3443
  {
3094
3444
  type: "button",
@@ -3104,12 +3454,12 @@ function PrivacyControls({
3104
3454
  }
3105
3455
 
3106
3456
  // src/TwoFactorManager.tsx
3107
- var import_react15 = require("react");
3457
+ var import_react16 = require("react");
3108
3458
 
3109
3459
  // src/QrCode.tsx
3110
3460
  var import_qrcode_generator = __toESM(require("qrcode-generator"));
3111
- var import_react14 = require("react");
3112
- var import_jsx_runtime16 = require("react/jsx-runtime");
3461
+ var import_react15 = require("react");
3462
+ var import_jsx_runtime18 = require("react/jsx-runtime");
3113
3463
  var QUIET_ZONE = 4;
3114
3464
  function utf8Binary(value) {
3115
3465
  let binary = "";
@@ -3134,9 +3484,9 @@ function qrPath(value) {
3134
3484
  return { path, modules };
3135
3485
  }
3136
3486
  function QrCode({ value, label, size = 180, className }) {
3137
- const { path, modules } = (0, import_react14.useMemo)(() => qrPath(value), [value]);
3487
+ const { path, modules } = (0, import_react15.useMemo)(() => qrPath(value), [value]);
3138
3488
  const extent = modules + QUIET_ZONE * 2;
3139
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3489
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
3140
3490
  "svg",
3141
3491
  {
3142
3492
  className,
@@ -3148,15 +3498,15 @@ function QrCode({ value, label, size = 180, className }) {
3148
3498
  shapeRendering: "crispEdges",
3149
3499
  xmlns: "http://www.w3.org/2000/svg",
3150
3500
  children: [
3151
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("rect", { width: extent, height: extent, fill: "#ffffff" }),
3152
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: path, fill: "#000000" })
3501
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("rect", { width: extent, height: extent, fill: "#ffffff" }),
3502
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { d: path, fill: "#000000" })
3153
3503
  ]
3154
3504
  }
3155
3505
  );
3156
3506
  }
3157
3507
 
3158
3508
  // src/TwoFactorManager.tsx
3159
- var import_jsx_runtime17 = require("react/jsx-runtime");
3509
+ var import_jsx_runtime19 = require("react/jsx-runtime");
3160
3510
  function groupKey(secret) {
3161
3511
  return secret.replace(/\s+/g, "").replace(/(.{4})(?=.)/g, "$1 ");
3162
3512
  }
@@ -3169,12 +3519,12 @@ function TwoFactorManager({
3169
3519
  style
3170
3520
  }) {
3171
3521
  const { client, token } = useBase316();
3172
- const [stage, setStage] = (0, import_react15.useState)({ name: "idle" });
3173
- const [on, setOn] = (0, import_react15.useState)(enabled);
3174
- const [code, setCode] = (0, import_react15.useState)("");
3175
- const [phone, setPhone] = (0, import_react15.useState)("");
3176
- const [error, setError] = (0, import_react15.useState)(null);
3177
- const [busy, setBusy] = (0, import_react15.useState)(false);
3522
+ const [stage, setStage] = (0, import_react16.useState)({ name: "idle" });
3523
+ const [on, setOn] = (0, import_react16.useState)(enabled);
3524
+ const [code, setCode] = (0, import_react16.useState)("");
3525
+ const [phone, setPhone] = (0, import_react16.useState)("");
3526
+ const [error, setError] = (0, import_react16.useState)(null);
3527
+ const [busy, setBusy] = (0, import_react16.useState)(false);
3178
3528
  if (!token) {
3179
3529
  return null;
3180
3530
  }
@@ -3252,17 +3602,17 @@ function TwoFactorManager({
3252
3602
  setBusy(false);
3253
3603
  }
3254
3604
  }
3255
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: cls("b316-card b316-mfa", className), style, children: [
3256
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { className: "b316-mfa-title", children: "Two-factor authentication" }),
3257
- error ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3258
- stage.name === "saved" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-codes", children: [
3259
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { children: "Save these recovery codes somewhere safe. Each one signs you in once if you lose your authenticator, and they are not shown again." }),
3260
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("ul", { className: "b316-mfa-code-list", children: stage.recoveryCodes.map((recovery) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("code", { children: recovery }) }, recovery)) }),
3261
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", className: "b316-button", onClick: () => setStage({ name: "idle" }), children: "I have saved them" })
3262
- ] }) : stage.name === "smsNumber" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-enrol", children: [
3263
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { children: "We will text a code to this number now, and each time you sign in." }),
3264
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-phone", children: "Mobile number" }),
3265
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3605
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: cls("b316-card b316-mfa", className), style, children: [
3606
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "b316-mfa-title", children: "Two-factor authentication" }),
3607
+ error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3608
+ stage.name === "saved" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-codes", children: [
3609
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { children: "Save these recovery codes somewhere safe. Each one signs you in once if you lose your authenticator, and they are not shown again." }),
3610
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("ul", { className: "b316-mfa-code-list", children: stage.recoveryCodes.map((recovery) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("code", { children: recovery }) }, recovery)) }),
3611
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", className: "b316-button", onClick: () => setStage({ name: "idle" }), children: "I have saved them" })
3612
+ ] }) : stage.name === "smsNumber" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-enrol", children: [
3613
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { children: "We will text a code to this number now, and each time you sign in." }),
3614
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-phone", children: "Mobile number" }),
3615
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3266
3616
  "input",
3267
3617
  {
3268
3618
  id: "b316-mfa-phone",
@@ -3274,8 +3624,8 @@ function TwoFactorManager({
3274
3624
  onChange: (event) => setPhone(event.target.value)
3275
3625
  }
3276
3626
  ),
3277
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-actions", children: [
3278
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3627
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-actions", children: [
3628
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3279
3629
  "button",
3280
3630
  {
3281
3631
  type: "button",
@@ -3284,16 +3634,16 @@ function TwoFactorManager({
3284
3634
  children: "Cancel"
3285
3635
  }
3286
3636
  ),
3287
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: beginSms, children: busy ? "Sending\u2026" : "Send code" })
3637
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: beginSms, children: busy ? "Sending\u2026" : "Send code" })
3288
3638
  ] })
3289
- ] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-enrol", children: [
3290
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("p", { children: [
3639
+ ] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-enrol", children: [
3640
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("p", { children: [
3291
3641
  "We sent a code to ",
3292
3642
  stage.destinationHint,
3293
3643
  ". Enter it below to turn this on."
3294
3644
  ] }),
3295
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3296
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3645
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3646
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3297
3647
  "input",
3298
3648
  {
3299
3649
  id: "b316-mfa-code",
@@ -3304,8 +3654,8 @@ function TwoFactorManager({
3304
3654
  onChange: (event) => setCode(event.target.value)
3305
3655
  }
3306
3656
  ),
3307
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-actions", children: [
3308
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3657
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-actions", children: [
3658
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3309
3659
  "button",
3310
3660
  {
3311
3661
  type: "button",
@@ -3314,7 +3664,7 @@ function TwoFactorManager({
3314
3664
  children: "Cancel"
3315
3665
  }
3316
3666
  ),
3317
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3667
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3318
3668
  "button",
3319
3669
  {
3320
3670
  type: "button",
@@ -3325,9 +3675,9 @@ function TwoFactorManager({
3325
3675
  }
3326
3676
  )
3327
3677
  ] })
3328
- ] }) : stage.name === "enrolling" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-enrol", children: [
3329
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { children: "Scan this with your authenticator app (Google Authenticator, 1Password, Authy\u2026), then enter the six-digit code it shows." }),
3330
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3678
+ ] }) : stage.name === "enrolling" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-enrol", children: [
3679
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { children: "Scan this with your authenticator app (Google Authenticator, 1Password, Authy\u2026), then enter the six-digit code it shows." }),
3680
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3331
3681
  QrCode,
3332
3682
  {
3333
3683
  className: "b316-mfa-qr",
@@ -3335,13 +3685,13 @@ function TwoFactorManager({
3335
3685
  label: "QR code for your authenticator app"
3336
3686
  }
3337
3687
  ),
3338
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-secret", children: [
3339
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "b316-label", id: "b316-mfa-manual-key", children: "Can't scan? Enter this key" }),
3340
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("code", { "aria-labelledby": "b316-mfa-manual-key", children: groupKey(stage.secret) })
3688
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-secret", children: [
3689
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "b316-label", id: "b316-mfa-manual-key", children: "Can't scan? Enter this key" }),
3690
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("code", { "aria-labelledby": "b316-mfa-manual-key", children: groupKey(stage.secret) })
3341
3691
  ] }),
3342
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("a", { className: "b316-mfa-uri", href: stage.uri, children: "Open in an authenticator app" }),
3343
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3344
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3692
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("a", { className: "b316-mfa-uri", href: stage.uri, children: "Open in an authenticator app" }),
3693
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3694
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3345
3695
  "input",
3346
3696
  {
3347
3697
  id: "b316-mfa-code",
@@ -3352,8 +3702,8 @@ function TwoFactorManager({
3352
3702
  onChange: (event) => setCode(event.target.value)
3353
3703
  }
3354
3704
  ),
3355
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-actions", children: [
3356
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3705
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-actions", children: [
3706
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3357
3707
  "button",
3358
3708
  {
3359
3709
  type: "button",
@@ -3362,7 +3712,7 @@ function TwoFactorManager({
3362
3712
  children: "Cancel"
3363
3713
  }
3364
3714
  ),
3365
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3715
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3366
3716
  "button",
3367
3717
  {
3368
3718
  type: "button",
@@ -3373,9 +3723,9 @@ function TwoFactorManager({
3373
3723
  }
3374
3724
  )
3375
3725
  ] })
3376
- ] }) : on ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-on", children: [
3377
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "b316-muted", children: "On. You will be asked for a code when you sign in." }),
3378
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3726
+ ] }) : on ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-on", children: [
3727
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "b316-muted", children: "On. You will be asked for a code when you sign in." }),
3728
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3379
3729
  ConfirmButton,
3380
3730
  {
3381
3731
  className: "b316-button-quiet b316-danger",
@@ -3385,11 +3735,11 @@ function TwoFactorManager({
3385
3735
  children: "Turn off"
3386
3736
  }
3387
3737
  )
3388
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-off", children: [
3389
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "b316-muted", children: "Off. Turning it on means a code as well as your password, every time you sign in." }),
3390
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-actions", children: [
3391
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: begin, children: busy ? "Starting\u2026" : "Use an authenticator app" }),
3392
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3738
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-off", children: [
3739
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "b316-muted", children: "Off. Turning it on means a code as well as your password, every time you sign in." }),
3740
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-mfa-actions", children: [
3741
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: begin, children: busy ? "Starting\u2026" : "Use an authenticator app" }),
3742
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3393
3743
  "button",
3394
3744
  {
3395
3745
  type: "button",
@@ -3399,7 +3749,7 @@ function TwoFactorManager({
3399
3749
  children: "Email me a code"
3400
3750
  }
3401
3751
  ),
3402
- allowSms ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3752
+ allowSms ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3403
3753
  "button",
3404
3754
  {
3405
3755
  type: "button",
@@ -3415,14 +3765,14 @@ function TwoFactorManager({
3415
3765
  }
3416
3766
 
3417
3767
  // src/ForgotPassword.tsx
3418
- var import_react16 = require("react");
3419
- var import_jsx_runtime18 = require("react/jsx-runtime");
3768
+ var import_react17 = require("react");
3769
+ var import_jsx_runtime20 = require("react/jsx-runtime");
3420
3770
  function ForgotPassword({ onSent, signInUrl, className, style }) {
3421
3771
  const { client } = useBase316();
3422
- const [email, setEmail] = (0, import_react16.useState)("");
3423
- const [sent, setSent] = (0, import_react16.useState)(false);
3424
- const [busy, setBusy] = (0, import_react16.useState)(false);
3425
- const [error, setError] = (0, import_react16.useState)(null);
3772
+ const [email, setEmail] = (0, import_react17.useState)("");
3773
+ const [sent, setSent] = (0, import_react17.useState)(false);
3774
+ const [busy, setBusy] = (0, import_react17.useState)(false);
3775
+ const [error, setError] = (0, import_react17.useState)(null);
3426
3776
  async function submit(event) {
3427
3777
  event.preventDefault();
3428
3778
  setBusy(true);
@@ -3438,22 +3788,22 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
3438
3788
  }
3439
3789
  }
3440
3790
  if (sent) {
3441
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: cls("b316-card", className), style, children: [
3442
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { className: "b316-form-title", children: "Check your email" }),
3443
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("p", { className: "b316-muted", children: [
3791
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: cls("b316-card", className), style, children: [
3792
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-form-title", children: "Check your email" }),
3793
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("p", { className: "b316-muted", children: [
3444
3794
  "If there is an account for ",
3445
3795
  email.trim(),
3446
3796
  ", a link to set a new password is on its way."
3447
3797
  ] }),
3448
- signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3798
+ signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3449
3799
  ] });
3450
3800
  }
3451
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3452
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { className: "b316-form-title", children: "Reset your password" }),
3453
- error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3454
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "b316-field", children: [
3455
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { className: "b316-label", htmlFor: "b316-forgot-email", children: "Email" }),
3456
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3801
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3802
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-form-title", children: "Reset your password" }),
3803
+ error ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3804
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-field", children: [
3805
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("label", { className: "b316-label", htmlFor: "b316-forgot-email", children: "Email" }),
3806
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3457
3807
  "input",
3458
3808
  {
3459
3809
  id: "b316-forgot-email",
@@ -3466,14 +3816,14 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
3466
3816
  }
3467
3817
  )
3468
3818
  ] }),
3469
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Send reset link" }),
3470
- signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3819
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Send reset link" }),
3820
+ signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3471
3821
  ] });
3472
3822
  }
3473
3823
 
3474
3824
  // src/ResetPassword.tsx
3475
- var import_react17 = require("react");
3476
- var import_jsx_runtime19 = require("react/jsx-runtime");
3825
+ var import_react18 = require("react");
3826
+ var import_jsx_runtime21 = require("react/jsx-runtime");
3477
3827
  function ResetPassword({
3478
3828
  token: supplied,
3479
3829
  onReset,
@@ -3482,13 +3832,13 @@ function ResetPassword({
3482
3832
  style
3483
3833
  }) {
3484
3834
  const { client } = useBase316();
3485
- const [token, setToken] = (0, import_react17.useState)(supplied ?? null);
3486
- const [password, setPassword] = (0, import_react17.useState)("");
3487
- const [confirmation, setConfirmation] = (0, import_react17.useState)("");
3488
- const [done, setDone] = (0, import_react17.useState)(false);
3489
- const [busy, setBusy] = (0, import_react17.useState)(false);
3490
- const [error, setError] = (0, import_react17.useState)(null);
3491
- (0, import_react17.useEffect)(() => {
3835
+ const [token, setToken] = (0, import_react18.useState)(supplied ?? null);
3836
+ const [password, setPassword] = (0, import_react18.useState)("");
3837
+ const [confirmation, setConfirmation] = (0, import_react18.useState)("");
3838
+ const [done, setDone] = (0, import_react18.useState)(false);
3839
+ const [busy, setBusy] = (0, import_react18.useState)(false);
3840
+ const [error, setError] = (0, import_react18.useState)(null);
3841
+ (0, import_react18.useEffect)(() => {
3492
3842
  if (supplied || typeof window === "undefined") {
3493
3843
  return;
3494
3844
  }
@@ -3523,24 +3873,24 @@ function ResetPassword({
3523
3873
  }
3524
3874
  }
3525
3875
  if (done) {
3526
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: cls("b316-card", className), style, children: [
3527
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "b316-form-title", children: "Password changed" }),
3528
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "b316-muted", children: "You can sign in with your new password." }),
3529
- signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Sign in" }) : null
3876
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cls("b316-card", className), style, children: [
3877
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "b316-form-title", children: "Password changed" }),
3878
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "b316-muted", children: "You can sign in with your new password." }),
3879
+ signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Sign in" }) : null
3530
3880
  ] });
3531
3881
  }
3532
3882
  if (!token) {
3533
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: cls("b316-card", className), style, children: [
3534
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "b316-form-title", children: "Nothing to reset" }),
3535
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "b316-muted", children: "This page needs the link from your email. Request a new one if yours has expired." })
3883
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cls("b316-card", className), style, children: [
3884
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "b316-form-title", children: "Nothing to reset" }),
3885
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "b316-muted", children: "This page needs the link from your email. Request a new one if yours has expired." })
3536
3886
  ] });
3537
3887
  }
3538
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3539
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "b316-form-title", children: "Choose a new password" }),
3540
- error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3541
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-field", children: [
3542
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "b316-label", htmlFor: "b316-reset-password", children: "New password" }),
3543
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3888
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3889
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "b316-form-title", children: "Choose a new password" }),
3890
+ error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3891
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-field", children: [
3892
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { className: "b316-label", htmlFor: "b316-reset-password", children: "New password" }),
3893
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3544
3894
  "input",
3545
3895
  {
3546
3896
  id: "b316-reset-password",
@@ -3553,9 +3903,9 @@ function ResetPassword({
3553
3903
  }
3554
3904
  )
3555
3905
  ] }),
3556
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-field", children: [
3557
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "b316-label", htmlFor: "b316-reset-confirm", children: "Repeat it" }),
3558
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3906
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-field", children: [
3907
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { className: "b316-label", htmlFor: "b316-reset-confirm", children: "Repeat it" }),
3908
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3559
3909
  "input",
3560
3910
  {
3561
3911
  id: "b316-reset-confirm",
@@ -3568,13 +3918,13 @@ function ResetPassword({
3568
3918
  }
3569
3919
  )
3570
3920
  ] }),
3571
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !password, children: busy ? "Saving\u2026" : "Set password" })
3921
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !password, children: busy ? "Saving\u2026" : "Set password" })
3572
3922
  ] });
3573
3923
  }
3574
3924
 
3575
3925
  // src/VerifyEmail.tsx
3576
- var import_react18 = require("react");
3577
- var import_jsx_runtime20 = require("react/jsx-runtime");
3926
+ var import_react19 = require("react");
3927
+ var import_jsx_runtime22 = require("react/jsx-runtime");
3578
3928
  function VerifyEmail({
3579
3929
  token: supplied,
3580
3930
  onVerified,
@@ -3583,9 +3933,9 @@ function VerifyEmail({
3583
3933
  style
3584
3934
  }) {
3585
3935
  const { client } = useBase316();
3586
- const [state, setState] = (0, import_react18.useState)("waiting");
3587
- const spent = (0, import_react18.useRef)(false);
3588
- (0, import_react18.useEffect)(() => {
3936
+ const [state, setState] = (0, import_react19.useState)("waiting");
3937
+ const spent = (0, import_react19.useRef)(false);
3938
+ (0, import_react19.useEffect)(() => {
3589
3939
  if (spent.current) {
3590
3940
  return;
3591
3941
  }
@@ -3611,22 +3961,22 @@ function VerifyEmail({
3611
3961
  setState("failed");
3612
3962
  });
3613
3963
  }, [client, supplied, onVerified]);
3614
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cls("b316-card", className), style, children: state === "verified" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3615
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-form-title", children: "Email confirmed" }),
3616
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "b316-muted", children: "Thanks \u2014 your address is verified." }),
3617
- continueUrl ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("a", { className: "b316-button-link", href: continueUrl, children: "Continue" }) : null
3618
- ] }) : state === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3619
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-form-title", children: "That link did not work" }),
3620
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "b316-muted", children: "It may have expired or already been used. Ask for a new one and try again." })
3621
- ] }) : state === "missing" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3622
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-form-title", children: "Nothing to confirm" }),
3623
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "b316-muted", children: "This page needs the link from your email." })
3624
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "b316-muted", children: "Confirming your email\u2026" }) });
3964
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cls("b316-card", className), style, children: state === "verified" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3965
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "b316-form-title", children: "Email confirmed" }),
3966
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-muted", children: "Thanks \u2014 your address is verified." }),
3967
+ continueUrl ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { className: "b316-button-link", href: continueUrl, children: "Continue" }) : null
3968
+ ] }) : state === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3969
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "b316-form-title", children: "That link did not work" }),
3970
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-muted", children: "It may have expired or already been used. Ask for a new one and try again." })
3971
+ ] }) : state === "missing" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3972
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "b316-form-title", children: "Nothing to confirm" }),
3973
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-muted", children: "This page needs the link from your email." })
3974
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-muted", children: "Confirming your email\u2026" }) });
3625
3975
  }
3626
3976
 
3627
3977
  // src/TeamMembers.tsx
3628
- var import_react19 = require("react");
3629
- var import_jsx_runtime21 = require("react/jsx-runtime");
3978
+ var import_react20 = require("react");
3979
+ var import_jsx_runtime23 = require("react/jsx-runtime");
3630
3980
  function TeamMembers({
3631
3981
  organizationId,
3632
3982
  onInvited,
@@ -3636,16 +3986,16 @@ function TeamMembers({
3636
3986
  style
3637
3987
  }) {
3638
3988
  const { client, token, session } = useBase316();
3639
- const [teams, setTeams] = (0, import_react19.useState)(null);
3640
- const [members, setMembers] = (0, import_react19.useState)(null);
3641
- const [invitations, setInvitations] = (0, import_react19.useState)(null);
3642
- const [email, setEmail] = (0, import_react19.useState)("");
3643
- const [busy, setBusy] = (0, import_react19.useState)(false);
3644
- const [error, setError] = (0, import_react19.useState)(null);
3645
- const [copied, setCopied] = (0, import_react19.useState)(null);
3989
+ const [teams, setTeams] = (0, import_react20.useState)(null);
3990
+ const [members, setMembers] = (0, import_react20.useState)(null);
3991
+ const [invitations, setInvitations] = (0, import_react20.useState)(null);
3992
+ const [email, setEmail] = (0, import_react20.useState)("");
3993
+ const [busy, setBusy] = (0, import_react20.useState)(false);
3994
+ const [error, setError] = (0, import_react20.useState)(null);
3995
+ const [copied, setCopied] = (0, import_react20.useState)(null);
3646
3996
  const chosen = organizationId ?? (teams?.length === 1 ? teams[0].id : null);
3647
3997
  const team = teams?.find((candidate) => candidate.id === chosen) ?? null;
3648
- const load = (0, import_react19.useCallback)(() => {
3998
+ const load = (0, import_react20.useCallback)(() => {
3649
3999
  if (!token) {
3650
4000
  return;
3651
4001
  }
@@ -3653,8 +4003,8 @@ function TeamMembers({
3653
4003
  (cause) => setError(cause instanceof Error ? cause.message : "Could not load your teams.")
3654
4004
  );
3655
4005
  }, [client, token]);
3656
- (0, import_react19.useEffect)(load, [load]);
3657
- (0, import_react19.useEffect)(() => {
4006
+ (0, import_react20.useEffect)(load, [load]);
4007
+ (0, import_react20.useEffect)(() => {
3658
4008
  if (!token || !chosen) {
3659
4009
  return;
3660
4010
  }
@@ -3685,10 +4035,10 @@ function TeamMembers({
3685
4035
  return null;
3686
4036
  }
3687
4037
  if (!teams) {
3688
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cls("b316-card", className), style, children: error ?? "Loading\u2026" });
4038
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cls("b316-card", className), style, children: error ?? "Loading\u2026" });
3689
4039
  }
3690
4040
  if (!chosen) {
3691
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cls("b316-card", className), style, children: teams.length === 0 ? "You are not in a team yet." : "You are in more than one team. Name which with the organizationId prop." });
4041
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cls("b316-card", className), style, children: teams.length === 0 ? "You are not in a team yet." : "You are in more than one team. Name which with the organizationId prop." });
3692
4042
  }
3693
4043
  const canManage = invitations !== null;
3694
4044
  async function invite(event) {
@@ -3738,30 +4088,30 @@ function TeamMembers({
3738
4088
  setError(cause instanceof Error ? cause.message : "That invitation could not be withdrawn.");
3739
4089
  }
3740
4090
  }
3741
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cls("b316-card b316-team", className), style, children: [
3742
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "b316-team-title", children: team?.name ?? "Team" }),
4091
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: cls("b316-card b316-team", className), style, children: [
4092
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "b316-team-title", children: team?.name ?? "Team" }),
3743
4093
  team?.inherited ? (
3744
4094
  // Not a member of this team, so not in the list below and with nothing
3745
4095
  // to leave: access comes from the team that manages it, and ends there.
3746
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-muted", children: [
4096
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-muted", children: [
3747
4097
  "You have access through",
3748
4098
  " ",
3749
4099
  teams.find((candidate) => candidate.id === team.via)?.name ?? "the organization that manages this team",
3750
4100
  "."
3751
4101
  ] })
3752
4102
  ) : null,
3753
- error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3754
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("ul", { className: "b316-team-list", children: (members ?? []).map((member) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("li", { className: "b316-team-member", children: [
3755
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
3756
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: member.user.name ?? member.user.email ?? "Someone" }),
3757
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-muted", children: [
4103
+ error ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
4104
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("ul", { className: "b316-team-list", children: (members ?? []).map((member) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("li", { className: "b316-team-member", children: [
4105
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
4106
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { children: member.user.name ?? member.user.email ?? "Someone" }),
4107
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-muted", children: [
3758
4108
  member.user.email,
3759
4109
  member.user.id === session?.userId ? " \xB7 you" : ""
3760
4110
  ] })
3761
4111
  ] }),
3762
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-team-member-side", children: [
3763
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "b316-chip", children: member.role.name }),
3764
- canManage || member.user.id === session?.userId ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4112
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-team-member-side", children: [
4113
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "b316-chip", children: member.role.name }),
4114
+ canManage || member.user.id === session?.userId ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3765
4115
  ConfirmButton,
3766
4116
  {
3767
4117
  className: "b316-button-quiet b316-danger",
@@ -3773,19 +4123,19 @@ function TeamMembers({
3773
4123
  ) : null
3774
4124
  ] })
3775
4125
  ] }, member.id)) }),
3776
- canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
3777
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h4", { className: "b316-team-subtitle", children: "Invited" }),
3778
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("ul", { className: "b316-team-list", children: (invitations ?? []).map((invitation) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("li", { className: "b316-team-member", children: [
3779
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
3780
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: invitation.email }),
3781
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-muted", children: [
4126
+ canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
4127
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h4", { className: "b316-team-subtitle", children: "Invited" }),
4128
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("ul", { className: "b316-team-list", children: (invitations ?? []).map((invitation) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("li", { className: "b316-team-member", children: [
4129
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
4130
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { children: invitation.email }),
4131
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-muted", children: [
3782
4132
  invitation.role.name,
3783
4133
  " \xB7 expires",
3784
4134
  " ",
3785
4135
  new Date(invitation.expiresAt).toLocaleDateString()
3786
4136
  ] })
3787
4137
  ] }),
3788
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4138
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3789
4139
  "button",
3790
4140
  {
3791
4141
  type: "button",
@@ -3796,10 +4146,10 @@ function TeamMembers({
3796
4146
  )
3797
4147
  ] }, invitation.id)) })
3798
4148
  ] }) : null,
3799
- canManage ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("form", { className: "b316-team-invite", onSubmit: invite, children: [
3800
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { className: "b316-label", htmlFor: "b316-invite-email", children: "Invite by email" }),
3801
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-team-invite-row", children: [
3802
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4149
+ canManage ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("form", { className: "b316-team-invite", onSubmit: invite, children: [
4150
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("label", { className: "b316-label", htmlFor: "b316-invite-email", children: "Invite by email" }),
4151
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-team-invite-row", children: [
4152
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3803
4153
  "input",
3804
4154
  {
3805
4155
  id: "b316-invite-email",
@@ -3811,19 +4161,19 @@ function TeamMembers({
3811
4161
  onChange: (event) => setEmail(event.target.value)
3812
4162
  }
3813
4163
  ),
3814
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Invite" })
4164
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Invite" })
3815
4165
  ] })
3816
4166
  ] }) : null,
3817
- copied ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-team-link", children: [
3818
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "b316-muted", children: "Send them this link. It is shown once and cannot be fetched again." }),
3819
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("code", { children: copied })
4167
+ copied ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-team-link", children: [
4168
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "b316-muted", children: "Send them this link. It is shown once and cannot be fetched again." }),
4169
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("code", { children: copied })
3820
4170
  ] }) : null
3821
4171
  ] });
3822
4172
  }
3823
4173
 
3824
4174
  // src/AcceptInvitation.tsx
3825
- var import_react20 = require("react");
3826
- var import_jsx_runtime22 = require("react/jsx-runtime");
4175
+ var import_react21 = require("react");
4176
+ var import_jsx_runtime24 = require("react/jsx-runtime");
3827
4177
  function signUpUrlWithInvitation(url, token) {
3828
4178
  const [beforeHash, ...hash] = url.split("#");
3829
4179
  const base = beforeHash ?? "";
@@ -3842,18 +4192,18 @@ function AcceptInvitation({
3842
4192
  style
3843
4193
  }) {
3844
4194
  const { client, token: session, session: user } = useBase316();
3845
- const [invitationToken, setInvitationToken] = (0, import_react20.useState)(supplied ?? null);
3846
- const [preview, setPreview] = (0, import_react20.useState)(null);
3847
- const [state, setState] = (0, import_react20.useState)("loading");
3848
- const [error, setError] = (0, import_react20.useState)(null);
3849
- const [busy, setBusy] = (0, import_react20.useState)(false);
3850
- (0, import_react20.useEffect)(() => {
4195
+ const [invitationToken, setInvitationToken] = (0, import_react21.useState)(supplied ?? null);
4196
+ const [preview, setPreview] = (0, import_react21.useState)(null);
4197
+ const [state, setState] = (0, import_react21.useState)("loading");
4198
+ const [error, setError] = (0, import_react21.useState)(null);
4199
+ const [busy, setBusy] = (0, import_react21.useState)(false);
4200
+ (0, import_react21.useEffect)(() => {
3851
4201
  if (supplied || typeof window === "undefined") {
3852
4202
  return;
3853
4203
  }
3854
4204
  setInvitationToken(new URL(window.location.href).searchParams.get("invitation"));
3855
4205
  }, [supplied]);
3856
- (0, import_react20.useEffect)(() => {
4206
+ (0, import_react21.useEffect)(() => {
3857
4207
  if (!invitationToken) {
3858
4208
  setState(supplied === void 0 ? "loading" : "invalid");
3859
4209
  return;
@@ -3890,42 +4240,42 @@ function AcceptInvitation({
3890
4240
  }
3891
4241
  }
3892
4242
  if (state === "loading") {
3893
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
4243
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
3894
4244
  }
3895
4245
  if (state === "invalid") {
3896
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cls("b316-card", className), style, children: [
3897
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "b316-form-title", children: "That invitation is no longer valid" }),
3898
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-muted", children: "It may have expired, been withdrawn, or already been used. Ask for a new one." })
4246
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cls("b316-card", className), style, children: [
4247
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "b316-form-title", children: "That invitation is no longer valid" }),
4248
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "b316-muted", children: "It may have expired, been withdrawn, or already been used. Ask for a new one." })
3899
4249
  ] });
3900
4250
  }
3901
4251
  if (state === "accepted") {
3902
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("h3", { className: "b316-form-title", children: [
4252
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("h3", { className: "b316-form-title", children: [
3903
4253
  "You have joined ",
3904
4254
  preview?.organizationName
3905
4255
  ] }) });
3906
4256
  }
3907
4257
  const matches = !user || (user.user.email ?? "").toLowerCase() === preview?.email.toLowerCase();
3908
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cls("b316-card b316-invitation", className), style, children: [
3909
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("h3", { className: "b316-form-title", children: [
4258
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cls("b316-card b316-invitation", className), style, children: [
4259
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("h3", { className: "b316-form-title", children: [
3910
4260
  "Join ",
3911
4261
  preview?.organizationName
3912
4262
  ] }),
3913
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("p", { className: "b316-muted", children: [
4263
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("p", { className: "b316-muted", children: [
3914
4264
  "Invited as ",
3915
4265
  preview?.email,
3916
4266
  " \xB7 ",
3917
4267
  preview?.roleName
3918
4268
  ] }),
3919
- error ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3920
- !session ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3921
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("p", { children: [
4269
+ error ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
4270
+ !session ? /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
4271
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("p", { children: [
3922
4272
  "Sign in as ",
3923
4273
  preview?.email,
3924
4274
  " to accept."
3925
4275
  ] }),
3926
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "b316-invitation-actions", children: [
3927
- signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { className: "b316-button", href: signInUrl, children: "Sign in" }) : null,
3928
- signUpUrl ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4276
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-invitation-actions", children: [
4277
+ signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("a", { className: "b316-button", href: signInUrl, children: "Sign in" }) : null,
4278
+ signUpUrl ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3929
4279
  "a",
3930
4280
  {
3931
4281
  className: "b316-button-link",
@@ -3938,20 +4288,20 @@ function AcceptInvitation({
3938
4288
  // Said before they press anything. The server refuses this, but
3939
4289
  // finding out after a click reads as a broken invitation rather than
3940
4290
  // as being signed in as the wrong person.
3941
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("p", { children: [
4291
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("p", { children: [
3942
4292
  "You are signed in as ",
3943
4293
  user?.user.email,
3944
4294
  ". This invitation was sent to ",
3945
4295
  preview?.email,
3946
4296
  " \u2014 sign in as that address to accept it."
3947
4297
  ] })
3948
- ) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: accept, children: busy ? "Joining\u2026" : `Join ${preview?.organizationName}` })
4298
+ ) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: accept, children: busy ? "Joining\u2026" : `Join ${preview?.organizationName}` })
3949
4299
  ] });
3950
4300
  }
3951
4301
 
3952
4302
  // src/PayInvoice.tsx
3953
- var import_react21 = require("react");
3954
- var import_jsx_runtime23 = require("react/jsx-runtime");
4303
+ var import_react22 = require("react");
4304
+ var import_jsx_runtime25 = require("react/jsx-runtime");
3955
4305
  var STRIPE_SRC = "https://js.stripe.com/v3/";
3956
4306
  function loadStripeScript() {
3957
4307
  if (typeof window === "undefined") {
@@ -3983,14 +4333,14 @@ function PayInvoice({
3983
4333
  style
3984
4334
  }) {
3985
4335
  const { client } = useBase316();
3986
- const mountRef = (0, import_react21.useRef)(null);
3987
- const stripeRef = (0, import_react21.useRef)(null);
3988
- const elementsRef = (0, import_react21.useRef)(null);
3989
- const [ready, setReady] = (0, import_react21.useState)(false);
3990
- const [paying, setPaying] = (0, import_react21.useState)(false);
3991
- const [done, setDone] = (0, import_react21.useState)(false);
3992
- const [error, setError] = (0, import_react21.useState)(null);
3993
- (0, import_react21.useEffect)(() => {
4336
+ const mountRef = (0, import_react22.useRef)(null);
4337
+ const stripeRef = (0, import_react22.useRef)(null);
4338
+ const elementsRef = (0, import_react22.useRef)(null);
4339
+ const [ready, setReady] = (0, import_react22.useState)(false);
4340
+ const [paying, setPaying] = (0, import_react22.useState)(false);
4341
+ const [done, setDone] = (0, import_react22.useState)(false);
4342
+ const [error, setError] = (0, import_react22.useState)(null);
4343
+ (0, import_react22.useEffect)(() => {
3994
4344
  let cancelled = false;
3995
4345
  async function start() {
3996
4346
  const base = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}`;
@@ -4043,17 +4393,17 @@ function PayInvoice({
4043
4393
  onPaid?.();
4044
4394
  };
4045
4395
  if (done) {
4046
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cls("b316-pay", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "b316-pay__done", children: "Paid \u2014 thank you." }) });
4396
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cls("b316-pay", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "b316-pay__done", children: "Paid \u2014 thank you." }) });
4047
4397
  }
4048
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("form", { className: cls("b316-pay", className), style, onSubmit: submit, children: [
4049
- error ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "b316-pay__error", role: "alert", children: error }) : null,
4050
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: mountRef, className: "b316-pay__element" }),
4051
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { className: "b316-pay__submit", type: "submit", disabled: !ready || paying, children: paying ? "Paying\u2026" : "Pay" })
4398
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("form", { className: cls("b316-pay", className), style, onSubmit: submit, children: [
4399
+ error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "b316-pay__error", role: "alert", children: error }) : null,
4400
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ref: mountRef, className: "b316-pay__element" }),
4401
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { className: "b316-pay__submit", type: "submit", disabled: !ready || paying, children: paying ? "Paying\u2026" : "Pay" })
4052
4402
  ] });
4053
4403
  }
4054
4404
 
4055
4405
  // src/usePaymentLink.ts
4056
- var import_react22 = require("react");
4406
+ var import_react23 = require("react");
4057
4407
  function usePaymentLink({
4058
4408
  token,
4059
4409
  environmentId,
@@ -4061,10 +4411,10 @@ function usePaymentLink({
4061
4411
  onPaid
4062
4412
  }) {
4063
4413
  const { client } = useBase316();
4064
- const [status2, setStatus] = (0, import_react22.useState)({ state: "loading" });
4065
- const onPaidRef = (0, import_react22.useRef)(onPaid);
4414
+ const [status2, setStatus] = (0, import_react23.useState)({ state: "loading" });
4415
+ const onPaidRef = (0, import_react23.useRef)(onPaid);
4066
4416
  onPaidRef.current = onPaid;
4067
- (0, import_react22.useEffect)(() => {
4417
+ (0, import_react23.useEffect)(() => {
4068
4418
  let stopped = false;
4069
4419
  let timer;
4070
4420
  const statusUrl = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}/status`;
@@ -4113,23 +4463,23 @@ function usePaymentLink({
4113
4463
  }
4114
4464
 
4115
4465
  // src/PricingTable.tsx
4116
- var import_react24 = require("react");
4466
+ var import_react25 = require("react");
4117
4467
 
4118
4468
  // src/usePlans.ts
4119
- var import_react23 = require("react");
4469
+ var import_react24 = require("react");
4120
4470
  var CHECKOUT_STATUSES = /* @__PURE__ */ new Set([402, 409]);
4121
4471
  function usePlans(options = {}) {
4122
4472
  const { client, token } = useBase316();
4123
- const [plans, setPlans] = (0, import_react23.useState)(null);
4124
- const [error, setError] = (0, import_react23.useState)(false);
4125
- const [busyPlanVersionId, setBusy] = (0, import_react23.useState)(null);
4126
- const [lastError, setLastError] = (0, import_react23.useState)(null);
4127
- const [ownPlanVersionId, setOwnPlanVersionId] = (0, import_react23.useState)(null);
4128
- const [managedBy, setManagedBy] = (0, import_react23.useState)(null);
4129
- const [reloadCount, setReloadCount] = (0, import_react23.useState)(0);
4473
+ const [plans, setPlans] = (0, import_react24.useState)(null);
4474
+ const [error, setError] = (0, import_react24.useState)(false);
4475
+ const [busyPlanVersionId, setBusy] = (0, import_react24.useState)(null);
4476
+ const [lastError, setLastError] = (0, import_react24.useState)(null);
4477
+ const [ownPlanVersionId, setOwnPlanVersionId] = (0, import_react24.useState)(null);
4478
+ const [managedBy, setManagedBy] = (0, import_react24.useState)(null);
4479
+ const [reloadCount, setReloadCount] = (0, import_react24.useState)(0);
4130
4480
  const supplied = options.currentPlanVersionId;
4131
4481
  const discover = supplied === void 0;
4132
- (0, import_react23.useEffect)(() => {
4482
+ (0, import_react24.useEffect)(() => {
4133
4483
  let cancelled = false;
4134
4484
  client.billing.plans().then((result) => {
4135
4485
  if (!cancelled) {
@@ -4145,7 +4495,7 @@ function usePlans(options = {}) {
4145
4495
  cancelled = true;
4146
4496
  };
4147
4497
  }, [client, reloadCount]);
4148
- (0, import_react23.useEffect)(() => {
4498
+ (0, import_react24.useEffect)(() => {
4149
4499
  if (!token) {
4150
4500
  return;
4151
4501
  }
@@ -4162,11 +4512,11 @@ function usePlans(options = {}) {
4162
4512
  cancelled = true;
4163
4513
  };
4164
4514
  }, [client, token, discover, reloadCount]);
4165
- const reload = (0, import_react23.useCallback)(() => {
4515
+ const reload = (0, import_react24.useCallback)(() => {
4166
4516
  setError(false);
4167
4517
  setReloadCount((count) => count + 1);
4168
4518
  }, []);
4169
- const selectPlan = (0, import_react23.useCallback)(
4519
+ const selectPlan = (0, import_react24.useCallback)(
4170
4520
  async (plan) => {
4171
4521
  setLastError(null);
4172
4522
  if (managedBy) {
@@ -4234,7 +4584,7 @@ function usePlans(options = {}) {
4234
4584
  }
4235
4585
 
4236
4586
  // src/PricingTable.tsx
4237
- var import_jsx_runtime24 = require("react/jsx-runtime");
4587
+ var import_jsx_runtime26 = require("react/jsx-runtime");
4238
4588
  function formatAmount(amount, currency) {
4239
4589
  if (amount === null) return "Free";
4240
4590
  const value = Number(amount);
@@ -4283,7 +4633,7 @@ function PricingTable({
4283
4633
  managedBy,
4284
4634
  selectPlan
4285
4635
  } = usePlans({ currentPlanVersionId });
4286
- const [scheduled, setScheduled] = (0, import_react24.useState)(null);
4636
+ const [scheduled, setScheduled] = (0, import_react25.useState)(null);
4287
4637
  async function choose(plan) {
4288
4638
  if (onSelectPlan) {
4289
4639
  await onSelectPlan(plan.planVersionId, plan);
@@ -4300,50 +4650,50 @@ function PricingTable({
4300
4650
  }
4301
4651
  }
4302
4652
  if (error) {
4303
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cls("b316-card", className), style, children: "Plans are unavailable right now." });
4653
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cls("b316-card", className), style, children: "Plans are unavailable right now." });
4304
4654
  }
4305
4655
  if (!plans) {
4306
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cls("b316-card", className), style, children: "Loading plans\u2026" });
4656
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cls("b316-card", className), style, children: "Loading plans\u2026" });
4307
4657
  }
4308
4658
  if (plans.length === 0) {
4309
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cls("b316-card", className), style, children: "No plans are published yet." });
4659
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cls("b316-card", className), style, children: "No plans are published yet." });
4310
4660
  }
4311
4661
  const anyTrial = plans.some((plan) => Boolean(plan.trialDays));
4312
4662
  const anyDescription = plans.some((plan) => Boolean(plan.description));
4313
4663
  const anyFeatured = plans.some((plan) => plan.key === featuredPlanKey);
4314
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cls("b316-plans", className), style, children: [
4664
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: cls("b316-plans", className), style, children: [
4315
4665
  managedBy ? (
4316
4666
  // A client company's plan comes from the firm that runs it. The table
4317
4667
  // still shows what is on offer, with the current plan marked, but
4318
4668
  // nothing here can be bought: it would grant this account nothing.
4319
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-plans-managed b316-muted", children: [
4669
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-plans-managed b316-muted", children: [
4320
4670
  "Your plan is provided by ",
4321
4671
  managedBy.name ?? "the organization that manages your account",
4322
4672
  ". Ask them to change it."
4323
4673
  ] })
4324
- ) : lastError ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plans-error", role: "alert", children: lastError }) : scheduled ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plans-managed b316-muted", role: "status", children: scheduled }) : null,
4674
+ ) : lastError ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plans-error", role: "alert", children: lastError }) : scheduled ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plans-managed b316-muted", role: "status", children: scheduled }) : null,
4325
4675
  plans.map((plan) => {
4326
4676
  const base = plan.prices.find((price) => price.featureId === null) ?? plan.prices[0];
4327
4677
  const isCurrent = current === plan.planVersionId;
4328
4678
  const featured = featuredPlanKey === plan.key;
4329
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
4679
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
4330
4680
  "div",
4331
4681
  {
4332
4682
  className: featured ? "b316-card b316-plan b316-plan-featured" : "b316-card b316-plan",
4333
4683
  children: [
4334
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-plan-head", children: [
4335
- anyFeatured ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: featured ? "b316-plan-badge" : "b316-plan-badge-spacer", children: featured ? "Recommended" : "\xA0" }) : null,
4336
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plan-name", children: plan.name }),
4337
- anyDescription ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plan-desc", children: plan.description ?? "\xA0" }) : null
4684
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-plan-head", children: [
4685
+ anyFeatured ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: featured ? "b316-plan-badge" : "b316-plan-badge-spacer", children: featured ? "Recommended" : "\xA0" }) : null,
4686
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-name", children: plan.name }),
4687
+ anyDescription ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-desc", children: plan.description ?? "\xA0" }) : null
4338
4688
  ] }),
4339
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-plan-pricing", children: [
4340
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plan-price", children: formatAmount(base?.amount ?? null, plan.currency) }),
4341
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plan-cadence", children: cadence(plan, base?.amount ?? null) }),
4342
- anyTrial ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plan-trial", children: describeTrial(plan, plans) ?? "\xA0" }) : null
4689
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-plan-pricing", children: [
4690
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-price", children: formatAmount(base?.amount ?? null, plan.currency) }),
4691
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-cadence", children: cadence(plan, base?.amount ?? null) }),
4692
+ anyTrial ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-trial", children: describeTrial(plan, plans) ?? "\xA0" }) : null
4343
4693
  ] }),
4344
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("ul", { className: "b316-plan-features", children: plan.entitlements.filter((entitlement) => entitlement.enabled).map((entitlement) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("li", { className: "b316-plan-feature", children: [
4345
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: entitlement.featureName }),
4346
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "b316-plan-feature-value", children: entitlement.limit === null ? "Unlimited" : (
4694
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("ul", { className: "b316-plan-features", children: plan.entitlements.filter((entitlement) => entitlement.enabled).map((entitlement) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("li", { className: "b316-plan-feature", children: [
4695
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: entitlement.featureName }),
4696
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "b316-plan-feature-value", children: entitlement.limit === null ? "Unlimited" : (
4347
4697
  // A usage price on the feature makes the limit an
4348
4698
  // allowance billed past, not a ceiling — the same
4349
4699
  // rule `check()` applies (any non-FLAT price).
@@ -4352,7 +4702,7 @@ function PricingTable({
4352
4702
  ) ? `${entitlement.limit} included` : entitlement.limit
4353
4703
  ) })
4354
4704
  ] }, entitlement.featureId)) }),
4355
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plan-action", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4705
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-plan-action", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4356
4706
  "button",
4357
4707
  {
4358
4708
  type: "button",
@@ -4373,12 +4723,12 @@ function PricingTable({
4373
4723
  }
4374
4724
 
4375
4725
  // src/DataTable.tsx
4376
- var import_sdk8 = require("@base316/sdk");
4377
- var import_react28 = require("react");
4726
+ var import_sdk9 = require("@base316/sdk");
4727
+ var import_react29 = require("react");
4378
4728
 
4379
4729
  // src/fields.tsx
4380
- var import_sdk6 = require("@base316/sdk");
4381
- var import_jsx_runtime25 = require("react/jsx-runtime");
4730
+ var import_sdk7 = require("@base316/sdk");
4731
+ var import_jsx_runtime27 = require("react/jsx-runtime");
4382
4732
  function formatNumber(value, fraction = 0) {
4383
4733
  const number = Number(value);
4384
4734
  return Number.isFinite(number) ? new Intl.NumberFormat(void 0, {
@@ -4400,10 +4750,10 @@ function formatDuration(value) {
4400
4750
  }
4401
4751
  function FieldCell({ value, field, related }) {
4402
4752
  if (field.type === "RELATION") {
4403
- return related?.title ?? (related?.id ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("code", { className: "b316-muted", children: related.id }) : "\u2014");
4753
+ return related?.title ?? (related?.id ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("code", { className: "b316-muted", children: related.id }) : "\u2014");
4404
4754
  }
4405
4755
  if (value === null || value === void 0 || value === "") {
4406
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "b316-muted", children: "\u2014" });
4756
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-muted", children: "\u2014" });
4407
4757
  }
4408
4758
  switch (field.type) {
4409
4759
  case "BOOLEAN":
@@ -4416,9 +4766,9 @@ function FieldCell({ value, field, related }) {
4416
4766
  return formatDuration(value);
4417
4767
  case "RATING": {
4418
4768
  const stars = Math.round(Number(value));
4419
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { "aria-label": `${stars} out of 5`, children: [
4769
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { "aria-label": `${stars} out of 5`, children: [
4420
4770
  "\u2605".repeat(stars),
4421
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "b316-muted", children: "\u2605".repeat(Math.max(0, 5 - stars)) })
4771
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-muted", children: "\u2605".repeat(Math.max(0, 5 - stars)) })
4422
4772
  ] });
4423
4773
  }
4424
4774
  case "DATE":
@@ -4426,17 +4776,17 @@ function FieldCell({ value, field, related }) {
4426
4776
  case "DATETIME":
4427
4777
  return new Date(String(value)).toLocaleString();
4428
4778
  case "SELECT":
4429
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "b316-chip", children: String(value) });
4779
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-chip", children: String(value) });
4430
4780
  case "MULTISELECT":
4431
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "b316-chips", children: (Array.isArray(value) ? value : [value]).map((item) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "b316-chip", children: String(item) }, String(item))) });
4781
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-chips", children: (Array.isArray(value) ? value : [value]).map((item) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-chip", children: String(item) }, String(item))) });
4432
4782
  case "URL":
4433
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("a", { href: String(value), target: "_blank", rel: "noreferrer noopener", children: String(value) });
4783
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("a", { href: String(value), target: "_blank", rel: "noreferrer noopener", children: String(value) });
4434
4784
  case "EMAIL":
4435
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("a", { href: `mailto:${String(value)}`, children: String(value) });
4785
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("a", { href: `mailto:${String(value)}`, children: String(value) });
4436
4786
  case "PHONE":
4437
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("a", { href: `tel:${String(value)}`, children: String(value) });
4787
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("a", { href: `tel:${String(value)}`, children: String(value) });
4438
4788
  case "ADDRESS":
4439
- return (0, import_sdk6.formatAddress)(value);
4789
+ return (0, import_sdk7.formatAddress)(value);
4440
4790
  case "ATTACHMENT": {
4441
4791
  const files = Array.isArray(value) ? value : [value];
4442
4792
  return `${files.length} file${files.length === 1 ? "" : "s"}`;
@@ -4446,13 +4796,13 @@ function FieldCell({ value, field, related }) {
4446
4796
  return text.length > 80 ? `${text.slice(0, 80)}\u2026` : text;
4447
4797
  }
4448
4798
  case "JSON":
4449
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("code", { className: "b316-muted", children: JSON.stringify(value).slice(0, 60) });
4799
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("code", { className: "b316-muted", children: JSON.stringify(value).slice(0, 60) });
4450
4800
  default:
4451
4801
  return String(value);
4452
4802
  }
4453
4803
  }
4454
4804
  function FieldInput({ value, field, onChange, error, disabled }) {
4455
- if ((0, import_sdk6.specFor)(field).computed) {
4805
+ if ((0, import_sdk7.specFor)(field).computed) {
4456
4806
  return null;
4457
4807
  }
4458
4808
  const id = `b316-field-${field.key}`;
@@ -4467,7 +4817,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4467
4817
  function control() {
4468
4818
  switch (field.type) {
4469
4819
  case "LONGTEXT":
4470
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4820
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4471
4821
  "textarea",
4472
4822
  {
4473
4823
  ...common,
@@ -4477,7 +4827,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4477
4827
  }
4478
4828
  );
4479
4829
  case "BOOLEAN":
4480
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4830
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4481
4831
  "input",
4482
4832
  {
4483
4833
  ...common,
@@ -4488,22 +4838,22 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4488
4838
  }
4489
4839
  );
4490
4840
  case "SELECT":
4491
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
4841
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
4492
4842
  "select",
4493
4843
  {
4494
4844
  ...common,
4495
4845
  value: value === null || value === void 0 ? "" : String(value),
4496
4846
  onChange: (event) => onChange(event.target.value === "" ? null : event.target.value),
4497
4847
  children: [
4498
- field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: "", children: "\u2014" }),
4499
- (field.options ?? []).map((option) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: option, children: option }, option))
4848
+ field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: "", children: "\u2014" }),
4849
+ (field.options ?? []).map((option) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("option", { value: option, children: option }, option))
4500
4850
  ]
4501
4851
  }
4502
4852
  );
4503
4853
  case "MULTISELECT": {
4504
4854
  const selected = new Set(Array.isArray(value) ? value.map(String) : []);
4505
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "b316-choices", children: (field.options ?? []).map((option) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "b316-choice", children: [
4506
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4855
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-choices", children: (field.options ?? []).map((option) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "b316-choice", children: [
4856
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4507
4857
  "input",
4508
4858
  {
4509
4859
  type: "checkbox",
@@ -4526,7 +4876,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4526
4876
  case "NUMBER":
4527
4877
  case "MONEY":
4528
4878
  case "PERCENT":
4529
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4879
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4530
4880
  "input",
4531
4881
  {
4532
4882
  ...common,
@@ -4537,7 +4887,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4537
4887
  }
4538
4888
  );
4539
4889
  case "RATING":
4540
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4890
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4541
4891
  "input",
4542
4892
  {
4543
4893
  ...common,
@@ -4551,8 +4901,8 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4551
4901
  );
4552
4902
  case "DURATION": {
4553
4903
  const minutes = value === null || value === void 0 ? "" : String(Number(value) / 60);
4554
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "b316-suffixed", children: [
4555
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4904
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-suffixed", children: [
4905
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4556
4906
  "input",
4557
4907
  {
4558
4908
  ...common,
@@ -4562,11 +4912,11 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4562
4912
  onChange: (event) => onChange(event.target.value === "" ? null : Number(event.target.value) * 60)
4563
4913
  }
4564
4914
  ),
4565
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "b316-muted", children: "minutes" })
4915
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "b316-muted", children: "minutes" })
4566
4916
  ] });
4567
4917
  }
4568
4918
  case "DATE":
4569
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4919
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4570
4920
  "input",
4571
4921
  {
4572
4922
  ...common,
@@ -4576,7 +4926,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4576
4926
  }
4577
4927
  );
4578
4928
  case "DATETIME":
4579
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4929
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4580
4930
  "input",
4581
4931
  {
4582
4932
  ...common,
@@ -4589,7 +4939,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4589
4939
  );
4590
4940
  case "ADDRESS": {
4591
4941
  const address = value ?? {};
4592
- const part = (key, label) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4942
+ const part = (key, label) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4593
4943
  "input",
4594
4944
  {
4595
4945
  className: "b316-input",
@@ -4601,7 +4951,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4601
4951
  },
4602
4952
  key
4603
4953
  );
4604
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "b316-address", children: [
4954
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-address", children: [
4605
4955
  part("line1", "Address line 1"),
4606
4956
  part("line2", "Address line 2"),
4607
4957
  part("city", "City"),
@@ -4611,7 +4961,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4611
4961
  ] });
4612
4962
  }
4613
4963
  case "EMAIL":
4614
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4964
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4615
4965
  "input",
4616
4966
  {
4617
4967
  ...common,
@@ -4621,7 +4971,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4621
4971
  }
4622
4972
  );
4623
4973
  case "URL":
4624
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4974
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4625
4975
  "input",
4626
4976
  {
4627
4977
  ...common,
@@ -4631,7 +4981,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4631
4981
  }
4632
4982
  );
4633
4983
  case "PHONE":
4634
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4984
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4635
4985
  "input",
4636
4986
  {
4637
4987
  ...common,
@@ -4641,7 +4991,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4641
4991
  }
4642
4992
  );
4643
4993
  default:
4644
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4994
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4645
4995
  "input",
4646
4996
  {
4647
4997
  ...common,
@@ -4652,24 +5002,24 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4652
5002
  );
4653
5003
  }
4654
5004
  }
4655
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "b316-field", children: [
4656
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "b316-label", htmlFor: id, children: [
5005
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-field", children: [
5006
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("label", { className: "b316-label", htmlFor: id, children: [
4657
5007
  field.label,
4658
- field.required ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
5008
+ field.required ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
4659
5009
  ] }),
4660
5010
  control(),
4661
- field.description ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "b316-hint", children: field.description }) : null,
4662
- error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "b316-error", id: described, role: "alert", children: error }) : null
5011
+ field.description ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-hint", children: field.description }) : null,
5012
+ error ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-error", id: described, role: "alert", children: error }) : null
4663
5013
  ] });
4664
5014
  }
4665
5015
 
4666
5016
  // src/RecordForm.tsx
4667
- var import_sdk7 = require("@base316/sdk");
4668
- var import_react27 = require("react");
5017
+ var import_sdk8 = require("@base316/sdk");
5018
+ var import_react28 = require("react");
4669
5019
 
4670
5020
  // src/RelationPicker.tsx
4671
- var import_react25 = require("react");
4672
- var import_jsx_runtime26 = require("react/jsx-runtime");
5021
+ var import_react26 = require("react");
5022
+ var import_jsx_runtime28 = require("react/jsx-runtime");
4673
5023
  function RelationPicker({
4674
5024
  field,
4675
5025
  value,
@@ -4679,13 +5029,13 @@ function RelationPicker({
4679
5029
  tenant
4680
5030
  }) {
4681
5031
  const { client, token } = useBase316();
4682
- const [query, setQuery] = (0, import_react25.useState)("");
4683
- const [results, setResults] = (0, import_react25.useState)([]);
4684
- const [chosenTitle, setChosenTitle] = (0, import_react25.useState)(null);
4685
- const [open, setOpen] = (0, import_react25.useState)(false);
5032
+ const [query, setQuery] = (0, import_react26.useState)("");
5033
+ const [results, setResults] = (0, import_react26.useState)([]);
5034
+ const [chosenTitle, setChosenTitle] = (0, import_react26.useState)(null);
5035
+ const [open, setOpen] = (0, import_react26.useState)(false);
4686
5036
  const id = `b316-field-${field.key}`;
4687
- const box = (0, import_react25.useRef)(null);
4688
- (0, import_react25.useEffect)(() => {
5037
+ const box = (0, import_react26.useRef)(null);
5038
+ (0, import_react26.useEffect)(() => {
4689
5039
  if (!token || !value || !field.relationTo) {
4690
5040
  setChosenTitle(null);
4691
5041
  return;
@@ -4700,7 +5050,7 @@ function RelationPicker({
4700
5050
  cancelled = true;
4701
5051
  };
4702
5052
  }, [client, token, value, field.relationTo, tenant]);
4703
- (0, import_react25.useEffect)(() => {
5053
+ (0, import_react26.useEffect)(() => {
4704
5054
  if (!token || !field.relationTo || !open) {
4705
5055
  return;
4706
5056
  }
@@ -4726,7 +5076,7 @@ function RelationPicker({
4726
5076
  clearTimeout(timer);
4727
5077
  };
4728
5078
  }, [client, token, field.relationTo, query, open, tenant]);
4729
- (0, import_react25.useEffect)(() => {
5079
+ (0, import_react26.useEffect)(() => {
4730
5080
  if (!open || typeof document === "undefined") {
4731
5081
  return;
4732
5082
  }
@@ -4740,14 +5090,14 @@ function RelationPicker({
4740
5090
  document.removeEventListener("mousedown", onDocumentClick);
4741
5091
  };
4742
5092
  }, [open]);
4743
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-field", ref: box, children: [
4744
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "b316-label", htmlFor: id, children: [
5093
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-field", ref: box, children: [
5094
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "b316-label", htmlFor: id, children: [
4745
5095
  field.label,
4746
- field.required ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
5096
+ field.required ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
4747
5097
  ] }),
4748
- value && !open ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-relation-chosen", children: [
4749
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: chosenTitle ?? value }),
4750
- disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5098
+ value && !open ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-relation-chosen", children: [
5099
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { children: chosenTitle ?? value }),
5100
+ disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4751
5101
  "button",
4752
5102
  {
4753
5103
  type: "button",
@@ -4759,7 +5109,7 @@ function RelationPicker({
4759
5109
  children: "Change"
4760
5110
  }
4761
5111
  ),
4762
- disabled || field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5112
+ disabled || field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4763
5113
  "button",
4764
5114
  {
4765
5115
  type: "button",
@@ -4769,8 +5119,8 @@ function RelationPicker({
4769
5119
  children: "Clear"
4770
5120
  }
4771
5121
  )
4772
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
4773
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5122
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
5123
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4774
5124
  "input",
4775
5125
  {
4776
5126
  id,
@@ -4791,7 +5141,7 @@ function RelationPicker({
4791
5141
  }
4792
5142
  }
4793
5143
  ),
4794
- open ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("ul", { className: "b316-relation-results", id: `${id}-results`, role: "listbox", children: results.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("li", { className: "b316-muted b316-relation-empty", children: "No matches" }) : results.map((result) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5144
+ open ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("ul", { className: "b316-relation-results", id: `${id}-results`, role: "listbox", children: results.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("li", { className: "b316-muted b316-relation-empty", children: "No matches" }) : results.map((result) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4795
5145
  "button",
4796
5146
  {
4797
5147
  type: "button",
@@ -4807,13 +5157,13 @@ function RelationPicker({
4807
5157
  }
4808
5158
  ) }, result.id)) }) : null
4809
5159
  ] }),
4810
- field.description ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-hint", children: field.description }) : null,
4811
- error ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null
5160
+ field.description ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-hint", children: field.description }) : null,
5161
+ error ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null
4812
5162
  ] });
4813
5163
  }
4814
5164
 
4815
5165
  // src/useCollection.ts
4816
- var import_react26 = require("react");
5166
+ var import_react27 = require("react");
4817
5167
  function fieldErrorFrom(cause) {
4818
5168
  const param = cause?.param;
4819
5169
  const message = cause instanceof Error ? cause.message : "That value was not accepted.";
@@ -4821,24 +5171,24 @@ function fieldErrorFrom(cause) {
4821
5171
  }
4822
5172
  function useCollection(collection, options = {}) {
4823
5173
  const { client, token } = useBase316();
4824
- const [schema, setSchema] = (0, import_react26.useState)(null);
4825
- const [records, setRecords] = (0, import_react26.useState)([]);
4826
- const [error, setError] = (0, import_react26.useState)(null);
4827
- const [loading, setLoading] = (0, import_react26.useState)(true);
4828
- const [total, setTotal] = (0, import_react26.useState)(0);
4829
- const [cursor, setCursor] = (0, import_react26.useState)(null);
4830
- const [reloadCount, setReloadCount] = (0, import_react26.useState)(0);
4831
- const [search, setSearch] = (0, import_react26.useState)("");
4832
- const [filters, setFilters] = (0, import_react26.useState)([]);
4833
- const [sort, setSort] = (0, import_react26.useState)(
5174
+ const [schema, setSchema] = (0, import_react27.useState)(null);
5175
+ const [records, setRecords] = (0, import_react27.useState)([]);
5176
+ const [error, setError] = (0, import_react27.useState)(null);
5177
+ const [loading, setLoading] = (0, import_react27.useState)(true);
5178
+ const [total, setTotal] = (0, import_react27.useState)(0);
5179
+ const [cursor, setCursor] = (0, import_react27.useState)(null);
5180
+ const [reloadCount, setReloadCount] = (0, import_react27.useState)(0);
5181
+ const [search, setSearch] = (0, import_react27.useState)("");
5182
+ const [filters, setFilters] = (0, import_react27.useState)([]);
5183
+ const [sort, setSort] = (0, import_react27.useState)(
4834
5184
  options.sort ?? null
4835
5185
  );
4836
- const [fieldErrors, setFieldErrors] = (0, import_react26.useState)({});
4837
- const [saving, setSaving] = (0, import_react26.useState)(false);
5186
+ const [fieldErrors, setFieldErrors] = (0, import_react27.useState)({});
5187
+ const [saving, setSaving] = (0, import_react27.useState)(false);
4838
5188
  const { tenant, limit, recordId } = options;
4839
5189
  const fixedFilters = JSON.stringify(options.filters ?? []);
4840
- const scope = (0, import_react26.useMemo)(() => tenant ? { tenant } : void 0, [tenant]);
4841
- (0, import_react26.useEffect)(() => {
5190
+ const scope = (0, import_react27.useMemo)(() => tenant ? { tenant } : void 0, [tenant]);
5191
+ (0, import_react27.useEffect)(() => {
4842
5192
  if (!token) {
4843
5193
  return;
4844
5194
  }
@@ -4857,7 +5207,7 @@ function useCollection(collection, options = {}) {
4857
5207
  cancelled = true;
4858
5208
  };
4859
5209
  }, [client, token, collection, scope]);
4860
- (0, import_react26.useEffect)(() => {
5210
+ (0, import_react27.useEffect)(() => {
4861
5211
  if (!token || !schema) {
4862
5212
  return;
4863
5213
  }
@@ -4927,10 +5277,10 @@ function useCollection(collection, options = {}) {
4927
5277
  scope,
4928
5278
  reloadCount
4929
5279
  ]);
4930
- const reload = (0, import_react26.useCallback)(() => {
5280
+ const reload = (0, import_react27.useCallback)(() => {
4931
5281
  setReloadCount((count) => count + 1);
4932
5282
  }, []);
4933
- const loadMore = (0, import_react26.useCallback)(() => {
5283
+ const loadMore = (0, import_react27.useCallback)(() => {
4934
5284
  if (!token || !cursor) {
4935
5285
  return;
4936
5286
  }
@@ -4954,7 +5304,7 @@ function useCollection(collection, options = {}) {
4954
5304
  setLoading(false);
4955
5305
  });
4956
5306
  }, [client, token, collection, cursor, fixedFilters, filters, search, sort, limit, scope]);
4957
- const toggleSort = (0, import_react26.useCallback)((field) => {
5307
+ const toggleSort = (0, import_react27.useCallback)((field) => {
4958
5308
  setSort((current) => {
4959
5309
  if (current?.field !== field) {
4960
5310
  return { field, direction: "asc" };
@@ -4962,7 +5312,7 @@ function useCollection(collection, options = {}) {
4962
5312
  return current.direction === "asc" ? { field, direction: "desc" } : null;
4963
5313
  });
4964
5314
  }, []);
4965
- const create = (0, import_react26.useCallback)(
5315
+ const create = (0, import_react27.useCallback)(
4966
5316
  async (fields) => {
4967
5317
  if (!token) {
4968
5318
  return null;
@@ -4982,7 +5332,7 @@ function useCollection(collection, options = {}) {
4982
5332
  },
4983
5333
  [client, token, collection, scope, reload]
4984
5334
  );
4985
- const update = (0, import_react26.useCallback)(
5335
+ const update = (0, import_react27.useCallback)(
4986
5336
  async (id, fields) => {
4987
5337
  if (!token) {
4988
5338
  return null;
@@ -5004,7 +5354,7 @@ function useCollection(collection, options = {}) {
5004
5354
  },
5005
5355
  [client, token, collection, scope]
5006
5356
  );
5007
- const remove = (0, import_react26.useCallback)(
5357
+ const remove = (0, import_react27.useCallback)(
5008
5358
  async (id) => {
5009
5359
  if (!token) {
5010
5360
  return false;
@@ -5049,7 +5399,7 @@ function useCollection(collection, options = {}) {
5049
5399
  }
5050
5400
 
5051
5401
  // src/RecordForm.tsx
5052
- var import_jsx_runtime27 = require("react/jsx-runtime");
5402
+ var import_jsx_runtime29 = require("react/jsx-runtime");
5053
5403
  function RecordForm({
5054
5404
  collection,
5055
5405
  recordId,
@@ -5070,22 +5420,22 @@ function RecordForm({
5070
5420
  recordId
5071
5421
  }
5072
5422
  );
5073
- const [values, setValues] = (0, import_react27.useState)(defaults ?? {});
5074
- const [loaded, setLoaded] = (0, import_react27.useState)(!recordId);
5423
+ const [values, setValues] = (0, import_react28.useState)(defaults ?? {});
5424
+ const [loaded, setLoaded] = (0, import_react28.useState)(!recordId);
5075
5425
  const existing = recordId ? records.find((record) => record.id === recordId) : void 0;
5076
- (0, import_react27.useEffect)(() => {
5426
+ (0, import_react28.useEffect)(() => {
5077
5427
  if (existing && !loaded) {
5078
5428
  setValues(existing.fields);
5079
5429
  setLoaded(true);
5080
5430
  }
5081
5431
  }, [existing, loaded]);
5082
5432
  if (error) {
5083
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5433
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5084
5434
  }
5085
5435
  if (!schema || !loaded) {
5086
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5436
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5087
5437
  }
5088
- const editable = schema.fields.filter((field) => !(0, import_sdk7.specFor)(field).computed);
5438
+ const editable = schema.fields.filter((field) => !(0, import_sdk8.specFor)(field).computed);
5089
5439
  async function submit(event) {
5090
5440
  event.preventDefault();
5091
5441
  const saved = recordId ? await update(recordId, values) : await create(values);
@@ -5093,11 +5443,11 @@ function RecordForm({
5093
5443
  onSaved?.(saved.id);
5094
5444
  }
5095
5445
  }
5096
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
5097
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h3", { className: "b316-form-title", children: recordId ? `Edit ${schema.name.toLowerCase()}` : `New ${schema.name.toLowerCase()}` }),
5098
- fieldErrors._ ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-error", role: "alert", children: fieldErrors._ }) : null,
5446
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
5447
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("h3", { className: "b316-form-title", children: recordId ? `Edit ${schema.name.toLowerCase()}` : `New ${schema.name.toLowerCase()}` }),
5448
+ fieldErrors._ ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-error", role: "alert", children: fieldErrors._ }) : null,
5099
5449
  editable.map(
5100
- (field) => field.type === "RELATION" ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5450
+ (field) => field.type === "RELATION" ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5101
5451
  RelationPicker,
5102
5452
  {
5103
5453
  field,
@@ -5108,7 +5458,7 @@ function RecordForm({
5108
5458
  onChange: (next) => setValues((current) => ({ ...current, [field.key]: next }))
5109
5459
  },
5110
5460
  field.key
5111
- ) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5461
+ ) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5112
5462
  FieldInput,
5113
5463
  {
5114
5464
  field,
@@ -5120,15 +5470,15 @@ function RecordForm({
5120
5470
  field.key
5121
5471
  )
5122
5472
  ),
5123
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-form-actions", children: [
5124
- onCancel ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: onCancel, disabled: saving, children: "Cancel" }) : null,
5125
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "submit", className: "b316-button", disabled: saving, children: saving ? "Saving\u2026" : "Save" })
5473
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "b316-form-actions", children: [
5474
+ onCancel ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: onCancel, disabled: saving, children: "Cancel" }) : null,
5475
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("button", { type: "submit", className: "b316-button", disabled: saving, children: saving ? "Saving\u2026" : "Save" })
5126
5476
  ] })
5127
5477
  ] });
5128
5478
  }
5129
5479
 
5130
5480
  // src/DataTable.tsx
5131
- var import_jsx_runtime28 = require("react/jsx-runtime");
5481
+ var import_jsx_runtime30 = require("react/jsx-runtime");
5132
5482
  function DataTable({
5133
5483
  collection,
5134
5484
  columns,
@@ -5157,25 +5507,25 @@ function DataTable({
5157
5507
  loadMore,
5158
5508
  remove
5159
5509
  } = useCollection(collection, options);
5160
- const [editing, setEditing] = (0, import_react28.useState)(null);
5161
- const [removeFailed, setRemoveFailed] = (0, import_react28.useState)(null);
5510
+ const [editing, setEditing] = (0, import_react29.useState)(null);
5511
+ const [removeFailed, setRemoveFailed] = (0, import_react29.useState)(null);
5162
5512
  if (error) {
5163
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5513
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5164
5514
  }
5165
5515
  if (!schema) {
5166
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5516
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5167
5517
  }
5168
5518
  const shown = columns ? (
5169
5519
  // Ordered by what was asked for, not by the schema: a caller naming
5170
5520
  // columns means that order.
5171
5521
  columns.map((key) => schema.fields.find((field) => field.key === key)).filter((field) => Boolean(field))
5172
5522
  ) : schema.fields;
5173
- const searchable = schema.fields.some((field) => (0, import_sdk8.specFor)(field).capabilities.searchable);
5523
+ const searchable = schema.fields.some((field) => (0, import_sdk9.specFor)(field).capabilities.searchable);
5174
5524
  const writable = canWrite && !readOnly;
5175
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cls("b316-table-wrap", className), style, children: [
5176
- removeFailed ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-error", role: "alert", children: removeFailed }) : null,
5177
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-table-bar", children: [
5178
- searchable && !hideSearch ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5525
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: cls("b316-table-wrap", className), style, children: [
5526
+ removeFailed ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-error", role: "alert", children: removeFailed }) : null,
5527
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "b316-table-bar", children: [
5528
+ searchable && !hideSearch ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5179
5529
  "input",
5180
5530
  {
5181
5531
  type: "search",
@@ -5185,25 +5535,25 @@ function DataTable({
5185
5535
  value: search,
5186
5536
  onChange: (event) => setSearch(event.target.value)
5187
5537
  }
5188
- ) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", {}),
5189
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-table-actions", children: [
5190
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "b316-muted", children: [
5538
+ ) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", {}),
5539
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "b316-table-actions", children: [
5540
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "b316-muted", children: [
5191
5541
  total,
5192
5542
  " ",
5193
5543
  total === 1 ? schema.name.toLowerCase() : schema.namePlural.toLowerCase()
5194
5544
  ] }),
5195
- writable ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("button", { type: "button", className: "b316-button", onClick: () => setEditing("new"), children: [
5545
+ writable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("button", { type: "button", className: "b316-button", onClick: () => setEditing("new"), children: [
5196
5546
  "New ",
5197
5547
  schema.name.toLowerCase()
5198
5548
  ] }) : null
5199
5549
  ] })
5200
5550
  ] }),
5201
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-table-scroll", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("table", { className: "b316-table", children: [
5202
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("tr", { children: [
5551
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-table-scroll", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("table", { className: "b316-table", children: [
5552
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("tr", { children: [
5203
5553
  shown.map((field) => {
5204
- const sortable = (0, import_sdk8.specFor)(field).capabilities.sortable;
5554
+ const sortable = (0, import_sdk9.specFor)(field).capabilities.sortable;
5205
5555
  const active = sort?.field === field.key;
5206
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("th", { scope: "col", "aria-sort": ariaSort(active, sort?.direction), children: sortable ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5556
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("th", { scope: "col", "aria-sort": ariaSort(active, sort?.direction), children: sortable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
5207
5557
  "button",
5208
5558
  {
5209
5559
  type: "button",
@@ -5211,20 +5561,20 @@ function DataTable({
5211
5561
  onClick: () => toggleSort(field.key),
5212
5562
  children: [
5213
5563
  field.label,
5214
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { "aria-hidden": "true", children: active ? sort?.direction === "desc" ? " \u2193" : " \u2191" : " \u2195" })
5564
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { "aria-hidden": "true", children: active ? sort?.direction === "desc" ? " \u2193" : " \u2191" : " \u2195" })
5215
5565
  ]
5216
5566
  }
5217
5567
  ) : field.label }, field.key);
5218
5568
  }),
5219
- writable ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("th", { scope: "col", className: "b316-table-rowactions" }) : null
5569
+ writable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("th", { scope: "col", className: "b316-table-rowactions" }) : null
5220
5570
  ] }) }),
5221
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("tbody", { children: records.map((record) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5571
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("tbody", { children: records.map((record) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
5222
5572
  "tr",
5223
5573
  {
5224
5574
  className: onSelect ? "b316-row-clickable" : void 0,
5225
5575
  onClick: onSelect ? () => onSelect(record) : void 0,
5226
5576
  children: [
5227
- shown.map((field) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("td", { children: renderCell?.(record, field) ?? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5577
+ shown.map((field) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("td", { children: renderCell?.(record, field) ?? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5228
5578
  FieldCell,
5229
5579
  {
5230
5580
  value: record.fields[field.key] ?? null,
@@ -5232,8 +5582,8 @@ function DataTable({
5232
5582
  related: record.related[field.key]
5233
5583
  }
5234
5584
  ) }, field.key)),
5235
- writable ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("td", { className: "b316-table-rowactions", children: [
5236
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5585
+ writable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("td", { className: "b316-table-rowactions", children: [
5586
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5237
5587
  "button",
5238
5588
  {
5239
5589
  type: "button",
@@ -5245,7 +5595,7 @@ function DataTable({
5245
5595
  children: "Edit"
5246
5596
  }
5247
5597
  ),
5248
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5598
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5249
5599
  ConfirmButton,
5250
5600
  {
5251
5601
  className: "b316-button-quiet b316-danger",
@@ -5269,10 +5619,10 @@ function DataTable({
5269
5619
  record.id
5270
5620
  )) })
5271
5621
  ] }) }),
5272
- records.length === 0 && !loading ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-empty", children: emptyState ?? `No ${schema.namePlural.toLowerCase()} yet.` }) : null,
5273
- loading ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-empty", children: "Loading\u2026" }) : null,
5274
- hasMore ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-table-more", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: "Load more" }) }) : null,
5275
- editing ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5622
+ records.length === 0 && !loading ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-empty", children: emptyState ?? `No ${schema.namePlural.toLowerCase()} yet.` }) : null,
5623
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-empty", children: "Loading\u2026" }) : null,
5624
+ hasMore ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-table-more", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: "Load more" }) }) : null,
5625
+ editing ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5276
5626
  RecordForm,
5277
5627
  {
5278
5628
  collection,
@@ -5295,9 +5645,9 @@ function ariaSort(active, direction) {
5295
5645
  }
5296
5646
 
5297
5647
  // src/Kanban.tsx
5298
- var import_sdk9 = require("@base316/sdk");
5299
- var import_react29 = require("react");
5300
- var import_jsx_runtime29 = require("react/jsx-runtime");
5648
+ var import_sdk10 = require("@base316/sdk");
5649
+ var import_react30 = require("react");
5650
+ var import_jsx_runtime31 = require("react/jsx-runtime");
5301
5651
  function Kanban({
5302
5652
  collection,
5303
5653
  groupBy,
@@ -5314,17 +5664,17 @@ function Kanban({
5314
5664
  limit: options.limit ?? 100,
5315
5665
  ...options
5316
5666
  });
5317
- const [dragging, setDragging] = (0, import_react29.useState)(null);
5318
- const [over, setOver] = (0, import_react29.useState)(null);
5667
+ const [dragging, setDragging] = (0, import_react30.useState)(null);
5668
+ const [over, setOver] = (0, import_react30.useState)(null);
5319
5669
  if (error) {
5320
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5670
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5321
5671
  }
5322
5672
  if (!schema) {
5323
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5673
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5324
5674
  }
5325
- const field = groupBy ? schema.fields.find((candidate) => candidate.key === groupBy) ?? null : (0, import_sdk9.defaultGroupFieldOf)(schema.fields);
5326
- if (!field || !(0, import_sdk9.specFor)(field).capabilities.groupable) {
5327
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: groupBy ? `"${groupBy}" cannot make columns. A board groups by a choice, a yes/no or a date.` : `${schema.namePlural} have no field to group by. Add a choice field \u2014 a status or a stage \u2014 and this board will use it.` });
5675
+ const field = groupBy ? schema.fields.find((candidate) => candidate.key === groupBy) ?? null : (0, import_sdk10.defaultGroupFieldOf)(schema.fields);
5676
+ if (!field || !(0, import_sdk10.specFor)(field).capabilities.groupable) {
5677
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: groupBy ? `"${groupBy}" cannot make columns. A board groups by a choice, a yes/no or a date.` : `${schema.namePlural} have no field to group by. Add a choice field \u2014 a status or a stage \u2014 and this board will use it.` });
5328
5678
  }
5329
5679
  const columns = columnsFor(field);
5330
5680
  const shown = cardFields ? cardFields.map((key) => schema.fields.find((candidate) => candidate.key === key)).filter((candidate) => Boolean(candidate)) : (
@@ -5332,7 +5682,7 @@ function Kanban({
5332
5682
  // The grouping field is already the column heading and the title is
5333
5683
  // already the card heading, so both would be printed twice on every card.
5334
5684
  schema.fields.filter(
5335
- (candidate) => candidate.key !== field.key && candidate.key !== (0, import_sdk9.titleFieldOf)(schema.fields)?.key
5685
+ (candidate) => candidate.key !== field.key && candidate.key !== (0, import_sdk10.titleFieldOf)(schema.fields)?.key
5336
5686
  ).slice(0, 3)
5337
5687
  );
5338
5688
  async function move(record, value) {
@@ -5341,12 +5691,12 @@ function Kanban({
5341
5691
  }
5342
5692
  await update(record.id, { [field.key]: value });
5343
5693
  }
5344
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: cls("b316-board-wrap", className), style, children: [
5345
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-board", role: "list", children: columns.map((column) => {
5694
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cls("b316-board-wrap", className), style, children: [
5695
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-board", role: "list", children: columns.map((column) => {
5346
5696
  const inColumn = records.filter(
5347
5697
  (record) => String(record.fields[field.key] ?? "") === String(column.value ?? "")
5348
5698
  );
5349
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
5699
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
5350
5700
  "section",
5351
5701
  {
5352
5702
  className: over === String(column.value) ? "b316-board-column b316-board-over" : "b316-board-column",
@@ -5370,12 +5720,12 @@ function Kanban({
5370
5720
  setDragging(null);
5371
5721
  },
5372
5722
  children: [
5373
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("header", { className: "b316-board-head", children: [
5374
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "b316-board-title", children: column.label }),
5375
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "b316-muted", children: inColumn.length })
5723
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("header", { className: "b316-board-head", children: [
5724
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "b316-board-title", children: column.label }),
5725
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "b316-muted", children: inColumn.length })
5376
5726
  ] }),
5377
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "b316-board-cards", children: [
5378
- inColumn.map((record) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
5727
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-board-cards", children: [
5728
+ inColumn.map((record) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
5379
5729
  "article",
5380
5730
  {
5381
5731
  className: "b316-board-card",
@@ -5387,10 +5737,10 @@ function Kanban({
5387
5737
  },
5388
5738
  onClick: onSelect ? () => onSelect(record) : void 0,
5389
5739
  children: [
5390
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-board-card-title", children: record.title ?? "Untitled" }),
5391
- shown.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "b316-board-card-field", children: [
5392
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "b316-muted", children: candidate.label }),
5393
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5740
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-board-card-title", children: record.title ?? "Untitled" }),
5741
+ shown.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-board-card-field", children: [
5742
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "b316-muted", children: candidate.label }),
5743
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5394
5744
  FieldCell,
5395
5745
  {
5396
5746
  value: record.fields[candidate.key] ?? null,
@@ -5403,9 +5753,9 @@ function Kanban({
5403
5753
  // Dragging is not reachable by keyboard and is awkward on a
5404
5754
  // phone. This is the same action by other means, not a
5405
5755
  // lesser fallback.
5406
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "b316-board-move", children: [
5407
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "b316-muted", children: "Move to" }),
5408
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5756
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("label", { className: "b316-board-move", children: [
5757
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "b316-muted", children: "Move to" }),
5758
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5409
5759
  "select",
5410
5760
  {
5411
5761
  className: "b316-input",
@@ -5417,7 +5767,7 @@ function Kanban({
5417
5767
  );
5418
5768
  void move(record, chosen?.value ?? null);
5419
5769
  },
5420
- children: columns.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("option", { value: String(candidate.value), children: candidate.label }, String(candidate.value)))
5770
+ children: columns.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("option", { value: String(candidate.value), children: candidate.label }, String(candidate.value)))
5421
5771
  }
5422
5772
  )
5423
5773
  ] })
@@ -5426,14 +5776,14 @@ function Kanban({
5426
5776
  },
5427
5777
  record.id
5428
5778
  )),
5429
- inColumn.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-board-empty", children: emptyState ?? "Nothing here" }) : null
5779
+ inColumn.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-board-empty", children: emptyState ?? "Nothing here" }) : null
5430
5780
  ] })
5431
5781
  ]
5432
5782
  },
5433
5783
  String(column.value)
5434
5784
  );
5435
5785
  }) }),
5436
- hasMore ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-table-more", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: [
5786
+ hasMore ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-table-more", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: [
5437
5787
  "Showing ",
5438
5788
  records.length,
5439
5789
  " of ",
@@ -5454,9 +5804,9 @@ function columnsFor(field) {
5454
5804
  }
5455
5805
 
5456
5806
  // src/Chart.tsx
5457
- var import_sdk10 = require("@base316/sdk");
5458
- var import_react30 = require("react");
5459
- var import_jsx_runtime30 = require("react/jsx-runtime");
5807
+ var import_sdk11 = require("@base316/sdk");
5808
+ var import_react31 = require("react");
5809
+ var import_jsx_runtime32 = require("react/jsx-runtime");
5460
5810
  function Chart({
5461
5811
  collection,
5462
5812
  x,
@@ -5475,43 +5825,43 @@ function Chart({
5475
5825
  limit: options.limit ?? 200,
5476
5826
  ...options
5477
5827
  });
5478
- const axis = (0, import_react30.useMemo)(() => {
5828
+ const axis = (0, import_react31.useMemo)(() => {
5479
5829
  if (!schema) {
5480
5830
  return null;
5481
5831
  }
5482
- const timeFields = (0, import_sdk10.fieldsFor)(schema.fields, "timeAxis");
5832
+ const timeFields = (0, import_sdk11.fieldsFor)(schema.fields, "timeAxis");
5483
5833
  const chosen = x ? schema.fields.find((field) => field.key === x) ?? null : timeFields[0] ?? null;
5484
- return chosen && (0, import_sdk10.specFor)(chosen).capabilities.timeAxis ? chosen : null;
5834
+ return chosen && (0, import_sdk11.specFor)(chosen).capabilities.timeAxis ? chosen : null;
5485
5835
  }, [schema, x]);
5486
- const measure = (0, import_react30.useMemo)(() => {
5836
+ const measure = (0, import_react31.useMemo)(() => {
5487
5837
  if (!schema || !y) {
5488
5838
  return null;
5489
5839
  }
5490
- const candidates = (0, import_sdk10.fieldsAggregatableBy)(schema.fields, aggregate);
5840
+ const candidates = (0, import_sdk11.fieldsAggregatableBy)(schema.fields, aggregate);
5491
5841
  return candidates.find((field) => field.key === y) ?? null;
5492
5842
  }, [schema, y, aggregate]);
5493
- const buckets = (0, import_react30.useMemo)(
5843
+ const buckets = (0, import_react31.useMemo)(
5494
5844
  () => axis ? bucketise(records, axis, measure, y ? aggregate : "count", bucket) : [],
5495
5845
  [records, axis, measure, aggregate, bucket, y]
5496
5846
  );
5497
5847
  if (error) {
5498
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5848
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5499
5849
  }
5500
5850
  if (!schema || loading) {
5501
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5851
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5502
5852
  }
5503
5853
  if (!axis) {
5504
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: x ? `"${x}" is not a date, so it cannot be a time axis.` : `${schema.namePlural} have no date field to chart against. Add one and this chart will use it.` });
5854
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: x ? `"${x}" is not a date, so it cannot be a time axis.` : `${schema.namePlural} have no date field to chart against. Add one and this chart will use it.` });
5505
5855
  }
5506
5856
  if (y && !measure) {
5507
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: `"${y}" cannot be ${aggregate === "avg" ? "averaged" : `combined with ${aggregate}`}.` });
5857
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: `"${y}" cannot be ${aggregate === "avg" ? "averaged" : `combined with ${aggregate}`}.` });
5508
5858
  }
5509
5859
  const peak = Math.max(...buckets.map((entry) => entry.value), 0);
5510
5860
  const heading = title ?? `${measure ? `${aggregate} of ${measure.label}` : schema.namePlural} by ${axis.label}`;
5511
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("figure", { className: cls("b316-card b316-chart", className), style, children: [
5512
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("figcaption", { className: "b316-chart-title", children: heading }),
5513
- buckets.length === 0 || peak === 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-empty", children: "Nothing to chart yet." }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-chart-plot", style: { height }, children: buckets.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "b316-chart-col", children: [
5514
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5861
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("figure", { className: cls("b316-card b316-chart", className), style, children: [
5862
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("figcaption", { className: "b316-chart-title", children: heading }),
5863
+ buckets.length === 0 || peak === 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-empty", children: "Nothing to chart yet." }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-chart-plot", style: { height }, children: buckets.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "b316-chart-col", children: [
5864
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5515
5865
  "div",
5516
5866
  {
5517
5867
  className: "b316-chart-bar",
@@ -5519,18 +5869,18 @@ function Chart({
5519
5869
  title: `${entry.label}: ${format(entry.value)}`
5520
5870
  }
5521
5871
  ),
5522
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "b316-chart-label", children: entry.label })
5872
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "b316-chart-label", children: entry.label })
5523
5873
  ] }, entry.key)) }),
5524
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("details", { className: "b316-chart-data", children: [
5525
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("summary", { children: "Values" }),
5526
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("table", { className: "b316-table", children: [
5527
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("tr", { children: [
5528
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("th", { scope: "col", children: axis.label }),
5529
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("th", { scope: "col", children: measure ? measure.label : "Count" })
5874
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("details", { className: "b316-chart-data", children: [
5875
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("summary", { children: "Values" }),
5876
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("table", { className: "b316-table", children: [
5877
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("tr", { children: [
5878
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("th", { scope: "col", children: axis.label }),
5879
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("th", { scope: "col", children: measure ? measure.label : "Count" })
5530
5880
  ] }) }),
5531
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("tbody", { children: buckets.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("tr", { children: [
5532
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("td", { children: entry.label }),
5533
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("td", { children: format(entry.value) })
5881
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("tbody", { children: buckets.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("tr", { children: [
5882
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("td", { children: entry.label }),
5883
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("td", { children: format(entry.value) })
5534
5884
  ] }, entry.key)) })
5535
5885
  ] })
5536
5886
  ] })
@@ -5588,9 +5938,9 @@ function combine(values, aggregate) {
5588
5938
  }
5589
5939
 
5590
5940
  // src/RecordDetail.tsx
5591
- var import_sdk11 = require("@base316/sdk");
5592
- var import_react31 = require("react");
5593
- var import_jsx_runtime31 = require("react/jsx-runtime");
5941
+ var import_sdk12 = require("@base316/sdk");
5942
+ var import_react32 = require("react");
5943
+ var import_jsx_runtime33 = require("react/jsx-runtime");
5594
5944
  function RecordDetail({
5595
5945
  collection,
5596
5946
  recordId,
@@ -5606,23 +5956,23 @@ function RecordDetail({
5606
5956
  tenant,
5607
5957
  recordId
5608
5958
  });
5609
- const [editing, setEditing] = (0, import_react31.useState)(false);
5959
+ const [editing, setEditing] = (0, import_react32.useState)(false);
5610
5960
  const record = records.find((candidate) => candidate.id === recordId);
5611
5961
  if (error) {
5612
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5962
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5613
5963
  }
5614
5964
  if (!schema || loading) {
5615
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5965
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5616
5966
  }
5617
5967
  if (!record) {
5618
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cls("b316-card", className), style, children: [
5968
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: cls("b316-card", className), style, children: [
5619
5969
  "That ",
5620
5970
  schema.name.toLowerCase(),
5621
5971
  " is not available."
5622
5972
  ] });
5623
5973
  }
5624
5974
  if (editing) {
5625
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5975
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5626
5976
  RecordForm,
5627
5977
  {
5628
5978
  collection,
@@ -5636,12 +5986,12 @@ function RecordDetail({
5636
5986
  );
5637
5987
  }
5638
5988
  const writable = canWrite && !readOnly;
5639
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cls("b316-card b316-detail", className), style, children: [
5640
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-detail-head", children: [
5641
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("h3", { className: "b316-detail-title", children: record.title ?? schema.name }),
5642
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-detail-actions", children: [
5643
- writable ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: () => setEditing(true), children: "Edit" }) : null,
5644
- writable ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5989
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: cls("b316-card b316-detail", className), style, children: [
5990
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-detail-head", children: [
5991
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("h3", { className: "b316-detail-title", children: record.title ?? schema.name }),
5992
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-detail-actions", children: [
5993
+ writable ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: () => setEditing(true), children: "Edit" }) : null,
5994
+ writable ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5645
5995
  ConfirmButton,
5646
5996
  {
5647
5997
  className: "b316-button-quiet b316-danger",
@@ -5654,15 +6004,15 @@ function RecordDetail({
5654
6004
  children: "Delete"
5655
6005
  }
5656
6006
  ) : null,
5657
- onClose ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: onClose, children: "Close" }) : null
6007
+ onClose ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: onClose, children: "Close" }) : null
5658
6008
  ] })
5659
6009
  ] }),
5660
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("dl", { className: "b316-detail-fields", children: schema.fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-detail-row", children: [
5661
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("dt", { className: "b316-label", children: [
6010
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("dl", { className: "b316-detail-fields", children: schema.fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-detail-row", children: [
6011
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("dt", { className: "b316-label", children: [
5662
6012
  field.label,
5663
- (0, import_sdk11.specFor)(field).computed ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "b316-muted", children: " (calculated)" }) : null
6013
+ (0, import_sdk12.specFor)(field).computed ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "b316-muted", children: " (calculated)" }) : null
5664
6014
  ] }),
5665
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
6015
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5666
6016
  FieldCell,
5667
6017
  {
5668
6018
  value: record.fields[field.key] ?? null,
@@ -5676,8 +6026,8 @@ function RecordDetail({
5676
6026
  }
5677
6027
 
5678
6028
  // src/SubscriptionManager.tsx
5679
- var import_react32 = require("react");
5680
- var import_jsx_runtime32 = require("react/jsx-runtime");
6029
+ var import_react33 = require("react");
6030
+ var import_jsx_runtime34 = require("react/jsx-runtime");
5681
6031
  function statusLabel(status2) {
5682
6032
  const words = status2.toLowerCase().split("_");
5683
6033
  return words.map((w, i) => i === 0 ? w.charAt(0).toUpperCase() + w.slice(1) : w).join(" ");
@@ -5717,16 +6067,16 @@ function SubscriptionManager({
5717
6067
  style
5718
6068
  }) {
5719
6069
  const { client, token, loading: sessionLoading } = useBase316();
5720
- const [subscription, setSubscription] = (0, import_react32.useState)(null);
5721
- const [loading, setLoading] = (0, import_react32.useState)(true);
5722
- const [managedBy, setManagedBy] = (0, import_react32.useState)(null);
5723
- const [schedule, setSchedule] = (0, import_react32.useState)([]);
5724
- const [busy, setBusy] = (0, import_react32.useState)(false);
5725
- const [error, setError] = (0, import_react32.useState)(null);
5726
- const [step, setStep] = (0, import_react32.useState)({ kind: "idle" });
5727
- const [reason, setReason] = (0, import_react32.useState)(null);
5728
- const [comment, setComment] = (0, import_react32.useState)("");
5729
- const load = (0, import_react32.useCallback)(async () => {
6070
+ const [subscription, setSubscription] = (0, import_react33.useState)(null);
6071
+ const [loading, setLoading] = (0, import_react33.useState)(true);
6072
+ const [managedBy, setManagedBy] = (0, import_react33.useState)(null);
6073
+ const [schedule, setSchedule] = (0, import_react33.useState)([]);
6074
+ const [busy, setBusy] = (0, import_react33.useState)(false);
6075
+ const [error, setError] = (0, import_react33.useState)(null);
6076
+ const [step, setStep] = (0, import_react33.useState)({ kind: "idle" });
6077
+ const [reason, setReason] = (0, import_react33.useState)(null);
6078
+ const [comment, setComment] = (0, import_react33.useState)("");
6079
+ const load = (0, import_react33.useCallback)(async () => {
5730
6080
  if (!token) {
5731
6081
  setSubscription(null);
5732
6082
  setLoading(false);
@@ -5744,7 +6094,7 @@ function SubscriptionManager({
5744
6094
  setLoading(false);
5745
6095
  }
5746
6096
  }, [client, token]);
5747
- (0, import_react32.useEffect)(() => {
6097
+ (0, import_react33.useEffect)(() => {
5748
6098
  void load();
5749
6099
  }, [load]);
5750
6100
  const act = async (change, failure) => {
@@ -5762,29 +6112,29 @@ function SubscriptionManager({
5762
6112
  }
5763
6113
  };
5764
6114
  if (sessionLoading || loading) {
5765
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
6115
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5766
6116
  }
5767
6117
  if (!token) {
5768
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: "Sign in to manage your subscription." });
6118
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card", className), style, children: "Sign in to manage your subscription." });
5769
6119
  }
5770
6120
  if (error) {
5771
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
6121
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5772
6122
  }
5773
6123
  if (!subscription) {
5774
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: "You are not subscribed to a plan." });
6124
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card", className), style, children: "You are not subscribed to a plan." });
5775
6125
  }
5776
6126
  const renews = new Date(subscription.currentPeriodEnd).toLocaleDateString();
5777
6127
  const next = schedule[0] ?? null;
5778
6128
  const nextOn = next?.effectiveAt ? new Date(next.effectiveAt).toLocaleDateString() : renews;
5779
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: cls("b316-card", className), style, children: [
5780
- error ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
5781
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-plan-name", children: subscription.planVersion.plan.name }),
5782
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "b316-muted", children: [
6129
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: cls("b316-card", className), style, children: [
6130
+ error ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6131
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-plan-name", children: subscription.planVersion.plan.name }),
6132
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-muted", children: [
5783
6133
  statusLabel(subscription.status),
5784
6134
  " \xB7 ",
5785
6135
  subscription.cancelAtPeriodEnd ? `Ends ${renews}` : `Renews ${renews}`
5786
6136
  ] }),
5787
- next && !managedBy ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "b316-muted", role: "status", style: { marginTop: 10 }, children: [
6137
+ next && !managedBy ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-muted", role: "status", style: { marginTop: 10 }, children: [
5788
6138
  "Moves to ",
5789
6139
  next.plan.name,
5790
6140
  " on ",
@@ -5792,7 +6142,7 @@ function SubscriptionManager({
5792
6142
  ". You keep ",
5793
6143
  subscription.planVersion.plan.name,
5794
6144
  " until then.",
5795
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6145
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
5796
6146
  "button",
5797
6147
  {
5798
6148
  type: "button",
@@ -5817,17 +6167,17 @@ function SubscriptionManager({
5817
6167
  }
5818
6168
  ) })
5819
6169
  ] }) : null,
5820
- managedBy ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("p", { className: "b316-muted", children: [
6170
+ managedBy ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
5821
6171
  "Provided by ",
5822
6172
  managedBy.name ?? "the organization that manages your account",
5823
6173
  ". Ask them to change or cancel it."
5824
- ] }) : subscription.cancelAtPeriodEnd ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { children: [
5825
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("p", { className: "b316-muted", children: [
6174
+ ] }) : subscription.cancelAtPeriodEnd ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
6175
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
5826
6176
  "This subscription will not renew. You keep access until ",
5827
6177
  renews,
5828
6178
  "."
5829
6179
  ] }),
5830
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6180
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
5831
6181
  "button",
5832
6182
  {
5833
6183
  type: "button",
@@ -5837,14 +6187,14 @@ function SubscriptionManager({
5837
6187
  children: busy ? "Working\u2026" : "Resume subscription"
5838
6188
  }
5839
6189
  )
5840
- ] }) : step.kind === "offer" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("section", { style: { marginTop: 14 }, "aria-label": "Retention offer", children: [
5841
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-plan-name", children: step.cancellation.offer.headline ?? "Before you go" }),
5842
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "b316-muted", children: step.cancellation.offer.message ?? `Stay on ${subscription.planVersion.plan.name} and get ${describeRetentionOffer(
6190
+ ] }) : step.kind === "offer" ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("section", { style: { marginTop: 14 }, "aria-label": "Retention offer", children: [
6191
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-plan-name", children: step.cancellation.offer.headline ?? "Before you go" }),
6192
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "b316-muted", children: step.cancellation.offer.message ?? `Stay on ${subscription.planVersion.plan.name} and get ${describeRetentionOffer(
5843
6193
  step.cancellation.offer,
5844
6194
  step.cancellation.currency
5845
6195
  )}.` }),
5846
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
5847
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6196
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
6197
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
5848
6198
  "button",
5849
6199
  {
5850
6200
  type: "button",
@@ -5857,7 +6207,7 @@ function SubscriptionManager({
5857
6207
  children: busy ? "Working\u2026" : "Accept offer and stay"
5858
6208
  }
5859
6209
  ),
5860
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6210
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
5861
6211
  "button",
5862
6212
  {
5863
6213
  type: "button",
@@ -5871,12 +6221,12 @@ function SubscriptionManager({
5871
6221
  }
5872
6222
  )
5873
6223
  ] }),
5874
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("p", { className: "b316-muted", children: [
6224
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
5875
6225
  "If you cancel, you keep access until ",
5876
6226
  renews,
5877
6227
  "."
5878
6228
  ] })
5879
- ] }) : step.kind === "survey" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
6229
+ ] }) : step.kind === "survey" ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
5880
6230
  "form",
5881
6231
  {
5882
6232
  style: { marginTop: 14 },
@@ -5896,15 +6246,15 @@ function SubscriptionManager({
5896
6246
  }, "Could not cancel. Try again.");
5897
6247
  },
5898
6248
  children: [
5899
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("p", { className: "b316-muted", children: [
6249
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
5900
6250
  "You keep access until ",
5901
6251
  renews,
5902
6252
  ". It will not renew after that."
5903
6253
  ] }),
5904
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("fieldset", { className: "b316-fieldset", children: [
5905
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("legend", { className: "b316-label", children: "Why are you leaving? (optional)" }),
5906
- REASONS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
5907
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6254
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("fieldset", { className: "b316-fieldset", children: [
6255
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("legend", { className: "b316-label", children: "Why are you leaving? (optional)" }),
6256
+ REASONS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("label", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
6257
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
5908
6258
  "input",
5909
6259
  {
5910
6260
  type: "radio",
@@ -5914,12 +6264,12 @@ function SubscriptionManager({
5914
6264
  onChange: () => setReason(option.value)
5915
6265
  }
5916
6266
  ),
5917
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: option.label })
6267
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { children: option.label })
5918
6268
  ] }, option.value))
5919
6269
  ] }),
5920
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { className: "b316-field", children: [
5921
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "b316-label", children: "Anything else? (optional)" }),
5922
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6270
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("label", { className: "b316-field", children: [
6271
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "b316-label", children: "Anything else? (optional)" }),
6272
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
5923
6273
  "textarea",
5924
6274
  {
5925
6275
  className: "b316-input",
@@ -5930,9 +6280,9 @@ function SubscriptionManager({
5930
6280
  }
5931
6281
  )
5932
6282
  ] }),
5933
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
5934
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("button", { type: "submit", className: "b316-button b316-button-secondary", disabled: busy, children: busy ? "Working\u2026" : "Cancel subscription" }),
5935
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
6283
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
6284
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "submit", className: "b316-button b316-button-secondary", disabled: busy, children: busy ? "Working\u2026" : "Cancel subscription" }),
6285
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
5936
6286
  "button",
5937
6287
  {
5938
6288
  type: "button",
@@ -5948,7 +6298,7 @@ function SubscriptionManager({
5948
6298
  ] })
5949
6299
  ]
5950
6300
  }
5951
- ) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6301
+ ) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
5952
6302
  "button",
5953
6303
  {
5954
6304
  type: "button",
@@ -5966,11 +6316,11 @@ function SubscriptionManager({
5966
6316
  }
5967
6317
 
5968
6318
  // src/BillingPortal.tsx
5969
- var import_react36 = require("react");
6319
+ var import_react37 = require("react");
5970
6320
 
5971
6321
  // src/CreditBalances.tsx
5972
- var import_react33 = require("react");
5973
- var import_jsx_runtime33 = require("react/jsx-runtime");
6322
+ var import_react34 = require("react");
6323
+ var import_jsx_runtime35 = require("react/jsx-runtime");
5974
6324
  function units(value) {
5975
6325
  return value === null ? "Unlimited" : Number(value).toLocaleString("en");
5976
6326
  }
@@ -6005,10 +6355,10 @@ function Feature({
6005
6355
  }) {
6006
6356
  const { client, token } = useBase316();
6007
6357
  const setting = feature.autoRecharge;
6008
- const [busy, setBusy] = (0, import_react33.useState)(false);
6009
- const [error, setError] = (0, import_react33.useState)(null);
6010
- const [saved, setSaved] = (0, import_react33.useState)(null);
6011
- const [pack, setPack] = (0, import_react33.useState)(feature.packs[0]?.id ?? "");
6358
+ const [busy, setBusy] = (0, import_react34.useState)(false);
6359
+ const [error, setError] = (0, import_react34.useState)(null);
6360
+ const [saved, setSaved] = (0, import_react34.useState)(null);
6361
+ const [pack, setPack] = (0, import_react34.useState)(feature.packs[0]?.id ?? "");
6012
6362
  const unit = feature.unit ? ` ${feature.unit}` : "";
6013
6363
  const warning = status(feature);
6014
6364
  const buy = async () => {
@@ -6062,33 +6412,33 @@ function Feature({
6062
6412
  setBusy(false);
6063
6413
  }
6064
6414
  };
6065
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-card b316-credit-balance", children: [
6066
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-label", children: feature.featureName }),
6067
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { children: [
6068
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("strong", { children: units(feature.remaining) }),
6415
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-card b316-credit-balance", children: [
6416
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-label", children: feature.featureName }),
6417
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { children: [
6418
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("strong", { children: units(feature.remaining) }),
6069
6419
  unit,
6070
6420
  " left"
6071
6421
  ] }),
6072
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-muted", children: [
6422
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-muted", children: [
6073
6423
  feature.allowance === null ? "Unlimited allowance" : `${units(feature.allowanceRemaining)} of ${units(feature.allowance)} included this period`,
6074
6424
  " ",
6075
6425
  "\xB7 ",
6076
6426
  units(feature.purchasedRemaining),
6077
6427
  " purchased"
6078
6428
  ] }),
6079
- warning && !managed ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-error", role: "alert", children: warning }) : null,
6080
- error ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6081
- saved ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-notice", role: "status", children: saved }) : null,
6082
- managed || feature.packs.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
6083
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-row", style: { marginTop: 12 }, children: [
6084
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6429
+ warning && !managed ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: warning }) : null,
6430
+ error ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6431
+ saved ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-notice", role: "status", children: saved }) : null,
6432
+ managed || feature.packs.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
6433
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-row", style: { marginTop: 12 }, children: [
6434
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6085
6435
  "select",
6086
6436
  {
6087
6437
  className: "b316-input",
6088
6438
  "aria-label": "Pack to buy",
6089
6439
  value: pack,
6090
6440
  onChange: (event) => setPack(event.target.value),
6091
- children: feature.packs.map((option) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("option", { value: option.id, children: [
6441
+ children: feature.packs.map((option) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("option", { value: option.id, children: [
6092
6442
  option.name,
6093
6443
  " \u2014 ",
6094
6444
  units(option.units),
@@ -6097,7 +6447,7 @@ function Feature({
6097
6447
  ] }, option.id))
6098
6448
  }
6099
6449
  ),
6100
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6450
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6101
6451
  "button",
6102
6452
  {
6103
6453
  type: "button",
@@ -6108,19 +6458,19 @@ function Feature({
6108
6458
  }
6109
6459
  )
6110
6460
  ] }),
6111
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("form", { onSubmit: save, style: { marginTop: 16 }, children: [
6112
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("label", { className: "b316-checkbox", children: [
6113
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("input", { type: "checkbox", name: "enabled", defaultChecked: setting?.enabled ?? false }),
6461
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("form", { onSubmit: save, style: { marginTop: 16 }, children: [
6462
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: "b316-checkbox", children: [
6463
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("input", { type: "checkbox", name: "enabled", defaultChecked: setting?.enabled ?? false }),
6114
6464
  " ",
6115
6465
  "Buy credits automatically when my balance runs low"
6116
6466
  ] }),
6117
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("label", { className: "b316-field", children: [
6118
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "b316-label", children: [
6467
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: "b316-field", children: [
6468
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "b316-label", children: [
6119
6469
  "When fewer than this many",
6120
6470
  unit,
6121
6471
  " are left"
6122
6472
  ] }),
6123
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6473
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6124
6474
  "input",
6125
6475
  {
6126
6476
  className: "b316-input",
@@ -6131,21 +6481,21 @@ function Feature({
6131
6481
  }
6132
6482
  )
6133
6483
  ] }),
6134
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("label", { className: "b316-field", children: [
6135
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "b316-label", children: "Buy" }),
6136
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6484
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: "b316-field", children: [
6485
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "b316-label", children: "Buy" }),
6486
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6137
6487
  "select",
6138
6488
  {
6139
6489
  className: "b316-input",
6140
6490
  name: "creditPackId",
6141
6491
  defaultValue: setting?.creditPackId ?? feature.packs[0]?.id,
6142
- children: feature.packs.map((option) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("option", { value: option.id, children: option.name }, option.id))
6492
+ children: feature.packs.map((option) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("option", { value: option.id, children: option.name }, option.id))
6143
6493
  }
6144
6494
  )
6145
6495
  ] }),
6146
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("label", { className: "b316-field", children: [
6147
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "b316-label", children: "At most this many times a month" }),
6148
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6496
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: "b316-field", children: [
6497
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "b316-label", children: "At most this many times a month" }),
6498
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6149
6499
  "input",
6150
6500
  {
6151
6501
  className: "b316-input",
@@ -6155,13 +6505,13 @@ function Feature({
6155
6505
  }
6156
6506
  )
6157
6507
  ] }),
6158
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("label", { className: "b316-field", children: [
6159
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "b316-label", children: [
6508
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("label", { className: "b316-field", children: [
6509
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "b316-label", children: [
6160
6510
  "Spending at most (",
6161
6511
  setting?.currency ?? feature.packs[0]?.currency ?? "USD",
6162
6512
  ") a month"
6163
6513
  ] }),
6164
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6514
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6165
6515
  "input",
6166
6516
  {
6167
6517
  className: "b316-input",
@@ -6171,16 +6521,16 @@ function Feature({
6171
6521
  }
6172
6522
  )
6173
6523
  ] }),
6174
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "submit", className: "b316-button", disabled: busy, children: "Save auto-recharge" })
6524
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("button", { type: "submit", className: "b316-button", disabled: busy, children: "Save auto-recharge" })
6175
6525
  ] })
6176
6526
  ] })
6177
6527
  ] });
6178
6528
  }
6179
6529
  function CreditBalances({ onChange, className, style }) {
6180
6530
  const { client, token, loading: sessionLoading } = useBase316();
6181
- const [state, setState] = (0, import_react33.useState)({ kind: "loading" });
6182
- const [version, setVersion] = (0, import_react33.useState)(0);
6183
- (0, import_react33.useEffect)(() => {
6531
+ const [state, setState] = (0, import_react34.useState)({ kind: "loading" });
6532
+ const [version, setVersion] = (0, import_react34.useState)(0);
6533
+ (0, import_react34.useEffect)(() => {
6184
6534
  if (!token) return;
6185
6535
  let cancelled = false;
6186
6536
  client.billing.credits(token).then((credits2) => {
@@ -6193,24 +6543,24 @@ function CreditBalances({ onChange, className, style }) {
6193
6543
  cancelled = true;
6194
6544
  };
6195
6545
  }, [client, token, version]);
6196
- const wrap = (content) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cls("b316-credit-balances", className), style, children: content });
6546
+ const wrap = (content) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cls("b316-credit-balances", className), style, children: content });
6197
6547
  if (sessionLoading || !token || state.kind === "loading") return null;
6198
6548
  if (state.kind === "error") {
6199
6549
  return wrap(
6200
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-card", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your credits." }) })
6550
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-card", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your credits." }) })
6201
6551
  );
6202
6552
  }
6203
6553
  const { credits } = state;
6204
6554
  if (credits.features.length === 0) return null;
6205
6555
  return wrap(
6206
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
6207
- credits.managedBy ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("p", { className: "b316-muted", children: [
6556
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
6557
+ credits.managedBy ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("p", { className: "b316-muted", children: [
6208
6558
  "Credits for this account come from",
6209
6559
  " ",
6210
6560
  credits.managedBy.name ?? "the organization that manages it",
6211
6561
  ", which manages them."
6212
6562
  ] }) : null,
6213
- credits.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6563
+ credits.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6214
6564
  Feature,
6215
6565
  {
6216
6566
  feature,
@@ -6227,19 +6577,19 @@ function CreditBalances({ onChange, className, style }) {
6227
6577
  }
6228
6578
 
6229
6579
  // src/PaymentMethod.tsx
6230
- var import_react34 = require("react");
6231
- var import_jsx_runtime34 = require("react/jsx-runtime");
6580
+ var import_react35 = require("react");
6581
+ var import_jsx_runtime36 = require("react/jsx-runtime");
6232
6582
  function brandName(brand) {
6233
6583
  if (!brand) return "Card";
6234
6584
  return brand.charAt(0).toUpperCase() + brand.slice(1);
6235
6585
  }
6236
6586
  function PaymentMethod({ returnUrl, className, style }) {
6237
6587
  const { client, token, loading: sessionLoading } = useBase316();
6238
- const [state, setState] = (0, import_react34.useState)({ kind: "loading" });
6239
- const [busy, setBusy] = (0, import_react34.useState)(false);
6240
- const [error, setError] = (0, import_react34.useState)(null);
6241
- const [version, setVersion] = (0, import_react34.useState)(0);
6242
- (0, import_react34.useEffect)(() => {
6588
+ const [state, setState] = (0, import_react35.useState)({ kind: "loading" });
6589
+ const [busy, setBusy] = (0, import_react35.useState)(false);
6590
+ const [error, setError] = (0, import_react35.useState)(null);
6591
+ const [version, setVersion] = (0, import_react35.useState)(0);
6592
+ (0, import_react35.useEffect)(() => {
6243
6593
  if (!token) return;
6244
6594
  let cancelled = false;
6245
6595
  client.billing.paymentMethods(token).then((result) => {
@@ -6255,7 +6605,7 @@ function PaymentMethod({ returnUrl, className, style }) {
6255
6605
  cancelled = true;
6256
6606
  };
6257
6607
  }, [client, token, version]);
6258
- const wrap = (content) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card b316-payment-method", className), style, children: content });
6608
+ const wrap = (content) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cls("b316-card b316-payment-method", className), style, children: content });
6259
6609
  if (sessionLoading) return wrap("Loading\u2026");
6260
6610
  if (!token) return wrap("Sign in to manage your payment method.");
6261
6611
  switch (state.kind) {
@@ -6263,11 +6613,11 @@ function PaymentMethod({ returnUrl, className, style }) {
6263
6613
  return wrap("Loading\u2026");
6264
6614
  case "error":
6265
6615
  return wrap(
6266
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your payment method." })
6616
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your payment method." })
6267
6617
  );
6268
6618
  case "managed":
6269
6619
  return wrap(
6270
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "b316-muted", children: "Your plan is paid for by the organization that manages it." })
6620
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "b316-muted", children: "Your plan is paid for by the organization that manages it." })
6271
6621
  );
6272
6622
  }
6273
6623
  const card = state.cards.find((saved) => saved.isDefault) ?? null;
@@ -6286,31 +6636,31 @@ function PaymentMethod({ returnUrl, className, style }) {
6286
6636
  }
6287
6637
  };
6288
6638
  return wrap(
6289
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
6290
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-label", children: "Payment method" }),
6291
- card ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
6292
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
6639
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
6640
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-label", children: "Payment method" }),
6641
+ card ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
6642
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
6293
6643
  brandName(card.brand),
6294
6644
  " ending ",
6295
6645
  card.last4 ?? "????"
6296
6646
  ] }),
6297
- card.expMonth && card.expYear ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-muted", children: [
6647
+ card.expMonth && card.expYear ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "b316-muted", children: [
6298
6648
  "Expires ",
6299
6649
  String(card.expMonth).padStart(2, "0"),
6300
6650
  "/",
6301
6651
  card.expYear
6302
6652
  ] }) : null
6303
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "b316-muted", children: "No card on file." }),
6304
- others.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { style: { marginTop: 12 }, children: [
6305
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-label", children: "Other saved cards" }),
6306
- others.map((saved) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-row", style: { marginTop: 6 }, children: [
6307
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { children: [
6653
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "b316-muted", children: "No card on file." }),
6654
+ others.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { style: { marginTop: 12 }, children: [
6655
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-label", children: "Other saved cards" }),
6656
+ others.map((saved) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "b316-row", style: { marginTop: 6 }, children: [
6657
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { children: [
6308
6658
  brandName(saved.brand),
6309
6659
  " ending ",
6310
6660
  saved.last4 ?? "????"
6311
6661
  ] }),
6312
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { children: [
6313
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6662
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { children: [
6663
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6314
6664
  "button",
6315
6665
  {
6316
6666
  type: "button",
@@ -6324,7 +6674,7 @@ function PaymentMethod({ returnUrl, className, style }) {
6324
6674
  }
6325
6675
  ),
6326
6676
  " ",
6327
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6677
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6328
6678
  "button",
6329
6679
  {
6330
6680
  type: "button",
@@ -6340,8 +6690,8 @@ function PaymentMethod({ returnUrl, className, style }) {
6340
6690
  ] })
6341
6691
  ] }, saved.id))
6342
6692
  ] }) : null,
6343
- error ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6344
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6693
+ error ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6694
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6345
6695
  "button",
6346
6696
  {
6347
6697
  type: "button",
@@ -6370,8 +6720,8 @@ function PaymentMethod({ returnUrl, className, style }) {
6370
6720
  }
6371
6721
 
6372
6722
  // src/PlanChangeReview.tsx
6373
- var import_react35 = require("react");
6374
- var import_jsx_runtime35 = require("react/jsx-runtime");
6723
+ var import_react36 = require("react");
6724
+ var import_jsx_runtime37 = require("react/jsx-runtime");
6375
6725
  function money5(amount, currency) {
6376
6726
  if (amount === null) return "\u2014";
6377
6727
  const value = Number(amount);
@@ -6404,12 +6754,12 @@ function PlanChangeReview({
6404
6754
  style
6405
6755
  }) {
6406
6756
  const { client, token } = useBase316();
6407
- const [timing, setTiming] = (0, import_react35.useState)(void 0);
6408
- const [preview, setPreview] = (0, import_react35.useState)(null);
6409
- const [error, setError] = (0, import_react35.useState)(null);
6410
- const [needsCard, setNeedsCard] = (0, import_react35.useState)(false);
6411
- const [busy, setBusy] = (0, import_react35.useState)(false);
6412
- (0, import_react35.useEffect)(() => {
6757
+ const [timing, setTiming] = (0, import_react36.useState)(void 0);
6758
+ const [preview, setPreview] = (0, import_react36.useState)(null);
6759
+ const [error, setError] = (0, import_react36.useState)(null);
6760
+ const [needsCard, setNeedsCard] = (0, import_react36.useState)(false);
6761
+ const [busy, setBusy] = (0, import_react36.useState)(false);
6762
+ (0, import_react36.useEffect)(() => {
6413
6763
  if (!token) return;
6414
6764
  let cancelled = false;
6415
6765
  client.billing.previewPlanChange(token, planVersionId, timing).then((result) => {
@@ -6426,7 +6776,7 @@ function PlanChangeReview({
6426
6776
  cancelled = true;
6427
6777
  };
6428
6778
  }, [client, token, planVersionId, timing]);
6429
- const confirm = (0, import_react35.useCallback)(async () => {
6779
+ const confirm = (0, import_react36.useCallback)(async () => {
6430
6780
  if (!token || !preview) return;
6431
6781
  setBusy(true);
6432
6782
  setError(null);
@@ -6447,7 +6797,7 @@ function PlanChangeReview({
6447
6797
  setBusy(false);
6448
6798
  }
6449
6799
  }, [client, token, preview, planVersionId, onDone]);
6450
- const addCard = (0, import_react35.useCallback)(async () => {
6800
+ const addCard = (0, import_react36.useCallback)(async () => {
6451
6801
  if (onNeedsCard) {
6452
6802
  onNeedsCard();
6453
6803
  return;
@@ -6461,12 +6811,12 @@ function PlanChangeReview({
6461
6811
  setError("Cards cannot be added here right now.");
6462
6812
  }
6463
6813
  }, [client, token, onNeedsCard]);
6464
- const card = (content) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cls("b316-card b316-plan-review", className), style, children: content });
6814
+ const card = (content) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cls("b316-card b316-plan-review", className), style, children: content });
6465
6815
  if (error && !preview) {
6466
6816
  return card(
6467
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
6468
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: error }),
6469
- onCancel ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: "Back" }) : null
6817
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
6818
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-error", role: "alert", children: error }),
6819
+ onCancel ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: "Back" }) : null
6470
6820
  ] })
6471
6821
  );
6472
6822
  }
@@ -6479,26 +6829,26 @@ function PlanChangeReview({
6479
6829
  const otherReason = preview.timings[other]?.reason ?? null;
6480
6830
  const changes = preview.entitlements.filter((change) => change.change !== "UNCHANGED");
6481
6831
  return card(
6482
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
6483
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-plan-name", children: [
6832
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(import_jsx_runtime37.Fragment, { children: [
6833
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-plan-name", children: [
6484
6834
  "Change to ",
6485
6835
  to.planName
6486
6836
  ] }),
6487
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-muted", children: [
6837
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-muted", children: [
6488
6838
  "From ",
6489
6839
  from.planName
6490
6840
  ] }),
6491
- error ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6492
- changes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: "b316-muted", children: "Every feature stays the same." }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("table", { className: "b316-review-table", children: [
6493
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("tr", { children: [
6494
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("th", { children: "Feature" }),
6495
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("th", { children: from.planName }),
6496
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("th", { children: to.planName })
6841
+ error ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6842
+ changes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "b316-muted", children: "Every feature stays the same." }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("table", { className: "b316-review-table", children: [
6843
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("tr", { children: [
6844
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("th", { children: "Feature" }),
6845
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("th", { children: from.planName }),
6846
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("th", { children: to.planName })
6497
6847
  ] }) }),
6498
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("tbody", { children: changes.map((change) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("tr", { children: [
6499
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("td", { children: change.featureName }),
6500
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("td", { children: limitText(change.before, change.type) }),
6501
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6848
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("tbody", { children: changes.map((change) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("tr", { children: [
6849
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("td", { children: change.featureName }),
6850
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("td", { children: limitText(change.before, change.type) }),
6851
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6502
6852
  "td",
6503
6853
  {
6504
6854
  className: change.change === "GAINED" || change.change === "INCREASED" ? "b316-review-gain" : "b316-review-loss",
@@ -6507,40 +6857,40 @@ function PlanChangeReview({
6507
6857
  )
6508
6858
  ] }, change.featureId)) })
6509
6859
  ] }),
6510
- preview.timing === "NOW" ? now.trialing ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("p", { children: [
6860
+ preview.timing === "NOW" ? now.trialing ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("p", { children: [
6511
6861
  "The change happens now. Your trial carries on until ",
6512
6862
  day4(now.trialEndsAt),
6513
6863
  ", and nothing is charged before then."
6514
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { children: [
6515
- Number(now.credit) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-row", children: [
6516
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "b316-muted", children: [
6864
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { children: [
6865
+ Number(now.credit) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-row", children: [
6866
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "b316-muted", children: [
6517
6867
  "Credit for the unused part of ",
6518
6868
  from.planName
6519
6869
  ] }),
6520
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "b316-num", children: [
6870
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "b316-num", children: [
6521
6871
  "\u2212",
6522
6872
  money5(now.credit, from.currency)
6523
6873
  ] })
6524
6874
  ] }) : null,
6525
- Number(now.closingUsage) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-row", children: [
6526
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "b316-muted", children: "Usage so far this period" }),
6527
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "b316-num", children: money5(now.closingUsage, from.currency) })
6875
+ Number(now.closingUsage) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-row", children: [
6876
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "b316-muted", children: "Usage so far this period" }),
6877
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "b316-num", children: money5(now.closingUsage, from.currency) })
6528
6878
  ] }) : null,
6529
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-row", children: [
6530
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "b316-muted", children: [
6879
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-row", children: [
6880
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "b316-muted", children: [
6531
6881
  to.planName,
6532
6882
  ", ",
6533
6883
  day4(now.newPeriod.start),
6534
6884
  " \u2013 ",
6535
6885
  day4(now.newPeriod.end)
6536
6886
  ] }),
6537
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "b316-num", children: money5(now.newPeriodCharge, to.currency) })
6887
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "b316-num", children: money5(now.newPeriodCharge, to.currency) })
6538
6888
  ] }),
6539
- now.net !== null ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-row b316-invoice-total", children: [
6540
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { children: "Due now" }),
6541
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "b316-num", children: money5(now.net, to.currency) })
6889
+ now.net !== null ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-row b316-invoice-total", children: [
6890
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { children: "Due now" }),
6891
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "b316-num", children: money5(now.net, to.currency) })
6542
6892
  ] }) : null
6543
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("p", { children: [
6893
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("p", { children: [
6544
6894
  "You keep ",
6545
6895
  from.planName,
6546
6896
  " until ",
@@ -6553,7 +6903,7 @@ function PlanChangeReview({
6553
6903
  preview.atPeriodEnd.nextInvoice.currency
6554
6904
  )}.` : ""
6555
6905
  ] }),
6556
- otherOpen ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6906
+ otherOpen ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6557
6907
  "button",
6558
6908
  {
6559
6909
  type: "button",
@@ -6564,12 +6914,12 @@ function PlanChangeReview({
6564
6914
  },
6565
6915
  children: other === "NOW" ? "Change now instead" : "Wait until the end of the period instead"
6566
6916
  }
6567
- ) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: "b316-muted", children: TIMING_CLOSED[otherReason] }) : null,
6568
- needsCard ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-notice", role: "status", children: [
6917
+ ) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "b316-muted", children: TIMING_CLOSED[otherReason] }) : null,
6918
+ needsCard ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-notice", role: "status", children: [
6569
6919
  "A card is needed for a change that is charged now.",
6570
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-review-actions", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("button", { type: "button", className: "b316-button", onClick: () => void addCard(), children: "Add a card" }) })
6571
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-review-actions", children: [
6572
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6920
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-review-actions", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("button", { type: "button", className: "b316-button", onClick: () => void addCard(), children: "Add a card" }) })
6921
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-review-actions", children: [
6922
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6573
6923
  "button",
6574
6924
  {
6575
6925
  type: "button",
@@ -6579,7 +6929,7 @@ function PlanChangeReview({
6579
6929
  children: busy ? "Working\u2026" : preview.timing === "NOW" ? `Change to ${to.planName} now` : `Schedule ${to.planName}`
6580
6930
  }
6581
6931
  ),
6582
- onCancel ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: [
6932
+ onCancel ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: [
6583
6933
  "Keep ",
6584
6934
  from.planName
6585
6935
  ] }) : null
@@ -6589,7 +6939,7 @@ function PlanChangeReview({
6589
6939
  }
6590
6940
 
6591
6941
  // src/BillingPortal.tsx
6592
- var import_jsx_runtime36 = require("react/jsx-runtime");
6942
+ var import_jsx_runtime38 = require("react/jsx-runtime");
6593
6943
  function BillingPortal({
6594
6944
  returnUrl,
6595
6945
  featuredPlanKey,
@@ -6599,12 +6949,12 @@ function BillingPortal({
6599
6949
  style
6600
6950
  }) {
6601
6951
  const { client, token, loading: sessionLoading } = useBase316();
6602
- const [overview, setOverview] = (0, import_react36.useState)(null);
6603
- const [failed, setFailed] = (0, import_react36.useState)(false);
6604
- const [version, setVersion] = (0, import_react36.useState)(0);
6605
- const [reviewing, setReviewing] = (0, import_react36.useState)(null);
6606
- const [notice, setNotice] = (0, import_react36.useState)(null);
6607
- (0, import_react36.useEffect)(() => {
6952
+ const [overview, setOverview] = (0, import_react37.useState)(null);
6953
+ const [failed, setFailed] = (0, import_react37.useState)(false);
6954
+ const [version, setVersion] = (0, import_react37.useState)(0);
6955
+ const [reviewing, setReviewing] = (0, import_react37.useState)(null);
6956
+ const [notice, setNotice] = (0, import_react37.useState)(null);
6957
+ (0, import_react37.useEffect)(() => {
6608
6958
  if (!token) return;
6609
6959
  let cancelled = false;
6610
6960
  client.billing.subscription(token).then((result) => {
@@ -6623,28 +6973,28 @@ function BillingPortal({
6623
6973
  cancelled = true;
6624
6974
  };
6625
6975
  }, [client, token, version]);
6626
- const refresh = (0, import_react36.useCallback)(() => {
6976
+ const refresh = (0, import_react37.useCallback)(() => {
6627
6977
  setNotice(null);
6628
6978
  setVersion((value) => value + 1);
6629
6979
  }, []);
6630
- const shell = (content) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cls("b316-billing-portal", className), style, children: content });
6631
- if (sessionLoading) return shell(/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-card", children: "Loading\u2026" }));
6632
- if (!token) return shell(/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-card", children: "Sign in to manage your billing." }));
6980
+ const shell = (content) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: cls("b316-billing-portal", className), style, children: content });
6981
+ if (sessionLoading) return shell(/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-card", children: "Loading\u2026" }));
6982
+ if (!token) return shell(/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-card", children: "Sign in to manage your billing." }));
6633
6983
  if (failed) {
6634
6984
  return shell(
6635
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-card", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your billing." }) })
6985
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-card", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your billing." }) })
6636
6986
  );
6637
6987
  }
6638
- if (!overview) return shell(/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-card", children: "Loading\u2026" }));
6988
+ if (!overview) return shell(/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-card", children: "Loading\u2026" }));
6639
6989
  const { subscription, managedBy, quantityPriced } = overview;
6640
6990
  const canChange = Boolean(subscription) && !managedBy;
6641
6991
  return shell(
6642
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
6643
- notice ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-card b316-notice", role: "status", children: notice }) : null,
6644
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SubscriptionManager, { onChange: refresh }, `plan-${version}`),
6645
- canChange ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(UpcomingInvoice, {}, `next-${version}`) : null,
6646
- canChange && quantityPriced ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SeatManager, { unitLabel, onChange: refresh }, `seats-${version}`) : null,
6647
- reviewing ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6992
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
6993
+ notice ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "b316-card b316-notice", role: "status", children: notice }) : null,
6994
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(SubscriptionManager, { onChange: refresh }, `plan-${version}`),
6995
+ canChange ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(UpcomingInvoice, {}, `next-${version}`) : null,
6996
+ canChange && quantityPriced ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(SeatManager, { unitLabel, onChange: refresh }, `seats-${version}`) : null,
6997
+ reviewing ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
6648
6998
  PlanChangeReview,
6649
6999
  {
6650
7000
  planVersionId: reviewing,
@@ -6657,9 +7007,9 @@ function BillingPortal({
6657
7007
  );
6658
7008
  }
6659
7009
  }
6660
- ) : /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("section", { children: [
6661
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("h2", { className: "b316-billing-portal-section-title", children: subscription ? "Change plan" : "Choose a plan" }),
6662
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7010
+ ) : /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("section", { children: [
7011
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("h2", { className: "b316-billing-portal-section-title", children: subscription ? "Change plan" : "Choose a plan" }),
7012
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
6663
7013
  PricingTable,
6664
7014
  {
6665
7015
  featuredPlanKey,
@@ -6671,17 +7021,17 @@ function BillingPortal({
6671
7021
  `plans-${version}`
6672
7022
  )
6673
7023
  ] }),
6674
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(CreditBalances, {}, `credits-${version}`),
6675
- managedBy ? null : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PaymentMethod, { returnUrl }, `card-${version}`),
6676
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Invoices, {}, `invoices-${version}`),
6677
- billingDetails === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(BillingDetailsForm, {}, `details-${version}`) : billingDetails
7024
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(CreditBalances, {}, `credits-${version}`),
7025
+ managedBy ? null : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(PaymentMethod, { returnUrl }, `card-${version}`),
7026
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Invoices, {}, `invoices-${version}`),
7027
+ billingDetails === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(BillingDetailsForm, {}, `details-${version}`) : billingDetails
6678
7028
  ] })
6679
7029
  );
6680
7030
  }
6681
7031
 
6682
7032
  // src/ApiKeyManager.tsx
6683
- var import_react37 = require("react");
6684
- var import_jsx_runtime37 = require("react/jsx-runtime");
7033
+ var import_react38 = require("react");
7034
+ var import_jsx_runtime39 = require("react/jsx-runtime");
6685
7035
  function duration(seconds) {
6686
7036
  if (seconds % 3600 === 0) {
6687
7037
  return `${seconds / 3600}h`;
@@ -6698,17 +7048,17 @@ function ApiKeyManager({
6698
7048
  audience
6699
7049
  }) {
6700
7050
  const { client, token, loading: sessionLoading } = useBase316();
6701
- const [resources, setResources] = (0, import_react37.useState)([]);
6702
- const [credentials, setCredentials] = (0, import_react37.useState)([]);
6703
- const [loading, setLoading] = (0, import_react37.useState)(true);
6704
- const [busy, setBusy] = (0, import_react37.useState)(false);
6705
- const [error, setError] = (0, import_react37.useState)(null);
6706
- const [creating, setCreating] = (0, import_react37.useState)(false);
6707
- const [name, setName] = (0, import_react37.useState)("");
6708
- const [chosen, setChosen] = (0, import_react37.useState)([]);
6709
- const [resourceId, setResourceId] = (0, import_react37.useState)(null);
6710
- const [issued, setIssued] = (0, import_react37.useState)(null);
6711
- const load = (0, import_react37.useCallback)(async () => {
7051
+ const [resources, setResources] = (0, import_react38.useState)([]);
7052
+ const [credentials, setCredentials] = (0, import_react38.useState)([]);
7053
+ const [loading, setLoading] = (0, import_react38.useState)(true);
7054
+ const [busy, setBusy] = (0, import_react38.useState)(false);
7055
+ const [error, setError] = (0, import_react38.useState)(null);
7056
+ const [creating, setCreating] = (0, import_react38.useState)(false);
7057
+ const [name, setName] = (0, import_react38.useState)("");
7058
+ const [chosen, setChosen] = (0, import_react38.useState)([]);
7059
+ const [resourceId, setResourceId] = (0, import_react38.useState)(null);
7060
+ const [issued, setIssued] = (0, import_react38.useState)(null);
7061
+ const load = (0, import_react38.useCallback)(async () => {
6712
7062
  if (!token) {
6713
7063
  setLoading(false);
6714
7064
  return;
@@ -6729,20 +7079,20 @@ function ApiKeyManager({
6729
7079
  setLoading(false);
6730
7080
  }
6731
7081
  }, [client, token, audience]);
6732
- (0, import_react37.useEffect)(() => {
7082
+ (0, import_react38.useEffect)(() => {
6733
7083
  void load();
6734
7084
  }, [load]);
6735
7085
  if (sessionLoading || loading) {
6736
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
7086
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
6737
7087
  }
6738
7088
  if (!token) {
6739
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cls("b316-card", className), style, children: "Sign in to manage your API keys." });
7089
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cls("b316-card", className), style, children: "Sign in to manage your API keys." });
6740
7090
  }
6741
7091
  if (error) {
6742
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
7092
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
6743
7093
  }
6744
7094
  if (resources.length === 0) {
6745
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cls("b316-card", className), style, children: "There are no APIs available to your account." });
7095
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cls("b316-card", className), style, children: "There are no APIs available to your account." });
6746
7096
  }
6747
7097
  const resource = resources.find((item) => item.id === resourceId) ?? resources[0];
6748
7098
  const reset = () => {
@@ -6751,37 +7101,37 @@ function ApiKeyManager({
6751
7101
  setChosen([]);
6752
7102
  setIssued(null);
6753
7103
  };
6754
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: cls("b316-card", className), style, children: [
6755
- error ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6756
- resources.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7104
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: cls("b316-card", className), style, children: [
7105
+ error ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
7106
+ resources.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6757
7107
  "select",
6758
7108
  {
6759
7109
  className: "b316-input",
6760
7110
  value: resource.id,
6761
7111
  onChange: (event) => setResourceId(event.target.value),
6762
7112
  style: { marginBottom: 14 },
6763
- children: resources.map((item) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("option", { value: item.id, children: item.name }, item.id))
7113
+ children: resources.map((item) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("option", { value: item.id, children: item.name }, item.id))
6764
7114
  }
6765
- ) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-plan-name", children: resource.name }),
6766
- resource.rateLimit ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-muted", children: [
7115
+ ) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-plan-name", children: resource.name }),
7116
+ resource.rateLimit ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "b316-muted", children: [
6767
7117
  resource.rateLimit.requestsPerWindow,
6768
7118
  " requests per",
6769
7119
  " ",
6770
7120
  duration(resource.rateLimit.windowSeconds),
6771
7121
  resource.rateLimit.burst > resource.rateLimit.requestsPerWindow ? `, bursting to ${resource.rateLimit.burst}` : null
6772
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-muted", children: "No rate limit." }),
6773
- credentials.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "b316-muted", style: { marginTop: 14 }, children: "You have no API keys yet." }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("ul", { className: "b316-list", style: { marginTop: 14 }, children: credentials.map((credential) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("li", { className: "b316-list-item", children: [
6774
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { children: [
6775
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-plan-name", children: credential.name }),
6776
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-muted", children: [
6777
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("code", { children: credential.clientId }),
7122
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-muted", children: "No rate limit." }),
7123
+ credentials.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "b316-muted", style: { marginTop: 14 }, children: "You have no API keys yet." }) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("ul", { className: "b316-list", style: { marginTop: 14 }, children: credentials.map((credential) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("li", { className: "b316-list-item", children: [
7124
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { children: [
7125
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-plan-name", children: credential.name }),
7126
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "b316-muted", children: [
7127
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("code", { children: credential.clientId }),
6778
7128
  credential.secretLastFour ? ` \xB7 \u2026${credential.secretLastFour}` : null,
6779
7129
  credential.disabled ? " \xB7 Disabled" : null
6780
7130
  ] }),
6781
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-muted", children: credential.scopes.join(", ") })
7131
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "b316-muted", children: credential.scopes.join(", ") })
6782
7132
  ] }),
6783
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { style: { display: "flex", gap: 8 }, children: [
6784
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7133
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { style: { display: "flex", gap: 8 }, children: [
7134
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6785
7135
  "button",
6786
7136
  {
6787
7137
  type: "button",
@@ -6810,7 +7160,7 @@ function ApiKeyManager({
6810
7160
  children: "Rotate"
6811
7161
  }
6812
7162
  ),
6813
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7163
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6814
7164
  ConfirmButton,
6815
7165
  {
6816
7166
  className: "b316-button b316-button-secondary",
@@ -6834,11 +7184,11 @@ function ApiKeyManager({
6834
7184
  )
6835
7185
  ] })
6836
7186
  ] }, credential.clientId)) }),
6837
- issued ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-notice", style: { marginTop: 14 }, children: [
6838
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("strong", { children: "Copy this now." }),
7187
+ issued ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "b316-notice", style: { marginTop: 14 }, children: [
7188
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("strong", { children: "Copy this now." }),
6839
7189
  " It is shown once and cannot be retrieved again.",
6840
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { style: { marginTop: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("code", { style: { wordBreak: "break-all" }, children: issued.secret }) }),
6841
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7190
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { style: { marginTop: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("code", { style: { wordBreak: "break-all" }, children: issued.secret }) }),
7191
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6842
7192
  "button",
6843
7193
  {
6844
7194
  type: "button",
@@ -6851,7 +7201,7 @@ function ApiKeyManager({
6851
7201
  children: "Copy"
6852
7202
  }
6853
7203
  ),
6854
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7204
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6855
7205
  "button",
6856
7206
  {
6857
7207
  type: "button",
@@ -6862,8 +7212,8 @@ function ApiKeyManager({
6862
7212
  }
6863
7213
  )
6864
7214
  ] }) : null,
6865
- creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { style: { marginTop: 14 }, children: [
6866
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7215
+ creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { style: { marginTop: 14 }, children: [
7216
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6867
7217
  "input",
6868
7218
  {
6869
7219
  className: "b316-input",
@@ -6872,9 +7222,9 @@ function ApiKeyManager({
6872
7222
  onChange: (event) => setName(event.target.value)
6873
7223
  }
6874
7224
  ),
6875
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { style: { marginTop: 10 }, children: [
6876
- resource.availableScopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("label", { className: "b316-checkbox", children: [
6877
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7225
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { style: { marginTop: 10 }, children: [
7226
+ resource.availableScopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("label", { className: "b316-checkbox", children: [
7227
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6878
7228
  "input",
6879
7229
  {
6880
7230
  type: "checkbox",
@@ -6884,19 +7234,19 @@ function ApiKeyManager({
6884
7234
  )
6885
7235
  }
6886
7236
  ),
6887
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("code", { children: scope.key }),
6888
- scope.description ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "b316-muted", children: [
7237
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("code", { children: scope.key }),
7238
+ scope.description ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "b316-muted", children: [
6889
7239
  " \u2014 ",
6890
7240
  scope.description
6891
7241
  ] }) : null
6892
7242
  ] }, scope.key)),
6893
- resource.lockedScopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("label", { className: "b316-checkbox b316-muted", children: [
6894
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("input", { type: "checkbox", disabled: true }),
6895
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("code", { children: scope.key }),
6896
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { children: " \u2014 not included in your plan" })
7243
+ resource.lockedScopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("label", { className: "b316-checkbox b316-muted", children: [
7244
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("input", { type: "checkbox", disabled: true }),
7245
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("code", { children: scope.key }),
7246
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { children: " \u2014 not included in your plan" })
6897
7247
  ] }, scope.key))
6898
7248
  ] }),
6899
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7249
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6900
7250
  "button",
6901
7251
  {
6902
7252
  type: "button",
@@ -6930,7 +7280,7 @@ function ApiKeyManager({
6930
7280
  children: "Create key"
6931
7281
  }
6932
7282
  ),
6933
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7283
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6934
7284
  "button",
6935
7285
  {
6936
7286
  type: "button",
@@ -6941,7 +7291,7 @@ function ApiKeyManager({
6941
7291
  }
6942
7292
  )
6943
7293
  ] }) : null,
6944
- !creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7294
+ !creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6945
7295
  "button",
6946
7296
  {
6947
7297
  type: "button",
@@ -7016,26 +7366,45 @@ var MANIFEST = [
7016
7366
  {
7017
7367
  name: "SignIn",
7018
7368
  kind: "component",
7019
- summary: "Password, passkey, magic-link and text-message sign-in in one form.",
7369
+ summary: "Sign in the ways the environment offers \u2014 password, magic link, passkeys, text message, social providers and SSO, as switched on in the dashboard (`GET /v1/auth/methods`).",
7020
7370
  useWhen: "The application renders its own sign-in rather than redirecting to the hosted page.",
7021
7371
  requires: [],
7022
7372
  props: [
7023
7373
  { name: "onSignedIn", summary: "Called once a session exists.", required: false },
7374
+ {
7375
+ name: "password",
7376
+ summary: "`false` hides the password form. Every method prop can only turn a method off.",
7377
+ required: false
7378
+ },
7024
7379
  {
7025
7380
  name: "passkeys",
7026
- summary: "Offer passkeys where supported. On by default.",
7381
+ summary: "`false` hides passkeys; otherwise offered where the environment and browser allow.",
7027
7382
  required: false
7028
7383
  },
7384
+ { name: "magicLink", summary: "`false` hides the emailed sign-in link.", required: false },
7029
7385
  {
7030
7386
  name: "magicLinkRedirectUrl",
7031
- summary: "Where an emailed link lands, which must be registered on the environment. Without it, magic link is not offered at all.",
7387
+ summary: "Where an emailed link lands; defaults to the page rendering the form, which redeems `?token=`. Must be on the environment's redirect allow-list.",
7388
+ required: false
7389
+ },
7390
+ { name: "phone", summary: "`false` hides text-message codes.", required: false },
7391
+ {
7392
+ name: "social",
7393
+ summary: "`false` hides the social buttons; a list of slugs keeps only those providers.",
7394
+ required: false
7395
+ },
7396
+ { name: "sso", summary: '`false` hides "Sign in with SSO".', required: false },
7397
+ {
7398
+ name: "socialRedirectUrl",
7399
+ summary: "Your server route a social or SSO sign-in returns to with `?code=&state=`: check `state` against the `b316_oauth_state` cookie (`readOAuthState`), then `base316.auth.exchangeCode` with the secret key. On the redirect allow-list. Without it no social or SSO button is shown.",
7032
7400
  required: false
7033
7401
  },
7034
7402
  {
7035
- name: "phone",
7036
- summary: "Offer signing in with a code sent by text message. Needs text messages switched on for the environment, and its own Twilio account in production.",
7403
+ name: "socialState",
7404
+ summary: "A short value carried through a social or SSO sign-in, returned by `readOAuthState`.",
7037
7405
  required: false
7038
7406
  },
7407
+ { name: "labels", summary: "Wording for the form, for translation.", required: false },
7039
7408
  {
7040
7409
  name: "secondFactorLabels",
7041
7410
  summary: "Wording for the second-factor step (code box, or enrolment when the environment requires a factor and the user has none), for translation. English when omitted.",
@@ -7045,6 +7414,38 @@ var MANIFEST = [
7045
7414
  ],
7046
7415
  seeAlso: ["SignUp", "ForgotPassword", "SecondFactorStep"]
7047
7416
  },
7417
+ {
7418
+ name: "SocialSignIn",
7419
+ kind: "component",
7420
+ summary: `The environment's social sign-in buttons alone ("Continue with Google"), for a sign-in or sign-up form you draw yourself.`,
7421
+ useWhen: "Your own form needs the social providers switched on in the dashboard. SignIn and SignUp already include them.",
7422
+ requires: [],
7423
+ props: [
7424
+ {
7425
+ name: "socialRedirectUrl",
7426
+ summary: "Your server route the code lands on with `?code=&state=`; check with `readOAuthState`, redeem with `exchangeCode`. On the redirect allow-list. Without it nothing is drawn.",
7427
+ required: false
7428
+ },
7429
+ {
7430
+ name: "socialState",
7431
+ summary: "A short value carried through, returned by `readOAuthState`.",
7432
+ required: false
7433
+ },
7434
+ {
7435
+ name: "social",
7436
+ summary: "`false` hides every button; a list of slugs keeps only those providers.",
7437
+ required: false
7438
+ },
7439
+ {
7440
+ name: "intent",
7441
+ summary: "`sign-up` hides the buttons when the environment is closed to new accounts.",
7442
+ required: false
7443
+ },
7444
+ { name: "divider", summary: 'Draw an "or" rule under the buttons.', required: false },
7445
+ { name: "labels", summary: "`continueWith` and `or`, for translation.", required: false }
7446
+ ],
7447
+ seeAlso: ["SignIn", "SignUp"]
7448
+ },
7048
7449
  {
7049
7450
  name: "SignUp",
7050
7451
  kind: "component",
@@ -7073,6 +7474,21 @@ var MANIFEST = [
7073
7474
  summary: "Wording for the second-factor step, for translation.",
7074
7475
  required: false
7075
7476
  },
7477
+ {
7478
+ name: "social",
7479
+ summary: "`false` hides the social buttons; a list of slugs keeps only those providers.",
7480
+ required: false
7481
+ },
7482
+ {
7483
+ name: "socialRedirectUrl",
7484
+ summary: "Where a social sign-up returns with `?code=&state=`, as on SignIn. Without it no social button is shown.",
7485
+ required: false
7486
+ },
7487
+ {
7488
+ name: "socialState",
7489
+ summary: "A short value carried through a social sign-up, returned by `readOAuthState`.",
7490
+ required: false
7491
+ },
7076
7492
  ...appearance
7077
7493
  ],
7078
7494
  seeAlso: ["SignIn", "VerifyEmail", "SecondFactorStep"]
@@ -7845,6 +8261,7 @@ function componentsRequiring(requirement) {
7845
8261
  SecondFactorStep,
7846
8262
  SignIn,
7847
8263
  SignUp,
8264
+ SocialSignIn,
7848
8265
  SubscriptionManager,
7849
8266
  TeamMembers,
7850
8267
  TwoFactorManager,