@base316/react 0.6.0 → 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; }
@@ -1673,8 +1691,8 @@ function BillingDetailsForm({
1673
1691
  }
1674
1692
 
1675
1693
  // src/SignIn.tsx
1676
- var import_sdk3 = require("@base316/sdk");
1677
- var import_react7 = require("react");
1694
+ var import_sdk4 = require("@base316/sdk");
1695
+ var import_react8 = require("react");
1678
1696
 
1679
1697
  // src/SecondFactorStep.tsx
1680
1698
  var import_sdk2 = require("@base316/sdk");
@@ -2063,33 +2081,230 @@ function SecondFactorStep({
2063
2081
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: cls("b316-mfa", className), style, children: body });
2064
2082
  }
2065
2083
 
2066
- // 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
2067
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
+ };
2068
2249
  function SignIn({
2069
2250
  onSignedIn,
2070
- passkeys = true,
2251
+ password: passwordProp,
2252
+ passkeys: passkeysProp,
2253
+ magicLink: magicLinkProp,
2071
2254
  magicLinkRedirectUrl,
2072
- phone = false,
2255
+ phone: phoneProp,
2256
+ social: socialProp,
2257
+ sso: ssoProp,
2258
+ socialRedirectUrl,
2259
+ socialState,
2260
+ labels: overrides,
2073
2261
  secondFactorLabels,
2074
2262
  className,
2075
2263
  style
2076
2264
  }) {
2265
+ const labels = { ...DEFAULT_SIGN_IN_LABELS, ...overrides };
2077
2266
  const { client, setToken } = useBase316();
2078
- const [email, setEmail] = (0, import_react7.useState)("");
2079
- const [password, setPassword] = (0, import_react7.useState)("");
2080
- const [code, setCode] = (0, import_react7.useState)("");
2081
- 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);
2082
2273
  const pendingChallenge = pending?.challengeToken ?? null;
2083
- const [phoneNumber, setPhoneNumber] = (0, import_react7.useState)("");
2084
- const [phoneChallenge, setPhoneChallenge] = (0, import_react7.useState)(
2274
+ const [phoneNumber, setPhoneNumber] = (0, import_react8.useState)("");
2275
+ const [phoneChallenge, setPhoneChallenge] = (0, import_react8.useState)(
2085
2276
  null
2086
2277
  );
2087
- const [error, setError] = (0, import_react7.useState)(null);
2088
- const [busy, setBusy] = (0, import_react7.useState)(false);
2089
- const [passkeyReady, setPasskeyReady] = (0, import_react7.useState)(false);
2090
- const [mode, setMode] = (0, import_react7.useState)("password");
2091
- const [linkSent, setLinkSent] = (0, import_react7.useState)(false);
2092
- 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;
2093
2308
  const signInWithPasskey = async (conditional, signal) => {
2094
2309
  if (!conditional) {
2095
2310
  setBusy(true);
@@ -2103,11 +2318,11 @@ function SignIn({
2103
2318
  if (cause instanceof DOMException && (cause.name === "NotAllowedError" || cause.name === "AbortError")) {
2104
2319
  return;
2105
2320
  }
2106
- if (cause instanceof import_sdk3.Base316Error && cause.reason === "EMAIL_NOT_VERIFIED") {
2321
+ if (cause instanceof import_sdk4.Base316Error && cause.reason === "EMAIL_NOT_VERIFIED") {
2107
2322
  setError(cause.message);
2108
2323
  } else if (!conditional) {
2109
2324
  console.error("[base316] passkey sign-in failed", cause);
2110
- setError("That passkey did not work.");
2325
+ setError(labels.passkeyFailed);
2111
2326
  }
2112
2327
  } finally {
2113
2328
  if (!conditional) {
@@ -2115,14 +2330,15 @@ function SignIn({
2115
2330
  }
2116
2331
  }
2117
2332
  };
2118
- (0, import_react7.useEffect)(() => {
2119
- if (!passkeys || !(0, import_sdk3.isPasskeySupported)() || pendingChallenge) {
2333
+ (0, import_react8.useEffect)(() => {
2334
+ if (!passkeysWanted || !(0, import_sdk4.isPasskeySupported)() || pendingChallenge) {
2335
+ setPasskeyReady(false);
2120
2336
  return;
2121
2337
  }
2122
2338
  setPasskeyReady(true);
2123
2339
  const controller = new AbortController();
2124
2340
  abortRef.current = controller;
2125
- void (0, import_sdk3.isPasskeyAutofillAvailable)().then((available) => {
2341
+ void (0, import_sdk4.isPasskeyAutofillAvailable)().then((available) => {
2126
2342
  if (available && !controller.signal.aborted) {
2127
2343
  void signInWithPasskey(true, controller.signal);
2128
2344
  }
@@ -2130,8 +2346,8 @@ function SignIn({
2130
2346
  return () => {
2131
2347
  controller.abort();
2132
2348
  };
2133
- }, [passkeys, pendingChallenge]);
2134
- (0, import_react7.useEffect)(() => {
2349
+ }, [passkeysWanted, pendingChallenge]);
2350
+ (0, import_react8.useEffect)(() => {
2135
2351
  if (typeof window === "undefined") {
2136
2352
  return;
2137
2353
  }
@@ -2147,7 +2363,7 @@ function SignIn({
2147
2363
  if (cancelled) {
2148
2364
  return;
2149
2365
  }
2150
- if ((0, import_sdk3.needsSecondFactor)(result)) {
2366
+ if ((0, import_sdk4.needsSecondFactor)(result)) {
2151
2367
  setPending(result);
2152
2368
  return;
2153
2369
  }
@@ -2155,7 +2371,7 @@ function SignIn({
2155
2371
  onSignedIn?.();
2156
2372
  }).catch(() => {
2157
2373
  if (!cancelled) {
2158
- setError("That sign-in link is no longer valid. Ask for a new one.");
2374
+ setError(labels.linkInvalid);
2159
2375
  }
2160
2376
  });
2161
2377
  return () => {
@@ -2163,23 +2379,44 @@ function SignIn({
2163
2379
  };
2164
2380
  }, []);
2165
2381
  async function sendLink() {
2166
- if (!magicLinkRedirectUrl) {
2382
+ if (!offered.magicLink) {
2167
2383
  return;
2168
2384
  }
2169
2385
  setBusy(true);
2170
2386
  setError(null);
2171
2387
  try {
2172
- await client.auth.magicLink.request({ email, redirectUrl: magicLinkRedirectUrl });
2388
+ await client.auth.magicLink.request({ email, redirectUrl: offered.magicLink });
2173
2389
  setLinkSent(true);
2174
2390
  } catch (cause) {
2175
2391
  console.error("[base316] magic link request failed", cause);
2176
- 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
+ );
2177
2395
  } finally {
2178
2396
  setBusy(false);
2179
2397
  }
2180
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
+ }
2181
2414
  async function submit(event) {
2182
2415
  event.preventDefault();
2416
+ if (mode === "sso") {
2417
+ leaveForSso();
2418
+ return;
2419
+ }
2183
2420
  setBusy(true);
2184
2421
  setError(null);
2185
2422
  try {
@@ -2197,7 +2434,7 @@ function SignIn({
2197
2434
  challengeToken: phoneChallenge.token,
2198
2435
  code
2199
2436
  });
2200
- if ((0, import_sdk3.needsSecondFactor)(signedIn)) {
2437
+ if ((0, import_sdk4.needsSecondFactor)(signedIn)) {
2201
2438
  setPending(signedIn);
2202
2439
  setCode("");
2203
2440
  return;
@@ -2207,7 +2444,7 @@ function SignIn({
2207
2444
  return;
2208
2445
  }
2209
2446
  const result = await client.auth.signIn({ email, password });
2210
- if ((0, import_sdk3.needsSecondFactor)(result)) {
2447
+ if ((0, import_sdk4.needsSecondFactor)(result)) {
2211
2448
  setPending(result);
2212
2449
  return;
2213
2450
  }
@@ -2216,25 +2453,23 @@ function SignIn({
2216
2453
  } catch (cause) {
2217
2454
  console.error("[base316] sign-in failed", cause);
2218
2455
  setError(
2219
- mode === "phone" ? phoneChallenge ? "That code did not work. Check it, or ask for a new one." : (
2456
+ mode === "phone" ? phoneChallenge ? labels.wrongCode : (
2220
2457
  // Why a text could not be sent is worth saying — a number in the
2221
2458
  // wrong format, or too many requests — and the server words it
2222
2459
  // without saying anything about accounts.
2223
- 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
2224
2461
  ) : (
2225
2462
  // An unconfirmed address and a throttle are worth naming; the
2226
2463
  // server words both without saying whether an account exists.
2227
- 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
2228
2465
  )
2229
2466
  );
2230
2467
  } finally {
2231
2468
  setBusy(false);
2232
2469
  }
2233
2470
  }
2234
- const magicAvailable = Boolean(magicLinkRedirectUrl) && !pendingChallenge;
2235
- const tabsShown = (magicAvailable || phone) && !pendingChallenge;
2236
2471
  if (pending) {
2237
- 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)(
2238
2473
  SecondFactorStep,
2239
2474
  {
2240
2475
  pending,
@@ -2250,59 +2485,68 @@ function SignIn({
2250
2485
  ) });
2251
2486
  }
2252
2487
  if (linkSent) {
2253
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: cls("b316-card", className), style, children: [
2254
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { fontWeight: 600, marginBottom: 6 }, children: "Check your email" }),
2255
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "b316-muted", children: [
2256
- "If an account exists for ",
2257
- email,
2258
- ", a sign-in link is on its way. It expires shortly and can be used once."
2259
- ] }),
2260
- /* @__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)(
2261
2492
  "button",
2262
2493
  {
2263
2494
  type: "button",
2264
2495
  className: "b316-button b316-button-secondary",
2265
2496
  style: { marginTop: 16 },
2266
2497
  onClick: () => setLinkSent(false),
2267
- children: "Back to sign in"
2498
+ children: labels.backToSignIn
2268
2499
  }
2269
2500
  )
2270
2501
  ] });
2271
2502
  }
2272
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
2273
- error ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
2274
- tabsShown ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "b316-tabs", children: [
2275
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2276
- "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,
2277
2514
  {
2278
- type: "button",
2279
- className: cls("b316-tab", mode === "password" ? "b316-tab-on" : void 0),
2280
- onClick: () => setMode("password"),
2281
- 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
+ }
2282
2533
  }
2283
2534
  ),
2284
- magicAvailable ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2285
- "button",
2286
- {
2287
- type: "button",
2288
- className: cls("b316-tab", mode === "magic" ? "b316-tab-on" : void 0),
2289
- onClick: () => setMode("magic"),
2290
- children: "Magic link"
2291
- }
2292
- ) : null,
2293
- phone ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2294
- "button",
2295
- {
2296
- type: "button",
2297
- className: cls("b316-tab", mode === "phone" ? "b316-tab-on" : void 0),
2298
- onClick: () => setMode("phone"),
2299
- children: "Text message"
2300
- }
2301
- ) : null
2535
+ hasForm ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "b316-divider", children: labels.or }) : null
2302
2536
  ] }) : null,
2303
- mode === "phone" ? phoneChallenge ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "b316-field", children: [
2304
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "b316-label", htmlFor: "b316-phone-code", children: "Code" }),
2305
- /* @__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)(
2306
2550
  "input",
2307
2551
  {
2308
2552
  id: "b316-phone-code",
@@ -2314,12 +2558,10 @@ function SignIn({
2314
2558
  required: true
2315
2559
  }
2316
2560
  ),
2317
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "b316-muted", children: [
2318
- "We sent a code to ",
2319
- phoneChallenge.hint,
2320
- ". It expires in ten minutes.",
2561
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "b316-muted", children: [
2562
+ labels.codeSent(phoneChallenge.hint),
2321
2563
  " ",
2322
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2564
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2323
2565
  "button",
2324
2566
  {
2325
2567
  type: "button",
@@ -2328,13 +2570,13 @@ function SignIn({
2328
2570
  setPhoneChallenge(null);
2329
2571
  setCode("");
2330
2572
  },
2331
- children: "Use a different number"
2573
+ children: labels.useDifferentNumber
2332
2574
  }
2333
2575
  )
2334
2576
  ] })
2335
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "b316-field", children: [
2336
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "b316-label", htmlFor: "b316-phone", children: "Mobile number" }),
2337
- /* @__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)(
2338
2580
  "input",
2339
2581
  {
2340
2582
  id: "b316-phone",
@@ -2347,11 +2589,11 @@ function SignIn({
2347
2589
  required: true
2348
2590
  }
2349
2591
  ),
2350
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "b316-muted", children: "Include the country code." })
2351
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
2352
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "b316-field", children: [
2353
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "b316-label", htmlFor: "b316-email", children: "Email" }),
2354
- /* @__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)(
2355
2597
  "input",
2356
2598
  {
2357
2599
  id: "b316-email",
@@ -2359,14 +2601,14 @@ function SignIn({
2359
2601
  type: "email",
2360
2602
  value: email,
2361
2603
  onChange: (event) => setEmail(event.target.value),
2362
- autoComplete: passkeyReady ? "email webauthn" : "email",
2604
+ autoComplete: passkeyReady && mode !== "sso" ? "email webauthn" : "email",
2363
2605
  required: true
2364
2606
  }
2365
2607
  )
2366
2608
  ] }),
2367
- mode === "password" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "b316-field", children: [
2368
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("label", { className: "b316-label", htmlFor: "b316-password", children: "Password" }),
2369
- /* @__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)(
2370
2612
  "input",
2371
2613
  {
2372
2614
  id: "b316-password",
@@ -2379,31 +2621,98 @@ function SignIn({
2379
2621
  }
2380
2622
  )
2381
2623
  ] }) : null
2382
- ] }),
2383
- /* @__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" }),
2384
- passkeyReady && !pendingChallenge ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
2385
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "b316-muted", style: { textAlign: "center", margin: "10px 0" }, children: "or" }),
2386
- /* @__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)(
2387
2640
  "button",
2388
2641
  {
2389
2642
  type: "button",
2390
2643
  className: "b316-button b316-button-secondary",
2644
+ style: { width: "100%" },
2391
2645
  disabled: busy,
2392
2646
  onClick: () => {
2393
2647
  abortRef.current?.abort();
2394
2648
  void signInWithPasskey(false);
2395
2649
  },
2396
- children: "Sign in with a passkey"
2650
+ children: labels.passkey
2397
2651
  }
2398
- )
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
2399
2668
  ] }) : null
2400
2669
  ] });
2401
2670
  }
2402
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
+
2403
2712
  // src/SignUp.tsx
2404
- var import_sdk4 = require("@base316/sdk");
2405
- var import_react8 = require("react");
2406
- 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");
2407
2716
  var DEFAULT_SIGN_UP_LABELS = {
2408
2717
  name: "Name",
2409
2718
  email: "Email",
@@ -2420,7 +2729,10 @@ var DEFAULT_SIGN_UP_LABELS = {
2420
2729
  confirmEmail: (email) => `Your account is ready. We sent a confirmation link to ${email} \u2014 open it, then sign in.`,
2421
2730
  createdSignInFailed: (reason) => `Your account was created, but we could not sign you in: ${reason}`,
2422
2731
  genericError: "We could not create that account. Try again.",
2423
- 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."
2424
2736
  };
2425
2737
  function describeRules(policy, labels) {
2426
2738
  const extras = [
@@ -2439,30 +2751,35 @@ function SignUp({
2439
2751
  onJoined,
2440
2752
  labels: overrides,
2441
2753
  secondFactorLabels,
2754
+ social,
2755
+ socialRedirectUrl,
2756
+ socialState,
2442
2757
  className,
2443
2758
  style
2444
2759
  }) {
2445
2760
  const labels = { ...DEFAULT_SIGN_UP_LABELS, ...overrides };
2446
2761
  const { client, setToken } = useBase316();
2447
- const [name, setName] = (0, import_react8.useState)("");
2448
- const [email, setEmail] = (0, import_react8.useState)("");
2449
- const [password, setPassword] = (0, import_react8.useState)("");
2450
- const [error, setError] = (0, import_react8.useState)(null);
2451
- const [busy, setBusy] = (0, import_react8.useState)(false);
2452
- const [policy, setPolicy] = (0, import_react8.useState)(null);
2453
- const [pending, setPending] = (0, import_react8.useState)(null);
2454
- const [confirmEmail, setConfirmEmail] = (0, import_react8.useState)(false);
2455
- const [urlInvitation, setUrlInvitation] = (0, import_react8.useState)(null);
2456
- 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);
2457
2774
  const invitation = suppliedInvitation === void 0 ? urlInvitation : suppliedInvitation;
2458
2775
  const preview = loaded && loaded.token === invitation ? loaded.preview : null;
2459
- (0, import_react8.useEffect)(() => {
2776
+ (0, import_react9.useEffect)(() => {
2460
2777
  if (suppliedInvitation !== void 0 || typeof window === "undefined") {
2461
2778
  return;
2462
2779
  }
2463
2780
  setUrlInvitation(new URL(window.location.href).searchParams.get("invitation"));
2464
2781
  }, [suppliedInvitation]);
2465
- (0, import_react8.useEffect)(() => {
2782
+ (0, import_react9.useEffect)(() => {
2466
2783
  if (!invitation) {
2467
2784
  return;
2468
2785
  }
@@ -2477,7 +2794,7 @@ function SignUp({
2477
2794
  cancelled = true;
2478
2795
  };
2479
2796
  }, [client, invitation]);
2480
- (0, import_react8.useEffect)(() => {
2797
+ (0, import_react9.useEffect)(() => {
2481
2798
  let cancelled = false;
2482
2799
  client.auth.passwordPolicy().then((loaded2) => {
2483
2800
  if (!cancelled) {
@@ -2505,14 +2822,14 @@ function SignUp({
2505
2822
  } catch (cause) {
2506
2823
  console.error("[base316] sign-up failed", cause);
2507
2824
  setError(
2508
- 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
2509
2826
  );
2510
2827
  setBusy(false);
2511
2828
  return;
2512
2829
  }
2513
2830
  try {
2514
2831
  const signedIn = await client.auth.signIn({ email, password });
2515
- if ((0, import_sdk4.needsSecondFactor)(signedIn)) {
2832
+ if ((0, import_sdk5.needsSecondFactor)(signedIn)) {
2516
2833
  setPending(signedIn);
2517
2834
  return;
2518
2835
  }
@@ -2520,14 +2837,14 @@ function SignUp({
2520
2837
  onSignedUp?.();
2521
2838
  } catch (cause) {
2522
2839
  console.error("[base316] sign-in after sign-up failed", cause);
2523
- if (cause instanceof import_sdk4.Base316Error && cause.reason === "EMAIL_NOT_VERIFIED") {
2840
+ if (cause instanceof import_sdk5.Base316Error && cause.reason === "EMAIL_NOT_VERIFIED") {
2524
2841
  setConfirmEmail(true);
2525
2842
  onSignedUp?.();
2526
2843
  return;
2527
2844
  }
2528
2845
  setError(
2529
2846
  labels.createdSignInFailed(
2530
- cause instanceof import_sdk4.Base316Error && cause.message ? cause.message : labels.genericError
2847
+ cause instanceof import_sdk5.Base316Error && cause.message ? cause.message : labels.genericError
2531
2848
  )
2532
2849
  );
2533
2850
  } finally {
@@ -2535,86 +2852,118 @@ function SignUp({
2535
2852
  }
2536
2853
  }
2537
2854
  if (pending) {
2538
- 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 }) });
2539
2856
  }
2540
2857
  if (confirmEmail) {
2541
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: cls("b316-card", className), style, children: [
2542
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h3", { className: "b316-form-title", children: labels.confirmEmailTitle }),
2543
- /* @__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) })
2544
2861
  ] });
2545
2862
  }
2546
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
2547
- preview ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "b316-muted", children: labels.joining(preview.organizationName, preview.roleName) }) : null,
2548
- error ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
2549
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "b316-field", children: [
2550
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "b316-label", htmlFor: "b316-name", children: labels.name }),
2551
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2552
- "input",
2553
- {
2554
- id: "b316-name",
2555
- className: "b316-input",
2556
- value: name,
2557
- onChange: (event) => setName(event.target.value),
2558
- autoComplete: "name"
2559
- }
2560
- )
2561
- ] }),
2562
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "b316-field", children: [
2563
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: "b316-label", htmlFor: "b316-signup-email", children: labels.email }),
2564
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2565
- "input",
2566
- {
2567
- id: "b316-signup-email",
2568
- className: "b316-input",
2569
- type: "email",
2570
- value: email,
2571
- onChange: (event) => setEmail(event.target.value),
2572
- autoComplete: "email",
2573
- required: true
2574
- }
2575
- )
2576
- ] }),
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-signup-password", children: labels.password }),
2579
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2580
- "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,
2581
2871
  {
2582
- id: "b316-signup-password",
2583
- className: "b316-input",
2584
- type: "password",
2585
- value: password,
2586
- onChange: (event) => setPassword(event.target.value),
2587
- autoComplete: "new-password",
2588
- minLength: policy?.minLength,
2589
- maxLength: policy?.maxLength,
2590
- "aria-describedby": policy ? "b316-signup-password-rules" : void 0,
2591
- 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
+ }
2592
2890
  }
2593
2891
  ),
2594
- policy ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { id: "b316-signup-password-rules", className: "b316-muted", children: describeRules(policy, labels) }) : null
2595
- ] }),
2596
- /* @__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
2597
2946
  ] });
2598
2947
  }
2599
2948
 
2600
2949
  // src/UserProfile.tsx
2601
- var import_jsx_runtime10 = require("react/jsx-runtime");
2950
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2602
2951
  function UserProfile({ className, style }) {
2603
2952
  const { session, loading, signOut } = useBase316();
2604
2953
  if (loading) {
2605
- 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" });
2606
2955
  }
2607
2956
  if (!session) {
2608
- 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." });
2609
2958
  }
2610
2959
  const user = session.user ?? {};
2611
- 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: [
2612
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
2613
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { fontWeight: 600 }, children: user.name || user.email || "Signed in" }),
2614
- user.name && user.email ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "b316-muted", children: user.email }) : null,
2615
- 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
2616
2965
  ] }),
2617
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2966
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2618
2967
  "button",
2619
2968
  {
2620
2969
  type: "button",
@@ -2627,12 +2976,12 @@ function UserProfile({ className, style }) {
2627
2976
  }
2628
2977
 
2629
2978
  // src/PasskeyManager.tsx
2630
- var import_sdk5 = require("@base316/sdk");
2631
- var import_react10 = require("react");
2979
+ var import_sdk6 = require("@base316/sdk");
2980
+ var import_react11 = require("react");
2632
2981
 
2633
2982
  // src/confirm.tsx
2634
- var import_react9 = require("react");
2635
- var import_jsx_runtime11 = require("react/jsx-runtime");
2983
+ var import_react10 = require("react");
2984
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2636
2985
  var DEFAULT_TIMEOUT_MS = 5e3;
2637
2986
  function ConfirmButton({
2638
2987
  children,
@@ -2642,9 +2991,9 @@ function ConfirmButton({
2642
2991
  disabled,
2643
2992
  timeoutMs = DEFAULT_TIMEOUT_MS
2644
2993
  }) {
2645
- const [armed, setArmed] = (0, import_react9.useState)(false);
2646
- const confirmRef = (0, import_react9.useRef)(null);
2647
- (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)(() => {
2648
2997
  if (!armed) {
2649
2998
  return;
2650
2999
  }
@@ -2653,7 +3002,7 @@ function ConfirmButton({
2653
3002
  return () => clearTimeout(timer);
2654
3003
  }, [armed, timeoutMs]);
2655
3004
  if (!armed) {
2656
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3005
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2657
3006
  "button",
2658
3007
  {
2659
3008
  type: "button",
@@ -2667,8 +3016,8 @@ function ConfirmButton({
2667
3016
  return (
2668
3017
  // No `role="group"`: both buttons already say what they do, and the
2669
3018
  // grouping would only repeat the question a screen reader has just read.
2670
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "b316-confirm", children: [
2671
- /* @__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)(
2672
3021
  "button",
2673
3022
  {
2674
3023
  ref: confirmRef,
@@ -2682,7 +3031,7 @@ function ConfirmButton({
2682
3031
  children: confirmLabel
2683
3032
  }
2684
3033
  ),
2685
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3034
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2686
3035
  "button",
2687
3036
  {
2688
3037
  type: "button",
@@ -2696,19 +3045,19 @@ function ConfirmButton({
2696
3045
  }
2697
3046
 
2698
3047
  // src/PasskeyManager.tsx
2699
- var import_jsx_runtime12 = require("react/jsx-runtime");
3048
+ var import_jsx_runtime14 = require("react/jsx-runtime");
2700
3049
  function PasskeyManager({
2701
3050
  className,
2702
3051
  style,
2703
3052
  title = "Passkeys"
2704
3053
  }) {
2705
3054
  const { client, token, session } = useBase316();
2706
- const [passkeys, setPasskeys] = (0, import_react10.useState)(null);
2707
- const [busy, setBusy] = (0, import_react10.useState)(false);
2708
- const [error, setError] = (0, import_react10.useState)(null);
2709
- const [name, setName] = (0, import_react10.useState)("");
2710
- const [supported, setSupported] = (0, import_react10.useState)(false);
2711
- 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 () => {
2712
3061
  if (!token) {
2713
3062
  return;
2714
3063
  }
@@ -2721,8 +3070,8 @@ function PasskeyManager({
2721
3070
  setPasskeys(null);
2722
3071
  }
2723
3072
  }, [client, token]);
2724
- (0, import_react10.useEffect)(() => {
2725
- if (!(0, import_sdk5.isPasskeySupported)()) {
3073
+ (0, import_react11.useEffect)(() => {
3074
+ if (!(0, import_sdk6.isPasskeySupported)()) {
2726
3075
  return;
2727
3076
  }
2728
3077
  setSupported(true);
@@ -2757,18 +3106,18 @@ function PasskeyManager({
2757
3106
  setError(caught instanceof Error ? caught.message : "That did not work.");
2758
3107
  }
2759
3108
  };
2760
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: cls("b316-card", className), style, children: [
2761
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: { fontWeight: 600, marginBottom: 4 }, children: title }),
2762
- /* @__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." }),
2763
- 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: [
2764
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
2765
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { children: passkey.name || "Passkey" }),
2766
- /* @__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: [
2767
3116
  passkey.lastUsedAt ? `Last used ${formatDate(passkey.lastUsedAt)}` : `Added ${formatDate(passkey.createdAt)}`,
2768
3117
  passkey.backedUp ? "" : " \xB7 this device only"
2769
3118
  ] })
2770
3119
  ] }),
2771
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
3120
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2772
3121
  ConfirmButton,
2773
3122
  {
2774
3123
  className: "b316-button b316-button-secondary",
@@ -2778,9 +3127,9 @@ function PasskeyManager({
2778
3127
  }
2779
3128
  )
2780
3129
  ] }, passkey.id)) }),
2781
- error ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "b316-error", role: "alert", style: { marginTop: 12 }, children: error }) : null,
2782
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "b316-row", style: { marginTop: 12, gap: 8 }, children: [
2783
- /* @__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)(
2784
3133
  "input",
2785
3134
  {
2786
3135
  className: "b316-input",
@@ -2789,7 +3138,7 @@ function PasskeyManager({
2789
3138
  onChange: (event) => setName(event.target.value)
2790
3139
  }
2791
3140
  ),
2792
- /* @__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" })
2793
3142
  ] })
2794
3143
  ] });
2795
3144
  }
@@ -2799,8 +3148,8 @@ function formatDate(value) {
2799
3148
  }
2800
3149
 
2801
3150
  // src/ActiveSessions.tsx
2802
- var import_react11 = require("react");
2803
- var import_jsx_runtime13 = require("react/jsx-runtime");
3151
+ var import_react12 = require("react");
3152
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2804
3153
  function describeDevice(userAgent) {
2805
3154
  if (!userAgent) {
2806
3155
  return null;
@@ -2818,10 +3167,10 @@ function when(value) {
2818
3167
  }
2819
3168
  function ActiveSessions({ onRevoked, className, style }) {
2820
3169
  const { client, token } = useBase316();
2821
- const [sessions, setSessions] = (0, import_react11.useState)(null);
2822
- const [error, setError] = (0, import_react11.useState)(null);
2823
- const [busy, setBusy] = (0, import_react11.useState)(false);
2824
- 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)(() => {
2825
3174
  if (!token) {
2826
3175
  return;
2827
3176
  }
@@ -2832,15 +3181,15 @@ function ActiveSessions({ onRevoked, className, style }) {
2832
3181
  setError(cause instanceof Error ? cause.message : "Could not load your sessions.");
2833
3182
  });
2834
3183
  }, [client, token]);
2835
- (0, import_react11.useEffect)(load, [load]);
3184
+ (0, import_react12.useEffect)(load, [load]);
2836
3185
  if (!token) {
2837
3186
  return null;
2838
3187
  }
2839
3188
  if (error) {
2840
- 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 }) });
2841
3190
  }
2842
3191
  if (!sessions) {
2843
- 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" });
2844
3193
  }
2845
3194
  async function revokeOthers() {
2846
3195
  setBusy(true);
@@ -2854,32 +3203,32 @@ function ActiveSessions({ onRevoked, className, style }) {
2854
3203
  setBusy(false);
2855
3204
  }
2856
3205
  }
2857
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: cls("b316-card b316-sessions", className), style, children: [
2858
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "b316-sessions-head", children: [
2859
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h3", { className: "b316-sessions-title", children: "Where you are signed in" }),
2860
- 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
2861
3210
  ] }),
2862
- /* @__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: [
2863
- /* @__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: [
2864
3213
  describeDevice(session.userAgent) ?? "Unknown device",
2865
3214
  session.impersonatedBy ? (
2866
3215
  // Worth saying loudly: somebody is acting as this account.
2867
- /* @__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" })
2868
3217
  ) : null
2869
3218
  ] }),
2870
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "b316-muted", children: [
3219
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-muted", children: [
2871
3220
  session.ipAddress ? `${session.ipAddress} \xB7 ` : "",
2872
3221
  "last used ",
2873
3222
  when(session.lastSeenAt)
2874
3223
  ] })
2875
3224
  ] }, session.id)) }),
2876
- 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
2877
3226
  ] });
2878
3227
  }
2879
3228
 
2880
3229
  // src/DeviceApproval.tsx
2881
- var import_react12 = require("react");
2882
- var import_jsx_runtime14 = require("react/jsx-runtime");
3230
+ var import_react13 = require("react");
3231
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2883
3232
  function DeviceApproval({
2884
3233
  userCode = "",
2885
3234
  onDecided,
@@ -2887,11 +3236,11 @@ function DeviceApproval({
2887
3236
  style
2888
3237
  }) {
2889
3238
  const { client, token } = useBase316();
2890
- const [code, setCode] = (0, import_react12.useState)(userCode);
2891
- const [request, setRequest] = (0, import_react12.useState)(null);
2892
- const [decided, setDecided] = (0, import_react12.useState)(null);
2893
- const [error, setError] = (0, import_react12.useState)(null);
2894
- 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);
2895
3244
  if (!token) {
2896
3245
  return null;
2897
3246
  }
@@ -2924,25 +3273,25 @@ function DeviceApproval({
2924
3273
  }
2925
3274
  }
2926
3275
  if (decided !== null) {
2927
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: cls("b316-card b316-device", className), style, children: [
2928
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: "b316-device-title", children: decided ? "You're all set" : "Not approved" }),
2929
- /* @__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." })
2930
3279
  ] });
2931
3280
  }
2932
3281
  if (request) {
2933
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: cls("b316-card b316-device", className), style, children: [
2934
- /* @__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: [
2935
3284
  "Sign in to ",
2936
3285
  request.clientName
2937
3286
  ] }),
2938
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { className: "b316-muted", children: [
3287
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("p", { className: "b316-muted", children: [
2939
3288
  request.clientName,
2940
3289
  " is asking to sign in as you."
2941
3290
  ] }),
2942
- 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,
2943
- error ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
2944
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "b316-device-actions", children: [
2945
- /* @__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)(
2946
3295
  "button",
2947
3296
  {
2948
3297
  type: "button",
@@ -2952,7 +3301,7 @@ function DeviceApproval({
2952
3301
  children: busy ? "Approving\u2026" : "Approve"
2953
3302
  }
2954
3303
  ),
2955
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3304
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2956
3305
  "button",
2957
3306
  {
2958
3307
  type: "button",
@@ -2965,11 +3314,11 @@ function DeviceApproval({
2965
3314
  ] })
2966
3315
  ] });
2967
3316
  }
2968
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("form", { className: cls("b316-card b316-device", className), style, onSubmit: lookUp, children: [
2969
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: "b316-device-title", children: "Connect your device" }),
2970
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "b316-muted", children: "Enter the code shown on your device." }),
2971
- error ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
2972
- /* @__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)(
2973
3322
  "input",
2974
3323
  {
2975
3324
  className: "b316-input",
@@ -2982,13 +3331,13 @@ function DeviceApproval({
2982
3331
  "aria-label": "Device code"
2983
3332
  }
2984
3333
  ),
2985
- /* @__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" })
2986
3335
  ] });
2987
3336
  }
2988
3337
 
2989
3338
  // src/PrivacyControls.tsx
2990
- var import_react13 = require("react");
2991
- var import_jsx_runtime15 = require("react/jsx-runtime");
3339
+ var import_react14 = require("react");
3340
+ var import_jsx_runtime17 = require("react/jsx-runtime");
2992
3341
  function PrivacyControls({
2993
3342
  confirmWord = "DELETE",
2994
3343
  onErased,
@@ -2996,10 +3345,10 @@ function PrivacyControls({
2996
3345
  style
2997
3346
  }) {
2998
3347
  const { client, token } = useBase316();
2999
- const [confirming, setConfirming] = (0, import_react13.useState)(false);
3000
- const [typed, setTyped] = (0, import_react13.useState)("");
3001
- const [error, setError] = (0, import_react13.useState)(null);
3002
- 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);
3003
3352
  if (!token) {
3004
3353
  return null;
3005
3354
  }
@@ -3034,22 +3383,22 @@ function PrivacyControls({
3034
3383
  setBusy(false);
3035
3384
  }
3036
3385
  }
3037
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: cls("b316-card b316-privacy", className), style, children: [
3038
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h3", { className: "b316-privacy-title", children: "Your data" }),
3039
- error ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3040
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-privacy-row", children: [
3041
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
3042
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { children: "Download a copy" }),
3043
- /* @__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." })
3044
3393
  ] }),
3045
- /* @__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" })
3046
3395
  ] }),
3047
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-privacy-row", children: [
3048
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
3049
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { children: "Delete your account" }),
3050
- /* @__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." })
3051
3400
  ] }),
3052
- confirming ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3401
+ confirming ? null : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3053
3402
  "button",
3054
3403
  {
3055
3404
  type: "button",
@@ -3060,13 +3409,13 @@ function PrivacyControls({
3060
3409
  }
3061
3410
  )
3062
3411
  ] }),
3063
- confirming ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-privacy-confirm", children: [
3064
- /* @__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: [
3065
3414
  "Type ",
3066
3415
  confirmWord,
3067
3416
  " to confirm"
3068
3417
  ] }),
3069
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3418
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3070
3419
  "input",
3071
3420
  {
3072
3421
  id: "b316-privacy-confirm",
@@ -3076,8 +3425,8 @@ function PrivacyControls({
3076
3425
  onChange: (event) => setTyped(event.target.value)
3077
3426
  }
3078
3427
  ),
3079
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "b316-privacy-actions", children: [
3080
- /* @__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)(
3081
3430
  "button",
3082
3431
  {
3083
3432
  type: "button",
@@ -3089,7 +3438,7 @@ function PrivacyControls({
3089
3438
  children: "Cancel"
3090
3439
  }
3091
3440
  ),
3092
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3441
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3093
3442
  "button",
3094
3443
  {
3095
3444
  type: "button",
@@ -3105,12 +3454,12 @@ function PrivacyControls({
3105
3454
  }
3106
3455
 
3107
3456
  // src/TwoFactorManager.tsx
3108
- var import_react15 = require("react");
3457
+ var import_react16 = require("react");
3109
3458
 
3110
3459
  // src/QrCode.tsx
3111
3460
  var import_qrcode_generator = __toESM(require("qrcode-generator"));
3112
- var import_react14 = require("react");
3113
- var import_jsx_runtime16 = require("react/jsx-runtime");
3461
+ var import_react15 = require("react");
3462
+ var import_jsx_runtime18 = require("react/jsx-runtime");
3114
3463
  var QUIET_ZONE = 4;
3115
3464
  function utf8Binary(value) {
3116
3465
  let binary = "";
@@ -3135,9 +3484,9 @@ function qrPath(value) {
3135
3484
  return { path, modules };
3136
3485
  }
3137
3486
  function QrCode({ value, label, size = 180, className }) {
3138
- const { path, modules } = (0, import_react14.useMemo)(() => qrPath(value), [value]);
3487
+ const { path, modules } = (0, import_react15.useMemo)(() => qrPath(value), [value]);
3139
3488
  const extent = modules + QUIET_ZONE * 2;
3140
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3489
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
3141
3490
  "svg",
3142
3491
  {
3143
3492
  className,
@@ -3149,15 +3498,15 @@ function QrCode({ value, label, size = 180, className }) {
3149
3498
  shapeRendering: "crispEdges",
3150
3499
  xmlns: "http://www.w3.org/2000/svg",
3151
3500
  children: [
3152
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("rect", { width: extent, height: extent, fill: "#ffffff" }),
3153
- /* @__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" })
3154
3503
  ]
3155
3504
  }
3156
3505
  );
3157
3506
  }
3158
3507
 
3159
3508
  // src/TwoFactorManager.tsx
3160
- var import_jsx_runtime17 = require("react/jsx-runtime");
3509
+ var import_jsx_runtime19 = require("react/jsx-runtime");
3161
3510
  function groupKey(secret) {
3162
3511
  return secret.replace(/\s+/g, "").replace(/(.{4})(?=.)/g, "$1 ");
3163
3512
  }
@@ -3170,12 +3519,12 @@ function TwoFactorManager({
3170
3519
  style
3171
3520
  }) {
3172
3521
  const { client, token } = useBase316();
3173
- const [stage, setStage] = (0, import_react15.useState)({ name: "idle" });
3174
- const [on, setOn] = (0, import_react15.useState)(enabled);
3175
- const [code, setCode] = (0, import_react15.useState)("");
3176
- const [phone, setPhone] = (0, import_react15.useState)("");
3177
- const [error, setError] = (0, import_react15.useState)(null);
3178
- 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);
3179
3528
  if (!token) {
3180
3529
  return null;
3181
3530
  }
@@ -3253,17 +3602,17 @@ function TwoFactorManager({
3253
3602
  setBusy(false);
3254
3603
  }
3255
3604
  }
3256
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: cls("b316-card b316-mfa", className), style, children: [
3257
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { className: "b316-mfa-title", children: "Two-factor authentication" }),
3258
- error ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3259
- stage.name === "saved" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-codes", children: [
3260
- /* @__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." }),
3261
- /* @__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)) }),
3262
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", className: "b316-button", onClick: () => setStage({ name: "idle" }), children: "I have saved them" })
3263
- ] }) : stage.name === "smsNumber" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-enrol", children: [
3264
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { children: "We will text a code to this number now, and each time you sign in." }),
3265
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-phone", children: "Mobile number" }),
3266
- /* @__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)(
3267
3616
  "input",
3268
3617
  {
3269
3618
  id: "b316-mfa-phone",
@@ -3275,8 +3624,8 @@ function TwoFactorManager({
3275
3624
  onChange: (event) => setPhone(event.target.value)
3276
3625
  }
3277
3626
  ),
3278
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-actions", children: [
3279
- /* @__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)(
3280
3629
  "button",
3281
3630
  {
3282
3631
  type: "button",
@@ -3285,16 +3634,16 @@ function TwoFactorManager({
3285
3634
  children: "Cancel"
3286
3635
  }
3287
3636
  ),
3288
- /* @__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" })
3289
3638
  ] })
3290
- ] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-enrol", children: [
3291
- /* @__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: [
3292
3641
  "We sent a code to ",
3293
3642
  stage.destinationHint,
3294
3643
  ". Enter it below to turn this on."
3295
3644
  ] }),
3296
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3297
- /* @__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)(
3298
3647
  "input",
3299
3648
  {
3300
3649
  id: "b316-mfa-code",
@@ -3305,8 +3654,8 @@ function TwoFactorManager({
3305
3654
  onChange: (event) => setCode(event.target.value)
3306
3655
  }
3307
3656
  ),
3308
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-actions", children: [
3309
- /* @__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)(
3310
3659
  "button",
3311
3660
  {
3312
3661
  type: "button",
@@ -3315,7 +3664,7 @@ function TwoFactorManager({
3315
3664
  children: "Cancel"
3316
3665
  }
3317
3666
  ),
3318
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3667
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3319
3668
  "button",
3320
3669
  {
3321
3670
  type: "button",
@@ -3326,9 +3675,9 @@ function TwoFactorManager({
3326
3675
  }
3327
3676
  )
3328
3677
  ] })
3329
- ] }) : stage.name === "enrolling" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-enrol", children: [
3330
- /* @__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." }),
3331
- /* @__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)(
3332
3681
  QrCode,
3333
3682
  {
3334
3683
  className: "b316-mfa-qr",
@@ -3336,13 +3685,13 @@ function TwoFactorManager({
3336
3685
  label: "QR code for your authenticator app"
3337
3686
  }
3338
3687
  ),
3339
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-secret", children: [
3340
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "b316-label", id: "b316-mfa-manual-key", children: "Can't scan? Enter this key" }),
3341
- /* @__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) })
3342
3691
  ] }),
3343
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("a", { className: "b316-mfa-uri", href: stage.uri, children: "Open in an authenticator app" }),
3344
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3345
- /* @__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)(
3346
3695
  "input",
3347
3696
  {
3348
3697
  id: "b316-mfa-code",
@@ -3353,8 +3702,8 @@ function TwoFactorManager({
3353
3702
  onChange: (event) => setCode(event.target.value)
3354
3703
  }
3355
3704
  ),
3356
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-actions", children: [
3357
- /* @__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)(
3358
3707
  "button",
3359
3708
  {
3360
3709
  type: "button",
@@ -3363,7 +3712,7 @@ function TwoFactorManager({
3363
3712
  children: "Cancel"
3364
3713
  }
3365
3714
  ),
3366
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3715
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3367
3716
  "button",
3368
3717
  {
3369
3718
  type: "button",
@@ -3374,9 +3723,9 @@ function TwoFactorManager({
3374
3723
  }
3375
3724
  )
3376
3725
  ] })
3377
- ] }) : on ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-on", children: [
3378
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "b316-muted", children: "On. You will be asked for a code when you sign in." }),
3379
- /* @__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)(
3380
3729
  ConfirmButton,
3381
3730
  {
3382
3731
  className: "b316-button-quiet b316-danger",
@@ -3386,11 +3735,11 @@ function TwoFactorManager({
3386
3735
  children: "Turn off"
3387
3736
  }
3388
3737
  )
3389
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-off", children: [
3390
- /* @__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." }),
3391
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-actions", children: [
3392
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: begin, children: busy ? "Starting\u2026" : "Use an authenticator app" }),
3393
- /* @__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)(
3394
3743
  "button",
3395
3744
  {
3396
3745
  type: "button",
@@ -3400,7 +3749,7 @@ function TwoFactorManager({
3400
3749
  children: "Email me a code"
3401
3750
  }
3402
3751
  ),
3403
- allowSms ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3752
+ allowSms ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3404
3753
  "button",
3405
3754
  {
3406
3755
  type: "button",
@@ -3416,14 +3765,14 @@ function TwoFactorManager({
3416
3765
  }
3417
3766
 
3418
3767
  // src/ForgotPassword.tsx
3419
- var import_react16 = require("react");
3420
- var import_jsx_runtime18 = require("react/jsx-runtime");
3768
+ var import_react17 = require("react");
3769
+ var import_jsx_runtime20 = require("react/jsx-runtime");
3421
3770
  function ForgotPassword({ onSent, signInUrl, className, style }) {
3422
3771
  const { client } = useBase316();
3423
- const [email, setEmail] = (0, import_react16.useState)("");
3424
- const [sent, setSent] = (0, import_react16.useState)(false);
3425
- const [busy, setBusy] = (0, import_react16.useState)(false);
3426
- 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);
3427
3776
  async function submit(event) {
3428
3777
  event.preventDefault();
3429
3778
  setBusy(true);
@@ -3439,22 +3788,22 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
3439
3788
  }
3440
3789
  }
3441
3790
  if (sent) {
3442
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: cls("b316-card", className), style, children: [
3443
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { className: "b316-form-title", children: "Check your email" }),
3444
- /* @__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: [
3445
3794
  "If there is an account for ",
3446
3795
  email.trim(),
3447
3796
  ", a link to set a new password is on its way."
3448
3797
  ] }),
3449
- 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
3450
3799
  ] });
3451
3800
  }
3452
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3453
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { className: "b316-form-title", children: "Reset your password" }),
3454
- error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3455
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "b316-field", children: [
3456
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { className: "b316-label", htmlFor: "b316-forgot-email", children: "Email" }),
3457
- /* @__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)(
3458
3807
  "input",
3459
3808
  {
3460
3809
  id: "b316-forgot-email",
@@ -3467,14 +3816,14 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
3467
3816
  }
3468
3817
  )
3469
3818
  ] }),
3470
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Send reset link" }),
3471
- 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
3472
3821
  ] });
3473
3822
  }
3474
3823
 
3475
3824
  // src/ResetPassword.tsx
3476
- var import_react17 = require("react");
3477
- var import_jsx_runtime19 = require("react/jsx-runtime");
3825
+ var import_react18 = require("react");
3826
+ var import_jsx_runtime21 = require("react/jsx-runtime");
3478
3827
  function ResetPassword({
3479
3828
  token: supplied,
3480
3829
  onReset,
@@ -3483,13 +3832,13 @@ function ResetPassword({
3483
3832
  style
3484
3833
  }) {
3485
3834
  const { client } = useBase316();
3486
- const [token, setToken] = (0, import_react17.useState)(supplied ?? null);
3487
- const [password, setPassword] = (0, import_react17.useState)("");
3488
- const [confirmation, setConfirmation] = (0, import_react17.useState)("");
3489
- const [done, setDone] = (0, import_react17.useState)(false);
3490
- const [busy, setBusy] = (0, import_react17.useState)(false);
3491
- const [error, setError] = (0, import_react17.useState)(null);
3492
- (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)(() => {
3493
3842
  if (supplied || typeof window === "undefined") {
3494
3843
  return;
3495
3844
  }
@@ -3524,24 +3873,24 @@ function ResetPassword({
3524
3873
  }
3525
3874
  }
3526
3875
  if (done) {
3527
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: cls("b316-card", className), style, children: [
3528
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "b316-form-title", children: "Password changed" }),
3529
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "b316-muted", children: "You can sign in with your new password." }),
3530
- 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
3531
3880
  ] });
3532
3881
  }
3533
3882
  if (!token) {
3534
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: cls("b316-card", className), style, children: [
3535
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "b316-form-title", children: "Nothing to reset" }),
3536
- /* @__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." })
3537
3886
  ] });
3538
3887
  }
3539
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3540
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "b316-form-title", children: "Choose a new password" }),
3541
- error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3542
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-field", children: [
3543
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "b316-label", htmlFor: "b316-reset-password", children: "New password" }),
3544
- /* @__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)(
3545
3894
  "input",
3546
3895
  {
3547
3896
  id: "b316-reset-password",
@@ -3554,9 +3903,9 @@ function ResetPassword({
3554
3903
  }
3555
3904
  )
3556
3905
  ] }),
3557
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-field", children: [
3558
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "b316-label", htmlFor: "b316-reset-confirm", children: "Repeat it" }),
3559
- /* @__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)(
3560
3909
  "input",
3561
3910
  {
3562
3911
  id: "b316-reset-confirm",
@@ -3569,13 +3918,13 @@ function ResetPassword({
3569
3918
  }
3570
3919
  )
3571
3920
  ] }),
3572
- /* @__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" })
3573
3922
  ] });
3574
3923
  }
3575
3924
 
3576
3925
  // src/VerifyEmail.tsx
3577
- var import_react18 = require("react");
3578
- var import_jsx_runtime20 = require("react/jsx-runtime");
3926
+ var import_react19 = require("react");
3927
+ var import_jsx_runtime22 = require("react/jsx-runtime");
3579
3928
  function VerifyEmail({
3580
3929
  token: supplied,
3581
3930
  onVerified,
@@ -3584,9 +3933,9 @@ function VerifyEmail({
3584
3933
  style
3585
3934
  }) {
3586
3935
  const { client } = useBase316();
3587
- const [state, setState] = (0, import_react18.useState)("waiting");
3588
- const spent = (0, import_react18.useRef)(false);
3589
- (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)(() => {
3590
3939
  if (spent.current) {
3591
3940
  return;
3592
3941
  }
@@ -3612,22 +3961,22 @@ function VerifyEmail({
3612
3961
  setState("failed");
3613
3962
  });
3614
3963
  }, [client, supplied, onVerified]);
3615
- 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: [
3616
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-form-title", children: "Email confirmed" }),
3617
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "b316-muted", children: "Thanks \u2014 your address is verified." }),
3618
- continueUrl ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("a", { className: "b316-button-link", href: continueUrl, children: "Continue" }) : null
3619
- ] }) : state === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3620
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-form-title", children: "That link did not work" }),
3621
- /* @__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." })
3622
- ] }) : state === "missing" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3623
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-form-title", children: "Nothing to confirm" }),
3624
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "b316-muted", children: "This page needs the link from your email." })
3625
- ] }) : /* @__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" }) });
3626
3975
  }
3627
3976
 
3628
3977
  // src/TeamMembers.tsx
3629
- var import_react19 = require("react");
3630
- var import_jsx_runtime21 = require("react/jsx-runtime");
3978
+ var import_react20 = require("react");
3979
+ var import_jsx_runtime23 = require("react/jsx-runtime");
3631
3980
  function TeamMembers({
3632
3981
  organizationId,
3633
3982
  onInvited,
@@ -3637,16 +3986,16 @@ function TeamMembers({
3637
3986
  style
3638
3987
  }) {
3639
3988
  const { client, token, session } = useBase316();
3640
- const [teams, setTeams] = (0, import_react19.useState)(null);
3641
- const [members, setMembers] = (0, import_react19.useState)(null);
3642
- const [invitations, setInvitations] = (0, import_react19.useState)(null);
3643
- const [email, setEmail] = (0, import_react19.useState)("");
3644
- const [busy, setBusy] = (0, import_react19.useState)(false);
3645
- const [error, setError] = (0, import_react19.useState)(null);
3646
- 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);
3647
3996
  const chosen = organizationId ?? (teams?.length === 1 ? teams[0].id : null);
3648
3997
  const team = teams?.find((candidate) => candidate.id === chosen) ?? null;
3649
- const load = (0, import_react19.useCallback)(() => {
3998
+ const load = (0, import_react20.useCallback)(() => {
3650
3999
  if (!token) {
3651
4000
  return;
3652
4001
  }
@@ -3654,8 +4003,8 @@ function TeamMembers({
3654
4003
  (cause) => setError(cause instanceof Error ? cause.message : "Could not load your teams.")
3655
4004
  );
3656
4005
  }, [client, token]);
3657
- (0, import_react19.useEffect)(load, [load]);
3658
- (0, import_react19.useEffect)(() => {
4006
+ (0, import_react20.useEffect)(load, [load]);
4007
+ (0, import_react20.useEffect)(() => {
3659
4008
  if (!token || !chosen) {
3660
4009
  return;
3661
4010
  }
@@ -3686,10 +4035,10 @@ function TeamMembers({
3686
4035
  return null;
3687
4036
  }
3688
4037
  if (!teams) {
3689
- 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" });
3690
4039
  }
3691
4040
  if (!chosen) {
3692
- 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." });
3693
4042
  }
3694
4043
  const canManage = invitations !== null;
3695
4044
  async function invite(event) {
@@ -3739,30 +4088,30 @@ function TeamMembers({
3739
4088
  setError(cause instanceof Error ? cause.message : "That invitation could not be withdrawn.");
3740
4089
  }
3741
4090
  }
3742
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cls("b316-card b316-team", className), style, children: [
3743
- /* @__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" }),
3744
4093
  team?.inherited ? (
3745
4094
  // Not a member of this team, so not in the list below and with nothing
3746
4095
  // to leave: access comes from the team that manages it, and ends there.
3747
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-muted", children: [
4096
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-muted", children: [
3748
4097
  "You have access through",
3749
4098
  " ",
3750
4099
  teams.find((candidate) => candidate.id === team.via)?.name ?? "the organization that manages this team",
3751
4100
  "."
3752
4101
  ] })
3753
4102
  ) : null,
3754
- error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3755
- /* @__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: [
3756
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
3757
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: member.user.name ?? member.user.email ?? "Someone" }),
3758
- /* @__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: [
3759
4108
  member.user.email,
3760
4109
  member.user.id === session?.userId ? " \xB7 you" : ""
3761
4110
  ] })
3762
4111
  ] }),
3763
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-team-member-side", children: [
3764
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "b316-chip", children: member.role.name }),
3765
- 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)(
3766
4115
  ConfirmButton,
3767
4116
  {
3768
4117
  className: "b316-button-quiet b316-danger",
@@ -3774,19 +4123,19 @@ function TeamMembers({
3774
4123
  ) : null
3775
4124
  ] })
3776
4125
  ] }, member.id)) }),
3777
- canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
3778
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h4", { className: "b316-team-subtitle", children: "Invited" }),
3779
- /* @__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: [
3780
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
3781
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: invitation.email }),
3782
- /* @__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: [
3783
4132
  invitation.role.name,
3784
4133
  " \xB7 expires",
3785
4134
  " ",
3786
4135
  new Date(invitation.expiresAt).toLocaleDateString()
3787
4136
  ] })
3788
4137
  ] }),
3789
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4138
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3790
4139
  "button",
3791
4140
  {
3792
4141
  type: "button",
@@ -3797,10 +4146,10 @@ function TeamMembers({
3797
4146
  )
3798
4147
  ] }, invitation.id)) })
3799
4148
  ] }) : null,
3800
- canManage ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("form", { className: "b316-team-invite", onSubmit: invite, children: [
3801
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { className: "b316-label", htmlFor: "b316-invite-email", children: "Invite by email" }),
3802
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-team-invite-row", children: [
3803
- /* @__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)(
3804
4153
  "input",
3805
4154
  {
3806
4155
  id: "b316-invite-email",
@@ -3812,19 +4161,19 @@ function TeamMembers({
3812
4161
  onChange: (event) => setEmail(event.target.value)
3813
4162
  }
3814
4163
  ),
3815
- /* @__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" })
3816
4165
  ] })
3817
4166
  ] }) : null,
3818
- copied ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-team-link", children: [
3819
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "b316-muted", children: "Send them this link. It is shown once and cannot be fetched again." }),
3820
- /* @__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 })
3821
4170
  ] }) : null
3822
4171
  ] });
3823
4172
  }
3824
4173
 
3825
4174
  // src/AcceptInvitation.tsx
3826
- var import_react20 = require("react");
3827
- var import_jsx_runtime22 = require("react/jsx-runtime");
4175
+ var import_react21 = require("react");
4176
+ var import_jsx_runtime24 = require("react/jsx-runtime");
3828
4177
  function signUpUrlWithInvitation(url, token) {
3829
4178
  const [beforeHash, ...hash] = url.split("#");
3830
4179
  const base = beforeHash ?? "";
@@ -3843,18 +4192,18 @@ function AcceptInvitation({
3843
4192
  style
3844
4193
  }) {
3845
4194
  const { client, token: session, session: user } = useBase316();
3846
- const [invitationToken, setInvitationToken] = (0, import_react20.useState)(supplied ?? null);
3847
- const [preview, setPreview] = (0, import_react20.useState)(null);
3848
- const [state, setState] = (0, import_react20.useState)("loading");
3849
- const [error, setError] = (0, import_react20.useState)(null);
3850
- const [busy, setBusy] = (0, import_react20.useState)(false);
3851
- (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)(() => {
3852
4201
  if (supplied || typeof window === "undefined") {
3853
4202
  return;
3854
4203
  }
3855
4204
  setInvitationToken(new URL(window.location.href).searchParams.get("invitation"));
3856
4205
  }, [supplied]);
3857
- (0, import_react20.useEffect)(() => {
4206
+ (0, import_react21.useEffect)(() => {
3858
4207
  if (!invitationToken) {
3859
4208
  setState(supplied === void 0 ? "loading" : "invalid");
3860
4209
  return;
@@ -3891,42 +4240,42 @@ function AcceptInvitation({
3891
4240
  }
3892
4241
  }
3893
4242
  if (state === "loading") {
3894
- 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" });
3895
4244
  }
3896
4245
  if (state === "invalid") {
3897
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cls("b316-card", className), style, children: [
3898
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "b316-form-title", children: "That invitation is no longer valid" }),
3899
- /* @__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." })
3900
4249
  ] });
3901
4250
  }
3902
4251
  if (state === "accepted") {
3903
- 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: [
3904
4253
  "You have joined ",
3905
4254
  preview?.organizationName
3906
4255
  ] }) });
3907
4256
  }
3908
4257
  const matches = !user || (user.user.email ?? "").toLowerCase() === preview?.email.toLowerCase();
3909
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cls("b316-card b316-invitation", className), style, children: [
3910
- /* @__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: [
3911
4260
  "Join ",
3912
4261
  preview?.organizationName
3913
4262
  ] }),
3914
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("p", { className: "b316-muted", children: [
4263
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("p", { className: "b316-muted", children: [
3915
4264
  "Invited as ",
3916
4265
  preview?.email,
3917
4266
  " \xB7 ",
3918
4267
  preview?.roleName
3919
4268
  ] }),
3920
- error ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3921
- !session ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3922
- /* @__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: [
3923
4272
  "Sign in as ",
3924
4273
  preview?.email,
3925
4274
  " to accept."
3926
4275
  ] }),
3927
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "b316-invitation-actions", children: [
3928
- signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { className: "b316-button", href: signInUrl, children: "Sign in" }) : null,
3929
- 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)(
3930
4279
  "a",
3931
4280
  {
3932
4281
  className: "b316-button-link",
@@ -3939,20 +4288,20 @@ function AcceptInvitation({
3939
4288
  // Said before they press anything. The server refuses this, but
3940
4289
  // finding out after a click reads as a broken invitation rather than
3941
4290
  // as being signed in as the wrong person.
3942
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("p", { children: [
4291
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("p", { children: [
3943
4292
  "You are signed in as ",
3944
4293
  user?.user.email,
3945
4294
  ". This invitation was sent to ",
3946
4295
  preview?.email,
3947
4296
  " \u2014 sign in as that address to accept it."
3948
4297
  ] })
3949
- ) : /* @__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}` })
3950
4299
  ] });
3951
4300
  }
3952
4301
 
3953
4302
  // src/PayInvoice.tsx
3954
- var import_react21 = require("react");
3955
- var import_jsx_runtime23 = require("react/jsx-runtime");
4303
+ var import_react22 = require("react");
4304
+ var import_jsx_runtime25 = require("react/jsx-runtime");
3956
4305
  var STRIPE_SRC = "https://js.stripe.com/v3/";
3957
4306
  function loadStripeScript() {
3958
4307
  if (typeof window === "undefined") {
@@ -3984,14 +4333,14 @@ function PayInvoice({
3984
4333
  style
3985
4334
  }) {
3986
4335
  const { client } = useBase316();
3987
- const mountRef = (0, import_react21.useRef)(null);
3988
- const stripeRef = (0, import_react21.useRef)(null);
3989
- const elementsRef = (0, import_react21.useRef)(null);
3990
- const [ready, setReady] = (0, import_react21.useState)(false);
3991
- const [paying, setPaying] = (0, import_react21.useState)(false);
3992
- const [done, setDone] = (0, import_react21.useState)(false);
3993
- const [error, setError] = (0, import_react21.useState)(null);
3994
- (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)(() => {
3995
4344
  let cancelled = false;
3996
4345
  async function start() {
3997
4346
  const base = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}`;
@@ -4044,17 +4393,17 @@ function PayInvoice({
4044
4393
  onPaid?.();
4045
4394
  };
4046
4395
  if (done) {
4047
- 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." }) });
4048
4397
  }
4049
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("form", { className: cls("b316-pay", className), style, onSubmit: submit, children: [
4050
- error ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "b316-pay__error", role: "alert", children: error }) : null,
4051
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: mountRef, className: "b316-pay__element" }),
4052
- /* @__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" })
4053
4402
  ] });
4054
4403
  }
4055
4404
 
4056
4405
  // src/usePaymentLink.ts
4057
- var import_react22 = require("react");
4406
+ var import_react23 = require("react");
4058
4407
  function usePaymentLink({
4059
4408
  token,
4060
4409
  environmentId,
@@ -4062,10 +4411,10 @@ function usePaymentLink({
4062
4411
  onPaid
4063
4412
  }) {
4064
4413
  const { client } = useBase316();
4065
- const [status2, setStatus] = (0, import_react22.useState)({ state: "loading" });
4066
- 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);
4067
4416
  onPaidRef.current = onPaid;
4068
- (0, import_react22.useEffect)(() => {
4417
+ (0, import_react23.useEffect)(() => {
4069
4418
  let stopped = false;
4070
4419
  let timer;
4071
4420
  const statusUrl = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}/status`;
@@ -4114,23 +4463,23 @@ function usePaymentLink({
4114
4463
  }
4115
4464
 
4116
4465
  // src/PricingTable.tsx
4117
- var import_react24 = require("react");
4466
+ var import_react25 = require("react");
4118
4467
 
4119
4468
  // src/usePlans.ts
4120
- var import_react23 = require("react");
4469
+ var import_react24 = require("react");
4121
4470
  var CHECKOUT_STATUSES = /* @__PURE__ */ new Set([402, 409]);
4122
4471
  function usePlans(options = {}) {
4123
4472
  const { client, token } = useBase316();
4124
- const [plans, setPlans] = (0, import_react23.useState)(null);
4125
- const [error, setError] = (0, import_react23.useState)(false);
4126
- const [busyPlanVersionId, setBusy] = (0, import_react23.useState)(null);
4127
- const [lastError, setLastError] = (0, import_react23.useState)(null);
4128
- const [ownPlanVersionId, setOwnPlanVersionId] = (0, import_react23.useState)(null);
4129
- const [managedBy, setManagedBy] = (0, import_react23.useState)(null);
4130
- 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);
4131
4480
  const supplied = options.currentPlanVersionId;
4132
4481
  const discover = supplied === void 0;
4133
- (0, import_react23.useEffect)(() => {
4482
+ (0, import_react24.useEffect)(() => {
4134
4483
  let cancelled = false;
4135
4484
  client.billing.plans().then((result) => {
4136
4485
  if (!cancelled) {
@@ -4146,7 +4495,7 @@ function usePlans(options = {}) {
4146
4495
  cancelled = true;
4147
4496
  };
4148
4497
  }, [client, reloadCount]);
4149
- (0, import_react23.useEffect)(() => {
4498
+ (0, import_react24.useEffect)(() => {
4150
4499
  if (!token) {
4151
4500
  return;
4152
4501
  }
@@ -4163,11 +4512,11 @@ function usePlans(options = {}) {
4163
4512
  cancelled = true;
4164
4513
  };
4165
4514
  }, [client, token, discover, reloadCount]);
4166
- const reload = (0, import_react23.useCallback)(() => {
4515
+ const reload = (0, import_react24.useCallback)(() => {
4167
4516
  setError(false);
4168
4517
  setReloadCount((count) => count + 1);
4169
4518
  }, []);
4170
- const selectPlan = (0, import_react23.useCallback)(
4519
+ const selectPlan = (0, import_react24.useCallback)(
4171
4520
  async (plan) => {
4172
4521
  setLastError(null);
4173
4522
  if (managedBy) {
@@ -4235,7 +4584,7 @@ function usePlans(options = {}) {
4235
4584
  }
4236
4585
 
4237
4586
  // src/PricingTable.tsx
4238
- var import_jsx_runtime24 = require("react/jsx-runtime");
4587
+ var import_jsx_runtime26 = require("react/jsx-runtime");
4239
4588
  function formatAmount(amount, currency) {
4240
4589
  if (amount === null) return "Free";
4241
4590
  const value = Number(amount);
@@ -4284,7 +4633,7 @@ function PricingTable({
4284
4633
  managedBy,
4285
4634
  selectPlan
4286
4635
  } = usePlans({ currentPlanVersionId });
4287
- const [scheduled, setScheduled] = (0, import_react24.useState)(null);
4636
+ const [scheduled, setScheduled] = (0, import_react25.useState)(null);
4288
4637
  async function choose(plan) {
4289
4638
  if (onSelectPlan) {
4290
4639
  await onSelectPlan(plan.planVersionId, plan);
@@ -4301,50 +4650,50 @@ function PricingTable({
4301
4650
  }
4302
4651
  }
4303
4652
  if (error) {
4304
- 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." });
4305
4654
  }
4306
4655
  if (!plans) {
4307
- 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" });
4308
4657
  }
4309
4658
  if (plans.length === 0) {
4310
- 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." });
4311
4660
  }
4312
4661
  const anyTrial = plans.some((plan) => Boolean(plan.trialDays));
4313
4662
  const anyDescription = plans.some((plan) => Boolean(plan.description));
4314
4663
  const anyFeatured = plans.some((plan) => plan.key === featuredPlanKey);
4315
- 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: [
4316
4665
  managedBy ? (
4317
4666
  // A client company's plan comes from the firm that runs it. The table
4318
4667
  // still shows what is on offer, with the current plan marked, but
4319
4668
  // nothing here can be bought: it would grant this account nothing.
4320
- /* @__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: [
4321
4670
  "Your plan is provided by ",
4322
4671
  managedBy.name ?? "the organization that manages your account",
4323
4672
  ". Ask them to change it."
4324
4673
  ] })
4325
- ) : 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,
4326
4675
  plans.map((plan) => {
4327
4676
  const base = plan.prices.find((price) => price.featureId === null) ?? plan.prices[0];
4328
4677
  const isCurrent = current === plan.planVersionId;
4329
4678
  const featured = featuredPlanKey === plan.key;
4330
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
4679
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
4331
4680
  "div",
4332
4681
  {
4333
4682
  className: featured ? "b316-card b316-plan b316-plan-featured" : "b316-card b316-plan",
4334
4683
  children: [
4335
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-plan-head", children: [
4336
- anyFeatured ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: featured ? "b316-plan-badge" : "b316-plan-badge-spacer", children: featured ? "Recommended" : "\xA0" }) : null,
4337
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plan-name", children: plan.name }),
4338
- 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
4339
4688
  ] }),
4340
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-plan-pricing", children: [
4341
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plan-price", children: formatAmount(base?.amount ?? null, plan.currency) }),
4342
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plan-cadence", children: cadence(plan, base?.amount ?? null) }),
4343
- 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
4344
4693
  ] }),
4345
- /* @__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: [
4346
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: entitlement.featureName }),
4347
- /* @__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" : (
4348
4697
  // A usage price on the feature makes the limit an
4349
4698
  // allowance billed past, not a ceiling — the same
4350
4699
  // rule `check()` applies (any non-FLAT price).
@@ -4353,7 +4702,7 @@ function PricingTable({
4353
4702
  ) ? `${entitlement.limit} included` : entitlement.limit
4354
4703
  ) })
4355
4704
  ] }, entitlement.featureId)) }),
4356
- /* @__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)(
4357
4706
  "button",
4358
4707
  {
4359
4708
  type: "button",
@@ -4374,12 +4723,12 @@ function PricingTable({
4374
4723
  }
4375
4724
 
4376
4725
  // src/DataTable.tsx
4377
- var import_sdk8 = require("@base316/sdk");
4378
- var import_react28 = require("react");
4726
+ var import_sdk9 = require("@base316/sdk");
4727
+ var import_react29 = require("react");
4379
4728
 
4380
4729
  // src/fields.tsx
4381
- var import_sdk6 = require("@base316/sdk");
4382
- var import_jsx_runtime25 = require("react/jsx-runtime");
4730
+ var import_sdk7 = require("@base316/sdk");
4731
+ var import_jsx_runtime27 = require("react/jsx-runtime");
4383
4732
  function formatNumber(value, fraction = 0) {
4384
4733
  const number = Number(value);
4385
4734
  return Number.isFinite(number) ? new Intl.NumberFormat(void 0, {
@@ -4401,10 +4750,10 @@ function formatDuration(value) {
4401
4750
  }
4402
4751
  function FieldCell({ value, field, related }) {
4403
4752
  if (field.type === "RELATION") {
4404
- 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");
4405
4754
  }
4406
4755
  if (value === null || value === void 0 || value === "") {
4407
- 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" });
4408
4757
  }
4409
4758
  switch (field.type) {
4410
4759
  case "BOOLEAN":
@@ -4417,9 +4766,9 @@ function FieldCell({ value, field, related }) {
4417
4766
  return formatDuration(value);
4418
4767
  case "RATING": {
4419
4768
  const stars = Math.round(Number(value));
4420
- 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: [
4421
4770
  "\u2605".repeat(stars),
4422
- /* @__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)) })
4423
4772
  ] });
4424
4773
  }
4425
4774
  case "DATE":
@@ -4427,17 +4776,17 @@ function FieldCell({ value, field, related }) {
4427
4776
  case "DATETIME":
4428
4777
  return new Date(String(value)).toLocaleString();
4429
4778
  case "SELECT":
4430
- 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) });
4431
4780
  case "MULTISELECT":
4432
- 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))) });
4433
4782
  case "URL":
4434
- 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) });
4435
4784
  case "EMAIL":
4436
- 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) });
4437
4786
  case "PHONE":
4438
- 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) });
4439
4788
  case "ADDRESS":
4440
- return (0, import_sdk6.formatAddress)(value);
4789
+ return (0, import_sdk7.formatAddress)(value);
4441
4790
  case "ATTACHMENT": {
4442
4791
  const files = Array.isArray(value) ? value : [value];
4443
4792
  return `${files.length} file${files.length === 1 ? "" : "s"}`;
@@ -4447,13 +4796,13 @@ function FieldCell({ value, field, related }) {
4447
4796
  return text.length > 80 ? `${text.slice(0, 80)}\u2026` : text;
4448
4797
  }
4449
4798
  case "JSON":
4450
- 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) });
4451
4800
  default:
4452
4801
  return String(value);
4453
4802
  }
4454
4803
  }
4455
4804
  function FieldInput({ value, field, onChange, error, disabled }) {
4456
- if ((0, import_sdk6.specFor)(field).computed) {
4805
+ if ((0, import_sdk7.specFor)(field).computed) {
4457
4806
  return null;
4458
4807
  }
4459
4808
  const id = `b316-field-${field.key}`;
@@ -4468,7 +4817,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4468
4817
  function control() {
4469
4818
  switch (field.type) {
4470
4819
  case "LONGTEXT":
4471
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4820
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4472
4821
  "textarea",
4473
4822
  {
4474
4823
  ...common,
@@ -4478,7 +4827,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4478
4827
  }
4479
4828
  );
4480
4829
  case "BOOLEAN":
4481
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4830
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4482
4831
  "input",
4483
4832
  {
4484
4833
  ...common,
@@ -4489,22 +4838,22 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4489
4838
  }
4490
4839
  );
4491
4840
  case "SELECT":
4492
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
4841
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
4493
4842
  "select",
4494
4843
  {
4495
4844
  ...common,
4496
4845
  value: value === null || value === void 0 ? "" : String(value),
4497
4846
  onChange: (event) => onChange(event.target.value === "" ? null : event.target.value),
4498
4847
  children: [
4499
- field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: "", children: "\u2014" }),
4500
- (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))
4501
4850
  ]
4502
4851
  }
4503
4852
  );
4504
4853
  case "MULTISELECT": {
4505
4854
  const selected = new Set(Array.isArray(value) ? value.map(String) : []);
4506
- 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: [
4507
- /* @__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)(
4508
4857
  "input",
4509
4858
  {
4510
4859
  type: "checkbox",
@@ -4527,7 +4876,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4527
4876
  case "NUMBER":
4528
4877
  case "MONEY":
4529
4878
  case "PERCENT":
4530
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4879
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4531
4880
  "input",
4532
4881
  {
4533
4882
  ...common,
@@ -4538,7 +4887,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4538
4887
  }
4539
4888
  );
4540
4889
  case "RATING":
4541
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4890
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4542
4891
  "input",
4543
4892
  {
4544
4893
  ...common,
@@ -4552,8 +4901,8 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4552
4901
  );
4553
4902
  case "DURATION": {
4554
4903
  const minutes = value === null || value === void 0 ? "" : String(Number(value) / 60);
4555
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "b316-suffixed", children: [
4556
- /* @__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)(
4557
4906
  "input",
4558
4907
  {
4559
4908
  ...common,
@@ -4563,11 +4912,11 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4563
4912
  onChange: (event) => onChange(event.target.value === "" ? null : Number(event.target.value) * 60)
4564
4913
  }
4565
4914
  ),
4566
- /* @__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" })
4567
4916
  ] });
4568
4917
  }
4569
4918
  case "DATE":
4570
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4919
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4571
4920
  "input",
4572
4921
  {
4573
4922
  ...common,
@@ -4577,7 +4926,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4577
4926
  }
4578
4927
  );
4579
4928
  case "DATETIME":
4580
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4929
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4581
4930
  "input",
4582
4931
  {
4583
4932
  ...common,
@@ -4590,7 +4939,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4590
4939
  );
4591
4940
  case "ADDRESS": {
4592
4941
  const address = value ?? {};
4593
- const part = (key, label) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4942
+ const part = (key, label) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4594
4943
  "input",
4595
4944
  {
4596
4945
  className: "b316-input",
@@ -4602,7 +4951,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4602
4951
  },
4603
4952
  key
4604
4953
  );
4605
- 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: [
4606
4955
  part("line1", "Address line 1"),
4607
4956
  part("line2", "Address line 2"),
4608
4957
  part("city", "City"),
@@ -4612,7 +4961,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4612
4961
  ] });
4613
4962
  }
4614
4963
  case "EMAIL":
4615
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4964
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4616
4965
  "input",
4617
4966
  {
4618
4967
  ...common,
@@ -4622,7 +4971,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4622
4971
  }
4623
4972
  );
4624
4973
  case "URL":
4625
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4974
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4626
4975
  "input",
4627
4976
  {
4628
4977
  ...common,
@@ -4632,7 +4981,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4632
4981
  }
4633
4982
  );
4634
4983
  case "PHONE":
4635
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4984
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4636
4985
  "input",
4637
4986
  {
4638
4987
  ...common,
@@ -4642,7 +4991,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4642
4991
  }
4643
4992
  );
4644
4993
  default:
4645
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4994
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4646
4995
  "input",
4647
4996
  {
4648
4997
  ...common,
@@ -4653,24 +5002,24 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4653
5002
  );
4654
5003
  }
4655
5004
  }
4656
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "b316-field", children: [
4657
- /* @__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: [
4658
5007
  field.label,
4659
- 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
4660
5009
  ] }),
4661
5010
  control(),
4662
- field.description ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "b316-hint", children: field.description }) : null,
4663
- 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
4664
5013
  ] });
4665
5014
  }
4666
5015
 
4667
5016
  // src/RecordForm.tsx
4668
- var import_sdk7 = require("@base316/sdk");
4669
- var import_react27 = require("react");
5017
+ var import_sdk8 = require("@base316/sdk");
5018
+ var import_react28 = require("react");
4670
5019
 
4671
5020
  // src/RelationPicker.tsx
4672
- var import_react25 = require("react");
4673
- var import_jsx_runtime26 = require("react/jsx-runtime");
5021
+ var import_react26 = require("react");
5022
+ var import_jsx_runtime28 = require("react/jsx-runtime");
4674
5023
  function RelationPicker({
4675
5024
  field,
4676
5025
  value,
@@ -4680,13 +5029,13 @@ function RelationPicker({
4680
5029
  tenant
4681
5030
  }) {
4682
5031
  const { client, token } = useBase316();
4683
- const [query, setQuery] = (0, import_react25.useState)("");
4684
- const [results, setResults] = (0, import_react25.useState)([]);
4685
- const [chosenTitle, setChosenTitle] = (0, import_react25.useState)(null);
4686
- 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);
4687
5036
  const id = `b316-field-${field.key}`;
4688
- const box = (0, import_react25.useRef)(null);
4689
- (0, import_react25.useEffect)(() => {
5037
+ const box = (0, import_react26.useRef)(null);
5038
+ (0, import_react26.useEffect)(() => {
4690
5039
  if (!token || !value || !field.relationTo) {
4691
5040
  setChosenTitle(null);
4692
5041
  return;
@@ -4701,7 +5050,7 @@ function RelationPicker({
4701
5050
  cancelled = true;
4702
5051
  };
4703
5052
  }, [client, token, value, field.relationTo, tenant]);
4704
- (0, import_react25.useEffect)(() => {
5053
+ (0, import_react26.useEffect)(() => {
4705
5054
  if (!token || !field.relationTo || !open) {
4706
5055
  return;
4707
5056
  }
@@ -4727,7 +5076,7 @@ function RelationPicker({
4727
5076
  clearTimeout(timer);
4728
5077
  };
4729
5078
  }, [client, token, field.relationTo, query, open, tenant]);
4730
- (0, import_react25.useEffect)(() => {
5079
+ (0, import_react26.useEffect)(() => {
4731
5080
  if (!open || typeof document === "undefined") {
4732
5081
  return;
4733
5082
  }
@@ -4741,14 +5090,14 @@ function RelationPicker({
4741
5090
  document.removeEventListener("mousedown", onDocumentClick);
4742
5091
  };
4743
5092
  }, [open]);
4744
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-field", ref: box, children: [
4745
- /* @__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: [
4746
5095
  field.label,
4747
- 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
4748
5097
  ] }),
4749
- value && !open ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-relation-chosen", children: [
4750
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: chosenTitle ?? value }),
4751
- 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)(
4752
5101
  "button",
4753
5102
  {
4754
5103
  type: "button",
@@ -4760,7 +5109,7 @@ function RelationPicker({
4760
5109
  children: "Change"
4761
5110
  }
4762
5111
  ),
4763
- disabled || field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5112
+ disabled || field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4764
5113
  "button",
4765
5114
  {
4766
5115
  type: "button",
@@ -4770,8 +5119,8 @@ function RelationPicker({
4770
5119
  children: "Clear"
4771
5120
  }
4772
5121
  )
4773
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
4774
- /* @__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)(
4775
5124
  "input",
4776
5125
  {
4777
5126
  id,
@@ -4792,7 +5141,7 @@ function RelationPicker({
4792
5141
  }
4793
5142
  }
4794
5143
  ),
4795
- 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)(
4796
5145
  "button",
4797
5146
  {
4798
5147
  type: "button",
@@ -4808,13 +5157,13 @@ function RelationPicker({
4808
5157
  }
4809
5158
  ) }, result.id)) }) : null
4810
5159
  ] }),
4811
- field.description ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-hint", children: field.description }) : null,
4812
- 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
4813
5162
  ] });
4814
5163
  }
4815
5164
 
4816
5165
  // src/useCollection.ts
4817
- var import_react26 = require("react");
5166
+ var import_react27 = require("react");
4818
5167
  function fieldErrorFrom(cause) {
4819
5168
  const param = cause?.param;
4820
5169
  const message = cause instanceof Error ? cause.message : "That value was not accepted.";
@@ -4822,24 +5171,24 @@ function fieldErrorFrom(cause) {
4822
5171
  }
4823
5172
  function useCollection(collection, options = {}) {
4824
5173
  const { client, token } = useBase316();
4825
- const [schema, setSchema] = (0, import_react26.useState)(null);
4826
- const [records, setRecords] = (0, import_react26.useState)([]);
4827
- const [error, setError] = (0, import_react26.useState)(null);
4828
- const [loading, setLoading] = (0, import_react26.useState)(true);
4829
- const [total, setTotal] = (0, import_react26.useState)(0);
4830
- const [cursor, setCursor] = (0, import_react26.useState)(null);
4831
- const [reloadCount, setReloadCount] = (0, import_react26.useState)(0);
4832
- const [search, setSearch] = (0, import_react26.useState)("");
4833
- const [filters, setFilters] = (0, import_react26.useState)([]);
4834
- 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)(
4835
5184
  options.sort ?? null
4836
5185
  );
4837
- const [fieldErrors, setFieldErrors] = (0, import_react26.useState)({});
4838
- 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);
4839
5188
  const { tenant, limit, recordId } = options;
4840
5189
  const fixedFilters = JSON.stringify(options.filters ?? []);
4841
- const scope = (0, import_react26.useMemo)(() => tenant ? { tenant } : void 0, [tenant]);
4842
- (0, import_react26.useEffect)(() => {
5190
+ const scope = (0, import_react27.useMemo)(() => tenant ? { tenant } : void 0, [tenant]);
5191
+ (0, import_react27.useEffect)(() => {
4843
5192
  if (!token) {
4844
5193
  return;
4845
5194
  }
@@ -4858,7 +5207,7 @@ function useCollection(collection, options = {}) {
4858
5207
  cancelled = true;
4859
5208
  };
4860
5209
  }, [client, token, collection, scope]);
4861
- (0, import_react26.useEffect)(() => {
5210
+ (0, import_react27.useEffect)(() => {
4862
5211
  if (!token || !schema) {
4863
5212
  return;
4864
5213
  }
@@ -4928,10 +5277,10 @@ function useCollection(collection, options = {}) {
4928
5277
  scope,
4929
5278
  reloadCount
4930
5279
  ]);
4931
- const reload = (0, import_react26.useCallback)(() => {
5280
+ const reload = (0, import_react27.useCallback)(() => {
4932
5281
  setReloadCount((count) => count + 1);
4933
5282
  }, []);
4934
- const loadMore = (0, import_react26.useCallback)(() => {
5283
+ const loadMore = (0, import_react27.useCallback)(() => {
4935
5284
  if (!token || !cursor) {
4936
5285
  return;
4937
5286
  }
@@ -4955,7 +5304,7 @@ function useCollection(collection, options = {}) {
4955
5304
  setLoading(false);
4956
5305
  });
4957
5306
  }, [client, token, collection, cursor, fixedFilters, filters, search, sort, limit, scope]);
4958
- const toggleSort = (0, import_react26.useCallback)((field) => {
5307
+ const toggleSort = (0, import_react27.useCallback)((field) => {
4959
5308
  setSort((current) => {
4960
5309
  if (current?.field !== field) {
4961
5310
  return { field, direction: "asc" };
@@ -4963,7 +5312,7 @@ function useCollection(collection, options = {}) {
4963
5312
  return current.direction === "asc" ? { field, direction: "desc" } : null;
4964
5313
  });
4965
5314
  }, []);
4966
- const create = (0, import_react26.useCallback)(
5315
+ const create = (0, import_react27.useCallback)(
4967
5316
  async (fields) => {
4968
5317
  if (!token) {
4969
5318
  return null;
@@ -4983,7 +5332,7 @@ function useCollection(collection, options = {}) {
4983
5332
  },
4984
5333
  [client, token, collection, scope, reload]
4985
5334
  );
4986
- const update = (0, import_react26.useCallback)(
5335
+ const update = (0, import_react27.useCallback)(
4987
5336
  async (id, fields) => {
4988
5337
  if (!token) {
4989
5338
  return null;
@@ -5005,7 +5354,7 @@ function useCollection(collection, options = {}) {
5005
5354
  },
5006
5355
  [client, token, collection, scope]
5007
5356
  );
5008
- const remove = (0, import_react26.useCallback)(
5357
+ const remove = (0, import_react27.useCallback)(
5009
5358
  async (id) => {
5010
5359
  if (!token) {
5011
5360
  return false;
@@ -5050,7 +5399,7 @@ function useCollection(collection, options = {}) {
5050
5399
  }
5051
5400
 
5052
5401
  // src/RecordForm.tsx
5053
- var import_jsx_runtime27 = require("react/jsx-runtime");
5402
+ var import_jsx_runtime29 = require("react/jsx-runtime");
5054
5403
  function RecordForm({
5055
5404
  collection,
5056
5405
  recordId,
@@ -5071,22 +5420,22 @@ function RecordForm({
5071
5420
  recordId
5072
5421
  }
5073
5422
  );
5074
- const [values, setValues] = (0, import_react27.useState)(defaults ?? {});
5075
- 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);
5076
5425
  const existing = recordId ? records.find((record) => record.id === recordId) : void 0;
5077
- (0, import_react27.useEffect)(() => {
5426
+ (0, import_react28.useEffect)(() => {
5078
5427
  if (existing && !loaded) {
5079
5428
  setValues(existing.fields);
5080
5429
  setLoaded(true);
5081
5430
  }
5082
5431
  }, [existing, loaded]);
5083
5432
  if (error) {
5084
- 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 }) });
5085
5434
  }
5086
5435
  if (!schema || !loaded) {
5087
- 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" });
5088
5437
  }
5089
- 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);
5090
5439
  async function submit(event) {
5091
5440
  event.preventDefault();
5092
5441
  const saved = recordId ? await update(recordId, values) : await create(values);
@@ -5094,11 +5443,11 @@ function RecordForm({
5094
5443
  onSaved?.(saved.id);
5095
5444
  }
5096
5445
  }
5097
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
5098
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h3", { className: "b316-form-title", children: recordId ? `Edit ${schema.name.toLowerCase()}` : `New ${schema.name.toLowerCase()}` }),
5099
- 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,
5100
5449
  editable.map(
5101
- (field) => field.type === "RELATION" ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5450
+ (field) => field.type === "RELATION" ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5102
5451
  RelationPicker,
5103
5452
  {
5104
5453
  field,
@@ -5109,7 +5458,7 @@ function RecordForm({
5109
5458
  onChange: (next) => setValues((current) => ({ ...current, [field.key]: next }))
5110
5459
  },
5111
5460
  field.key
5112
- ) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5461
+ ) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5113
5462
  FieldInput,
5114
5463
  {
5115
5464
  field,
@@ -5121,15 +5470,15 @@ function RecordForm({
5121
5470
  field.key
5122
5471
  )
5123
5472
  ),
5124
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-form-actions", children: [
5125
- onCancel ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: onCancel, disabled: saving, children: "Cancel" }) : null,
5126
- /* @__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" })
5127
5476
  ] })
5128
5477
  ] });
5129
5478
  }
5130
5479
 
5131
5480
  // src/DataTable.tsx
5132
- var import_jsx_runtime28 = require("react/jsx-runtime");
5481
+ var import_jsx_runtime30 = require("react/jsx-runtime");
5133
5482
  function DataTable({
5134
5483
  collection,
5135
5484
  columns,
@@ -5158,25 +5507,25 @@ function DataTable({
5158
5507
  loadMore,
5159
5508
  remove
5160
5509
  } = useCollection(collection, options);
5161
- const [editing, setEditing] = (0, import_react28.useState)(null);
5162
- 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);
5163
5512
  if (error) {
5164
- 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 }) });
5165
5514
  }
5166
5515
  if (!schema) {
5167
- 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" });
5168
5517
  }
5169
5518
  const shown = columns ? (
5170
5519
  // Ordered by what was asked for, not by the schema: a caller naming
5171
5520
  // columns means that order.
5172
5521
  columns.map((key) => schema.fields.find((field) => field.key === key)).filter((field) => Boolean(field))
5173
5522
  ) : schema.fields;
5174
- 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);
5175
5524
  const writable = canWrite && !readOnly;
5176
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cls("b316-table-wrap", className), style, children: [
5177
- removeFailed ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-error", role: "alert", children: removeFailed }) : null,
5178
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-table-bar", children: [
5179
- 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)(
5180
5529
  "input",
5181
5530
  {
5182
5531
  type: "search",
@@ -5186,25 +5535,25 @@ function DataTable({
5186
5535
  value: search,
5187
5536
  onChange: (event) => setSearch(event.target.value)
5188
5537
  }
5189
- ) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", {}),
5190
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-table-actions", children: [
5191
- /* @__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: [
5192
5541
  total,
5193
5542
  " ",
5194
5543
  total === 1 ? schema.name.toLowerCase() : schema.namePlural.toLowerCase()
5195
5544
  ] }),
5196
- 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: [
5197
5546
  "New ",
5198
5547
  schema.name.toLowerCase()
5199
5548
  ] }) : null
5200
5549
  ] })
5201
5550
  ] }),
5202
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-table-scroll", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("table", { className: "b316-table", children: [
5203
- /* @__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: [
5204
5553
  shown.map((field) => {
5205
- const sortable = (0, import_sdk8.specFor)(field).capabilities.sortable;
5554
+ const sortable = (0, import_sdk9.specFor)(field).capabilities.sortable;
5206
5555
  const active = sort?.field === field.key;
5207
- 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)(
5208
5557
  "button",
5209
5558
  {
5210
5559
  type: "button",
@@ -5212,20 +5561,20 @@ function DataTable({
5212
5561
  onClick: () => toggleSort(field.key),
5213
5562
  children: [
5214
5563
  field.label,
5215
- /* @__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" })
5216
5565
  ]
5217
5566
  }
5218
5567
  ) : field.label }, field.key);
5219
5568
  }),
5220
- 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
5221
5570
  ] }) }),
5222
- /* @__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)(
5223
5572
  "tr",
5224
5573
  {
5225
5574
  className: onSelect ? "b316-row-clickable" : void 0,
5226
5575
  onClick: onSelect ? () => onSelect(record) : void 0,
5227
5576
  children: [
5228
- 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)(
5229
5578
  FieldCell,
5230
5579
  {
5231
5580
  value: record.fields[field.key] ?? null,
@@ -5233,8 +5582,8 @@ function DataTable({
5233
5582
  related: record.related[field.key]
5234
5583
  }
5235
5584
  ) }, field.key)),
5236
- writable ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("td", { className: "b316-table-rowactions", children: [
5237
- /* @__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)(
5238
5587
  "button",
5239
5588
  {
5240
5589
  type: "button",
@@ -5246,7 +5595,7 @@ function DataTable({
5246
5595
  children: "Edit"
5247
5596
  }
5248
5597
  ),
5249
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5598
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5250
5599
  ConfirmButton,
5251
5600
  {
5252
5601
  className: "b316-button-quiet b316-danger",
@@ -5270,10 +5619,10 @@ function DataTable({
5270
5619
  record.id
5271
5620
  )) })
5272
5621
  ] }) }),
5273
- records.length === 0 && !loading ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-empty", children: emptyState ?? `No ${schema.namePlural.toLowerCase()} yet.` }) : null,
5274
- loading ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-empty", children: "Loading\u2026" }) : null,
5275
- 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,
5276
- 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)(
5277
5626
  RecordForm,
5278
5627
  {
5279
5628
  collection,
@@ -5296,9 +5645,9 @@ function ariaSort(active, direction) {
5296
5645
  }
5297
5646
 
5298
5647
  // src/Kanban.tsx
5299
- var import_sdk9 = require("@base316/sdk");
5300
- var import_react29 = require("react");
5301
- 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");
5302
5651
  function Kanban({
5303
5652
  collection,
5304
5653
  groupBy,
@@ -5315,17 +5664,17 @@ function Kanban({
5315
5664
  limit: options.limit ?? 100,
5316
5665
  ...options
5317
5666
  });
5318
- const [dragging, setDragging] = (0, import_react29.useState)(null);
5319
- 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);
5320
5669
  if (error) {
5321
- 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 }) });
5322
5671
  }
5323
5672
  if (!schema) {
5324
- 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" });
5325
5674
  }
5326
- const field = groupBy ? schema.fields.find((candidate) => candidate.key === groupBy) ?? null : (0, import_sdk9.defaultGroupFieldOf)(schema.fields);
5327
- if (!field || !(0, import_sdk9.specFor)(field).capabilities.groupable) {
5328
- 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.` });
5329
5678
  }
5330
5679
  const columns = columnsFor(field);
5331
5680
  const shown = cardFields ? cardFields.map((key) => schema.fields.find((candidate) => candidate.key === key)).filter((candidate) => Boolean(candidate)) : (
@@ -5333,7 +5682,7 @@ function Kanban({
5333
5682
  // The grouping field is already the column heading and the title is
5334
5683
  // already the card heading, so both would be printed twice on every card.
5335
5684
  schema.fields.filter(
5336
- (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
5337
5686
  ).slice(0, 3)
5338
5687
  );
5339
5688
  async function move(record, value) {
@@ -5342,12 +5691,12 @@ function Kanban({
5342
5691
  }
5343
5692
  await update(record.id, { [field.key]: value });
5344
5693
  }
5345
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: cls("b316-board-wrap", className), style, children: [
5346
- /* @__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) => {
5347
5696
  const inColumn = records.filter(
5348
5697
  (record) => String(record.fields[field.key] ?? "") === String(column.value ?? "")
5349
5698
  );
5350
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
5699
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
5351
5700
  "section",
5352
5701
  {
5353
5702
  className: over === String(column.value) ? "b316-board-column b316-board-over" : "b316-board-column",
@@ -5371,12 +5720,12 @@ function Kanban({
5371
5720
  setDragging(null);
5372
5721
  },
5373
5722
  children: [
5374
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("header", { className: "b316-board-head", children: [
5375
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "b316-board-title", children: column.label }),
5376
- /* @__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 })
5377
5726
  ] }),
5378
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "b316-board-cards", children: [
5379
- 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)(
5380
5729
  "article",
5381
5730
  {
5382
5731
  className: "b316-board-card",
@@ -5388,10 +5737,10 @@ function Kanban({
5388
5737
  },
5389
5738
  onClick: onSelect ? () => onSelect(record) : void 0,
5390
5739
  children: [
5391
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-board-card-title", children: record.title ?? "Untitled" }),
5392
- shown.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "b316-board-card-field", children: [
5393
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "b316-muted", children: candidate.label }),
5394
- /* @__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)(
5395
5744
  FieldCell,
5396
5745
  {
5397
5746
  value: record.fields[candidate.key] ?? null,
@@ -5404,9 +5753,9 @@ function Kanban({
5404
5753
  // Dragging is not reachable by keyboard and is awkward on a
5405
5754
  // phone. This is the same action by other means, not a
5406
5755
  // lesser fallback.
5407
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "b316-board-move", children: [
5408
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "b316-muted", children: "Move to" }),
5409
- /* @__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)(
5410
5759
  "select",
5411
5760
  {
5412
5761
  className: "b316-input",
@@ -5418,7 +5767,7 @@ function Kanban({
5418
5767
  );
5419
5768
  void move(record, chosen?.value ?? null);
5420
5769
  },
5421
- 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)))
5422
5771
  }
5423
5772
  )
5424
5773
  ] })
@@ -5427,14 +5776,14 @@ function Kanban({
5427
5776
  },
5428
5777
  record.id
5429
5778
  )),
5430
- 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
5431
5780
  ] })
5432
5781
  ]
5433
5782
  },
5434
5783
  String(column.value)
5435
5784
  );
5436
5785
  }) }),
5437
- 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: [
5438
5787
  "Showing ",
5439
5788
  records.length,
5440
5789
  " of ",
@@ -5455,9 +5804,9 @@ function columnsFor(field) {
5455
5804
  }
5456
5805
 
5457
5806
  // src/Chart.tsx
5458
- var import_sdk10 = require("@base316/sdk");
5459
- var import_react30 = require("react");
5460
- 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");
5461
5810
  function Chart({
5462
5811
  collection,
5463
5812
  x,
@@ -5476,43 +5825,43 @@ function Chart({
5476
5825
  limit: options.limit ?? 200,
5477
5826
  ...options
5478
5827
  });
5479
- const axis = (0, import_react30.useMemo)(() => {
5828
+ const axis = (0, import_react31.useMemo)(() => {
5480
5829
  if (!schema) {
5481
5830
  return null;
5482
5831
  }
5483
- const timeFields = (0, import_sdk10.fieldsFor)(schema.fields, "timeAxis");
5832
+ const timeFields = (0, import_sdk11.fieldsFor)(schema.fields, "timeAxis");
5484
5833
  const chosen = x ? schema.fields.find((field) => field.key === x) ?? null : timeFields[0] ?? null;
5485
- return chosen && (0, import_sdk10.specFor)(chosen).capabilities.timeAxis ? chosen : null;
5834
+ return chosen && (0, import_sdk11.specFor)(chosen).capabilities.timeAxis ? chosen : null;
5486
5835
  }, [schema, x]);
5487
- const measure = (0, import_react30.useMemo)(() => {
5836
+ const measure = (0, import_react31.useMemo)(() => {
5488
5837
  if (!schema || !y) {
5489
5838
  return null;
5490
5839
  }
5491
- const candidates = (0, import_sdk10.fieldsAggregatableBy)(schema.fields, aggregate);
5840
+ const candidates = (0, import_sdk11.fieldsAggregatableBy)(schema.fields, aggregate);
5492
5841
  return candidates.find((field) => field.key === y) ?? null;
5493
5842
  }, [schema, y, aggregate]);
5494
- const buckets = (0, import_react30.useMemo)(
5843
+ const buckets = (0, import_react31.useMemo)(
5495
5844
  () => axis ? bucketise(records, axis, measure, y ? aggregate : "count", bucket) : [],
5496
5845
  [records, axis, measure, aggregate, bucket, y]
5497
5846
  );
5498
5847
  if (error) {
5499
- 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 }) });
5500
5849
  }
5501
5850
  if (!schema || loading) {
5502
- 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" });
5503
5852
  }
5504
5853
  if (!axis) {
5505
- 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.` });
5506
5855
  }
5507
5856
  if (y && !measure) {
5508
- 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}`}.` });
5509
5858
  }
5510
5859
  const peak = Math.max(...buckets.map((entry) => entry.value), 0);
5511
5860
  const heading = title ?? `${measure ? `${aggregate} of ${measure.label}` : schema.namePlural} by ${axis.label}`;
5512
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("figure", { className: cls("b316-card b316-chart", className), style, children: [
5513
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("figcaption", { className: "b316-chart-title", children: heading }),
5514
- 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: [
5515
- /* @__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)(
5516
5865
  "div",
5517
5866
  {
5518
5867
  className: "b316-chart-bar",
@@ -5520,18 +5869,18 @@ function Chart({
5520
5869
  title: `${entry.label}: ${format(entry.value)}`
5521
5870
  }
5522
5871
  ),
5523
- /* @__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 })
5524
5873
  ] }, entry.key)) }),
5525
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("details", { className: "b316-chart-data", children: [
5526
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("summary", { children: "Values" }),
5527
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("table", { className: "b316-table", children: [
5528
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("tr", { children: [
5529
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("th", { scope: "col", children: axis.label }),
5530
- /* @__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" })
5531
5880
  ] }) }),
5532
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("tbody", { children: buckets.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("tr", { children: [
5533
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("td", { children: entry.label }),
5534
- /* @__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) })
5535
5884
  ] }, entry.key)) })
5536
5885
  ] })
5537
5886
  ] })
@@ -5589,9 +5938,9 @@ function combine(values, aggregate) {
5589
5938
  }
5590
5939
 
5591
5940
  // src/RecordDetail.tsx
5592
- var import_sdk11 = require("@base316/sdk");
5593
- var import_react31 = require("react");
5594
- 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");
5595
5944
  function RecordDetail({
5596
5945
  collection,
5597
5946
  recordId,
@@ -5607,23 +5956,23 @@ function RecordDetail({
5607
5956
  tenant,
5608
5957
  recordId
5609
5958
  });
5610
- const [editing, setEditing] = (0, import_react31.useState)(false);
5959
+ const [editing, setEditing] = (0, import_react32.useState)(false);
5611
5960
  const record = records.find((candidate) => candidate.id === recordId);
5612
5961
  if (error) {
5613
- 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 }) });
5614
5963
  }
5615
5964
  if (!schema || loading) {
5616
- 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" });
5617
5966
  }
5618
5967
  if (!record) {
5619
- 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: [
5620
5969
  "That ",
5621
5970
  schema.name.toLowerCase(),
5622
5971
  " is not available."
5623
5972
  ] });
5624
5973
  }
5625
5974
  if (editing) {
5626
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5975
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5627
5976
  RecordForm,
5628
5977
  {
5629
5978
  collection,
@@ -5637,12 +5986,12 @@ function RecordDetail({
5637
5986
  );
5638
5987
  }
5639
5988
  const writable = canWrite && !readOnly;
5640
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cls("b316-card b316-detail", className), style, children: [
5641
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-detail-head", children: [
5642
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("h3", { className: "b316-detail-title", children: record.title ?? schema.name }),
5643
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-detail-actions", children: [
5644
- writable ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: () => setEditing(true), children: "Edit" }) : null,
5645
- 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)(
5646
5995
  ConfirmButton,
5647
5996
  {
5648
5997
  className: "b316-button-quiet b316-danger",
@@ -5655,15 +6004,15 @@ function RecordDetail({
5655
6004
  children: "Delete"
5656
6005
  }
5657
6006
  ) : null,
5658
- 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
5659
6008
  ] })
5660
6009
  ] }),
5661
- /* @__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: [
5662
- /* @__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: [
5663
6012
  field.label,
5664
- (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
5665
6014
  ] }),
5666
- /* @__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)(
5667
6016
  FieldCell,
5668
6017
  {
5669
6018
  value: record.fields[field.key] ?? null,
@@ -5677,8 +6026,8 @@ function RecordDetail({
5677
6026
  }
5678
6027
 
5679
6028
  // src/SubscriptionManager.tsx
5680
- var import_react32 = require("react");
5681
- var import_jsx_runtime32 = require("react/jsx-runtime");
6029
+ var import_react33 = require("react");
6030
+ var import_jsx_runtime34 = require("react/jsx-runtime");
5682
6031
  function statusLabel(status2) {
5683
6032
  const words = status2.toLowerCase().split("_");
5684
6033
  return words.map((w, i) => i === 0 ? w.charAt(0).toUpperCase() + w.slice(1) : w).join(" ");
@@ -5718,16 +6067,16 @@ function SubscriptionManager({
5718
6067
  style
5719
6068
  }) {
5720
6069
  const { client, token, loading: sessionLoading } = useBase316();
5721
- const [subscription, setSubscription] = (0, import_react32.useState)(null);
5722
- const [loading, setLoading] = (0, import_react32.useState)(true);
5723
- const [managedBy, setManagedBy] = (0, import_react32.useState)(null);
5724
- const [schedule, setSchedule] = (0, import_react32.useState)([]);
5725
- const [busy, setBusy] = (0, import_react32.useState)(false);
5726
- const [error, setError] = (0, import_react32.useState)(null);
5727
- const [step, setStep] = (0, import_react32.useState)({ kind: "idle" });
5728
- const [reason, setReason] = (0, import_react32.useState)(null);
5729
- const [comment, setComment] = (0, import_react32.useState)("");
5730
- 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 () => {
5731
6080
  if (!token) {
5732
6081
  setSubscription(null);
5733
6082
  setLoading(false);
@@ -5745,7 +6094,7 @@ function SubscriptionManager({
5745
6094
  setLoading(false);
5746
6095
  }
5747
6096
  }, [client, token]);
5748
- (0, import_react32.useEffect)(() => {
6097
+ (0, import_react33.useEffect)(() => {
5749
6098
  void load();
5750
6099
  }, [load]);
5751
6100
  const act = async (change, failure) => {
@@ -5763,29 +6112,29 @@ function SubscriptionManager({
5763
6112
  }
5764
6113
  };
5765
6114
  if (sessionLoading || loading) {
5766
- 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" });
5767
6116
  }
5768
6117
  if (!token) {
5769
- 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." });
5770
6119
  }
5771
6120
  if (error) {
5772
- 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 }) });
5773
6122
  }
5774
6123
  if (!subscription) {
5775
- 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." });
5776
6125
  }
5777
6126
  const renews = new Date(subscription.currentPeriodEnd).toLocaleDateString();
5778
6127
  const next = schedule[0] ?? null;
5779
6128
  const nextOn = next?.effectiveAt ? new Date(next.effectiveAt).toLocaleDateString() : renews;
5780
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: cls("b316-card", className), style, children: [
5781
- error ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
5782
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-plan-name", children: subscription.planVersion.plan.name }),
5783
- /* @__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: [
5784
6133
  statusLabel(subscription.status),
5785
6134
  " \xB7 ",
5786
6135
  subscription.cancelAtPeriodEnd ? `Ends ${renews}` : `Renews ${renews}`
5787
6136
  ] }),
5788
- 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: [
5789
6138
  "Moves to ",
5790
6139
  next.plan.name,
5791
6140
  " on ",
@@ -5793,7 +6142,7 @@ function SubscriptionManager({
5793
6142
  ". You keep ",
5794
6143
  subscription.planVersion.plan.name,
5795
6144
  " until then.",
5796
- /* @__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)(
5797
6146
  "button",
5798
6147
  {
5799
6148
  type: "button",
@@ -5818,17 +6167,17 @@ function SubscriptionManager({
5818
6167
  }
5819
6168
  ) })
5820
6169
  ] }) : null,
5821
- 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: [
5822
6171
  "Provided by ",
5823
6172
  managedBy.name ?? "the organization that manages your account",
5824
6173
  ". Ask them to change or cancel it."
5825
- ] }) : subscription.cancelAtPeriodEnd ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { children: [
5826
- /* @__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: [
5827
6176
  "This subscription will not renew. You keep access until ",
5828
6177
  renews,
5829
6178
  "."
5830
6179
  ] }),
5831
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6180
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
5832
6181
  "button",
5833
6182
  {
5834
6183
  type: "button",
@@ -5838,14 +6187,14 @@ function SubscriptionManager({
5838
6187
  children: busy ? "Working\u2026" : "Resume subscription"
5839
6188
  }
5840
6189
  )
5841
- ] }) : step.kind === "offer" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("section", { style: { marginTop: 14 }, "aria-label": "Retention offer", children: [
5842
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-plan-name", children: step.cancellation.offer.headline ?? "Before you go" }),
5843
- /* @__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(
5844
6193
  step.cancellation.offer,
5845
6194
  step.cancellation.currency
5846
6195
  )}.` }),
5847
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
5848
- /* @__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)(
5849
6198
  "button",
5850
6199
  {
5851
6200
  type: "button",
@@ -5858,7 +6207,7 @@ function SubscriptionManager({
5858
6207
  children: busy ? "Working\u2026" : "Accept offer and stay"
5859
6208
  }
5860
6209
  ),
5861
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6210
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
5862
6211
  "button",
5863
6212
  {
5864
6213
  type: "button",
@@ -5872,12 +6221,12 @@ function SubscriptionManager({
5872
6221
  }
5873
6222
  )
5874
6223
  ] }),
5875
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("p", { className: "b316-muted", children: [
6224
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
5876
6225
  "If you cancel, you keep access until ",
5877
6226
  renews,
5878
6227
  "."
5879
6228
  ] })
5880
- ] }) : step.kind === "survey" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
6229
+ ] }) : step.kind === "survey" ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
5881
6230
  "form",
5882
6231
  {
5883
6232
  style: { marginTop: 14 },
@@ -5897,15 +6246,15 @@ function SubscriptionManager({
5897
6246
  }, "Could not cancel. Try again.");
5898
6247
  },
5899
6248
  children: [
5900
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("p", { className: "b316-muted", children: [
6249
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "b316-muted", children: [
5901
6250
  "You keep access until ",
5902
6251
  renews,
5903
6252
  ". It will not renew after that."
5904
6253
  ] }),
5905
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("fieldset", { className: "b316-fieldset", children: [
5906
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("legend", { className: "b316-label", children: "Why are you leaving? (optional)" }),
5907
- REASONS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
5908
- /* @__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)(
5909
6258
  "input",
5910
6259
  {
5911
6260
  type: "radio",
@@ -5915,12 +6264,12 @@ function SubscriptionManager({
5915
6264
  onChange: () => setReason(option.value)
5916
6265
  }
5917
6266
  ),
5918
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: option.label })
6267
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { children: option.label })
5919
6268
  ] }, option.value))
5920
6269
  ] }),
5921
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { className: "b316-field", children: [
5922
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "b316-label", children: "Anything else? (optional)" }),
5923
- /* @__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)(
5924
6273
  "textarea",
5925
6274
  {
5926
6275
  className: "b316-input",
@@ -5931,9 +6280,9 @@ function SubscriptionManager({
5931
6280
  }
5932
6281
  )
5933
6282
  ] }),
5934
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
5935
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("button", { type: "submit", className: "b316-button b316-button-secondary", disabled: busy, children: busy ? "Working\u2026" : "Cancel subscription" }),
5936
- /* @__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)(
5937
6286
  "button",
5938
6287
  {
5939
6288
  type: "button",
@@ -5949,7 +6298,7 @@ function SubscriptionManager({
5949
6298
  ] })
5950
6299
  ]
5951
6300
  }
5952
- ) : /* @__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)(
5953
6302
  "button",
5954
6303
  {
5955
6304
  type: "button",
@@ -5967,11 +6316,11 @@ function SubscriptionManager({
5967
6316
  }
5968
6317
 
5969
6318
  // src/BillingPortal.tsx
5970
- var import_react36 = require("react");
6319
+ var import_react37 = require("react");
5971
6320
 
5972
6321
  // src/CreditBalances.tsx
5973
- var import_react33 = require("react");
5974
- var import_jsx_runtime33 = require("react/jsx-runtime");
6322
+ var import_react34 = require("react");
6323
+ var import_jsx_runtime35 = require("react/jsx-runtime");
5975
6324
  function units(value) {
5976
6325
  return value === null ? "Unlimited" : Number(value).toLocaleString("en");
5977
6326
  }
@@ -6006,10 +6355,10 @@ function Feature({
6006
6355
  }) {
6007
6356
  const { client, token } = useBase316();
6008
6357
  const setting = feature.autoRecharge;
6009
- const [busy, setBusy] = (0, import_react33.useState)(false);
6010
- const [error, setError] = (0, import_react33.useState)(null);
6011
- const [saved, setSaved] = (0, import_react33.useState)(null);
6012
- 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 ?? "");
6013
6362
  const unit = feature.unit ? ` ${feature.unit}` : "";
6014
6363
  const warning = status(feature);
6015
6364
  const buy = async () => {
@@ -6063,33 +6412,33 @@ function Feature({
6063
6412
  setBusy(false);
6064
6413
  }
6065
6414
  };
6066
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-card b316-credit-balance", children: [
6067
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-label", children: feature.featureName }),
6068
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { children: [
6069
- /* @__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) }),
6070
6419
  unit,
6071
6420
  " left"
6072
6421
  ] }),
6073
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-muted", children: [
6422
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-muted", children: [
6074
6423
  feature.allowance === null ? "Unlimited allowance" : `${units(feature.allowanceRemaining)} of ${units(feature.allowance)} included this period`,
6075
6424
  " ",
6076
6425
  "\xB7 ",
6077
6426
  units(feature.purchasedRemaining),
6078
6427
  " purchased"
6079
6428
  ] }),
6080
- warning && !managed ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-error", role: "alert", children: warning }) : null,
6081
- error ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6082
- saved ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-notice", role: "status", children: saved }) : null,
6083
- managed || feature.packs.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
6084
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-row", style: { marginTop: 12 }, children: [
6085
- /* @__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)(
6086
6435
  "select",
6087
6436
  {
6088
6437
  className: "b316-input",
6089
6438
  "aria-label": "Pack to buy",
6090
6439
  value: pack,
6091
6440
  onChange: (event) => setPack(event.target.value),
6092
- 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: [
6093
6442
  option.name,
6094
6443
  " \u2014 ",
6095
6444
  units(option.units),
@@ -6098,7 +6447,7 @@ function Feature({
6098
6447
  ] }, option.id))
6099
6448
  }
6100
6449
  ),
6101
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6450
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6102
6451
  "button",
6103
6452
  {
6104
6453
  type: "button",
@@ -6109,19 +6458,19 @@ function Feature({
6109
6458
  }
6110
6459
  )
6111
6460
  ] }),
6112
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("form", { onSubmit: save, style: { marginTop: 16 }, children: [
6113
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("label", { className: "b316-checkbox", children: [
6114
- /* @__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 }),
6115
6464
  " ",
6116
6465
  "Buy credits automatically when my balance runs low"
6117
6466
  ] }),
6118
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("label", { className: "b316-field", children: [
6119
- /* @__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: [
6120
6469
  "When fewer than this many",
6121
6470
  unit,
6122
6471
  " are left"
6123
6472
  ] }),
6124
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6473
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6125
6474
  "input",
6126
6475
  {
6127
6476
  className: "b316-input",
@@ -6132,21 +6481,21 @@ function Feature({
6132
6481
  }
6133
6482
  )
6134
6483
  ] }),
6135
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("label", { className: "b316-field", children: [
6136
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "b316-label", children: "Buy" }),
6137
- /* @__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)(
6138
6487
  "select",
6139
6488
  {
6140
6489
  className: "b316-input",
6141
6490
  name: "creditPackId",
6142
6491
  defaultValue: setting?.creditPackId ?? feature.packs[0]?.id,
6143
- 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))
6144
6493
  }
6145
6494
  )
6146
6495
  ] }),
6147
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("label", { className: "b316-field", children: [
6148
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "b316-label", children: "At most this many times a month" }),
6149
- /* @__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)(
6150
6499
  "input",
6151
6500
  {
6152
6501
  className: "b316-input",
@@ -6156,13 +6505,13 @@ function Feature({
6156
6505
  }
6157
6506
  )
6158
6507
  ] }),
6159
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("label", { className: "b316-field", children: [
6160
- /* @__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: [
6161
6510
  "Spending at most (",
6162
6511
  setting?.currency ?? feature.packs[0]?.currency ?? "USD",
6163
6512
  ") a month"
6164
6513
  ] }),
6165
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6514
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6166
6515
  "input",
6167
6516
  {
6168
6517
  className: "b316-input",
@@ -6172,16 +6521,16 @@ function Feature({
6172
6521
  }
6173
6522
  )
6174
6523
  ] }),
6175
- /* @__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" })
6176
6525
  ] })
6177
6526
  ] })
6178
6527
  ] });
6179
6528
  }
6180
6529
  function CreditBalances({ onChange, className, style }) {
6181
6530
  const { client, token, loading: sessionLoading } = useBase316();
6182
- const [state, setState] = (0, import_react33.useState)({ kind: "loading" });
6183
- const [version, setVersion] = (0, import_react33.useState)(0);
6184
- (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)(() => {
6185
6534
  if (!token) return;
6186
6535
  let cancelled = false;
6187
6536
  client.billing.credits(token).then((credits2) => {
@@ -6194,24 +6543,24 @@ function CreditBalances({ onChange, className, style }) {
6194
6543
  cancelled = true;
6195
6544
  };
6196
6545
  }, [client, token, version]);
6197
- 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 });
6198
6547
  if (sessionLoading || !token || state.kind === "loading") return null;
6199
6548
  if (state.kind === "error") {
6200
6549
  return wrap(
6201
- /* @__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." }) })
6202
6551
  );
6203
6552
  }
6204
6553
  const { credits } = state;
6205
6554
  if (credits.features.length === 0) return null;
6206
6555
  return wrap(
6207
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
6208
- 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: [
6209
6558
  "Credits for this account come from",
6210
6559
  " ",
6211
6560
  credits.managedBy.name ?? "the organization that manages it",
6212
6561
  ", which manages them."
6213
6562
  ] }) : null,
6214
- credits.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6563
+ credits.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6215
6564
  Feature,
6216
6565
  {
6217
6566
  feature,
@@ -6228,19 +6577,19 @@ function CreditBalances({ onChange, className, style }) {
6228
6577
  }
6229
6578
 
6230
6579
  // src/PaymentMethod.tsx
6231
- var import_react34 = require("react");
6232
- var import_jsx_runtime34 = require("react/jsx-runtime");
6580
+ var import_react35 = require("react");
6581
+ var import_jsx_runtime36 = require("react/jsx-runtime");
6233
6582
  function brandName(brand) {
6234
6583
  if (!brand) return "Card";
6235
6584
  return brand.charAt(0).toUpperCase() + brand.slice(1);
6236
6585
  }
6237
6586
  function PaymentMethod({ returnUrl, className, style }) {
6238
6587
  const { client, token, loading: sessionLoading } = useBase316();
6239
- const [state, setState] = (0, import_react34.useState)({ kind: "loading" });
6240
- const [busy, setBusy] = (0, import_react34.useState)(false);
6241
- const [error, setError] = (0, import_react34.useState)(null);
6242
- const [version, setVersion] = (0, import_react34.useState)(0);
6243
- (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)(() => {
6244
6593
  if (!token) return;
6245
6594
  let cancelled = false;
6246
6595
  client.billing.paymentMethods(token).then((result) => {
@@ -6256,7 +6605,7 @@ function PaymentMethod({ returnUrl, className, style }) {
6256
6605
  cancelled = true;
6257
6606
  };
6258
6607
  }, [client, token, version]);
6259
- 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 });
6260
6609
  if (sessionLoading) return wrap("Loading\u2026");
6261
6610
  if (!token) return wrap("Sign in to manage your payment method.");
6262
6611
  switch (state.kind) {
@@ -6264,11 +6613,11 @@ function PaymentMethod({ returnUrl, className, style }) {
6264
6613
  return wrap("Loading\u2026");
6265
6614
  case "error":
6266
6615
  return wrap(
6267
- /* @__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." })
6268
6617
  );
6269
6618
  case "managed":
6270
6619
  return wrap(
6271
- /* @__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." })
6272
6621
  );
6273
6622
  }
6274
6623
  const card = state.cards.find((saved) => saved.isDefault) ?? null;
@@ -6287,31 +6636,31 @@ function PaymentMethod({ returnUrl, className, style }) {
6287
6636
  }
6288
6637
  };
6289
6638
  return wrap(
6290
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
6291
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-label", children: "Payment method" }),
6292
- card ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
6293
- /* @__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: [
6294
6643
  brandName(card.brand),
6295
6644
  " ending ",
6296
6645
  card.last4 ?? "????"
6297
6646
  ] }),
6298
- 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: [
6299
6648
  "Expires ",
6300
6649
  String(card.expMonth).padStart(2, "0"),
6301
6650
  "/",
6302
6651
  card.expYear
6303
6652
  ] }) : null
6304
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "b316-muted", children: "No card on file." }),
6305
- others.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { style: { marginTop: 12 }, children: [
6306
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-label", children: "Other saved cards" }),
6307
- others.map((saved) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-row", style: { marginTop: 6 }, children: [
6308
- /* @__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: [
6309
6658
  brandName(saved.brand),
6310
6659
  " ending ",
6311
6660
  saved.last4 ?? "????"
6312
6661
  ] }),
6313
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { children: [
6314
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6662
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { children: [
6663
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6315
6664
  "button",
6316
6665
  {
6317
6666
  type: "button",
@@ -6325,7 +6674,7 @@ function PaymentMethod({ returnUrl, className, style }) {
6325
6674
  }
6326
6675
  ),
6327
6676
  " ",
6328
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6677
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6329
6678
  "button",
6330
6679
  {
6331
6680
  type: "button",
@@ -6341,8 +6690,8 @@ function PaymentMethod({ returnUrl, className, style }) {
6341
6690
  ] })
6342
6691
  ] }, saved.id))
6343
6692
  ] }) : null,
6344
- error ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6345
- /* @__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)(
6346
6695
  "button",
6347
6696
  {
6348
6697
  type: "button",
@@ -6371,8 +6720,8 @@ function PaymentMethod({ returnUrl, className, style }) {
6371
6720
  }
6372
6721
 
6373
6722
  // src/PlanChangeReview.tsx
6374
- var import_react35 = require("react");
6375
- var import_jsx_runtime35 = require("react/jsx-runtime");
6723
+ var import_react36 = require("react");
6724
+ var import_jsx_runtime37 = require("react/jsx-runtime");
6376
6725
  function money5(amount, currency) {
6377
6726
  if (amount === null) return "\u2014";
6378
6727
  const value = Number(amount);
@@ -6405,12 +6754,12 @@ function PlanChangeReview({
6405
6754
  style
6406
6755
  }) {
6407
6756
  const { client, token } = useBase316();
6408
- const [timing, setTiming] = (0, import_react35.useState)(void 0);
6409
- const [preview, setPreview] = (0, import_react35.useState)(null);
6410
- const [error, setError] = (0, import_react35.useState)(null);
6411
- const [needsCard, setNeedsCard] = (0, import_react35.useState)(false);
6412
- const [busy, setBusy] = (0, import_react35.useState)(false);
6413
- (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)(() => {
6414
6763
  if (!token) return;
6415
6764
  let cancelled = false;
6416
6765
  client.billing.previewPlanChange(token, planVersionId, timing).then((result) => {
@@ -6427,7 +6776,7 @@ function PlanChangeReview({
6427
6776
  cancelled = true;
6428
6777
  };
6429
6778
  }, [client, token, planVersionId, timing]);
6430
- const confirm = (0, import_react35.useCallback)(async () => {
6779
+ const confirm = (0, import_react36.useCallback)(async () => {
6431
6780
  if (!token || !preview) return;
6432
6781
  setBusy(true);
6433
6782
  setError(null);
@@ -6448,7 +6797,7 @@ function PlanChangeReview({
6448
6797
  setBusy(false);
6449
6798
  }
6450
6799
  }, [client, token, preview, planVersionId, onDone]);
6451
- const addCard = (0, import_react35.useCallback)(async () => {
6800
+ const addCard = (0, import_react36.useCallback)(async () => {
6452
6801
  if (onNeedsCard) {
6453
6802
  onNeedsCard();
6454
6803
  return;
@@ -6462,12 +6811,12 @@ function PlanChangeReview({
6462
6811
  setError("Cards cannot be added here right now.");
6463
6812
  }
6464
6813
  }, [client, token, onNeedsCard]);
6465
- 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 });
6466
6815
  if (error && !preview) {
6467
6816
  return card(
6468
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
6469
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: error }),
6470
- 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
6471
6820
  ] })
6472
6821
  );
6473
6822
  }
@@ -6480,26 +6829,26 @@ function PlanChangeReview({
6480
6829
  const otherReason = preview.timings[other]?.reason ?? null;
6481
6830
  const changes = preview.entitlements.filter((change) => change.change !== "UNCHANGED");
6482
6831
  return card(
6483
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
6484
- /* @__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: [
6485
6834
  "Change to ",
6486
6835
  to.planName
6487
6836
  ] }),
6488
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-muted", children: [
6837
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-muted", children: [
6489
6838
  "From ",
6490
6839
  from.planName
6491
6840
  ] }),
6492
- error ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6493
- 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: [
6494
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("tr", { children: [
6495
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("th", { children: "Feature" }),
6496
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("th", { children: from.planName }),
6497
- /* @__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 })
6498
6847
  ] }) }),
6499
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("tbody", { children: changes.map((change) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("tr", { children: [
6500
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("td", { children: change.featureName }),
6501
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("td", { children: limitText(change.before, change.type) }),
6502
- /* @__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)(
6503
6852
  "td",
6504
6853
  {
6505
6854
  className: change.change === "GAINED" || change.change === "INCREASED" ? "b316-review-gain" : "b316-review-loss",
@@ -6508,40 +6857,40 @@ function PlanChangeReview({
6508
6857
  )
6509
6858
  ] }, change.featureId)) })
6510
6859
  ] }),
6511
- 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: [
6512
6861
  "The change happens now. Your trial carries on until ",
6513
6862
  day4(now.trialEndsAt),
6514
6863
  ", and nothing is charged before then."
6515
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { children: [
6516
- Number(now.credit) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-row", children: [
6517
- /* @__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: [
6518
6867
  "Credit for the unused part of ",
6519
6868
  from.planName
6520
6869
  ] }),
6521
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "b316-num", children: [
6870
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "b316-num", children: [
6522
6871
  "\u2212",
6523
6872
  money5(now.credit, from.currency)
6524
6873
  ] })
6525
6874
  ] }) : null,
6526
- Number(now.closingUsage) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-row", children: [
6527
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "b316-muted", children: "Usage so far this period" }),
6528
- /* @__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) })
6529
6878
  ] }) : null,
6530
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-row", children: [
6531
- /* @__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: [
6532
6881
  to.planName,
6533
6882
  ", ",
6534
6883
  day4(now.newPeriod.start),
6535
6884
  " \u2013 ",
6536
6885
  day4(now.newPeriod.end)
6537
6886
  ] }),
6538
- /* @__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) })
6539
6888
  ] }),
6540
- now.net !== null ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-row b316-invoice-total", children: [
6541
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { children: "Due now" }),
6542
- /* @__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) })
6543
6892
  ] }) : null
6544
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("p", { children: [
6893
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("p", { children: [
6545
6894
  "You keep ",
6546
6895
  from.planName,
6547
6896
  " until ",
@@ -6554,7 +6903,7 @@ function PlanChangeReview({
6554
6903
  preview.atPeriodEnd.nextInvoice.currency
6555
6904
  )}.` : ""
6556
6905
  ] }),
6557
- otherOpen ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6906
+ otherOpen ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6558
6907
  "button",
6559
6908
  {
6560
6909
  type: "button",
@@ -6565,12 +6914,12 @@ function PlanChangeReview({
6565
6914
  },
6566
6915
  children: other === "NOW" ? "Change now instead" : "Wait until the end of the period instead"
6567
6916
  }
6568
- ) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: "b316-muted", children: TIMING_CLOSED[otherReason] }) : null,
6569
- 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: [
6570
6919
  "A card is needed for a change that is charged now.",
6571
- /* @__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" }) })
6572
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-review-actions", children: [
6573
- /* @__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)(
6574
6923
  "button",
6575
6924
  {
6576
6925
  type: "button",
@@ -6580,7 +6929,7 @@ function PlanChangeReview({
6580
6929
  children: busy ? "Working\u2026" : preview.timing === "NOW" ? `Change to ${to.planName} now` : `Schedule ${to.planName}`
6581
6930
  }
6582
6931
  ),
6583
- 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: [
6584
6933
  "Keep ",
6585
6934
  from.planName
6586
6935
  ] }) : null
@@ -6590,7 +6939,7 @@ function PlanChangeReview({
6590
6939
  }
6591
6940
 
6592
6941
  // src/BillingPortal.tsx
6593
- var import_jsx_runtime36 = require("react/jsx-runtime");
6942
+ var import_jsx_runtime38 = require("react/jsx-runtime");
6594
6943
  function BillingPortal({
6595
6944
  returnUrl,
6596
6945
  featuredPlanKey,
@@ -6600,12 +6949,12 @@ function BillingPortal({
6600
6949
  style
6601
6950
  }) {
6602
6951
  const { client, token, loading: sessionLoading } = useBase316();
6603
- const [overview, setOverview] = (0, import_react36.useState)(null);
6604
- const [failed, setFailed] = (0, import_react36.useState)(false);
6605
- const [version, setVersion] = (0, import_react36.useState)(0);
6606
- const [reviewing, setReviewing] = (0, import_react36.useState)(null);
6607
- const [notice, setNotice] = (0, import_react36.useState)(null);
6608
- (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)(() => {
6609
6958
  if (!token) return;
6610
6959
  let cancelled = false;
6611
6960
  client.billing.subscription(token).then((result) => {
@@ -6624,28 +6973,28 @@ function BillingPortal({
6624
6973
  cancelled = true;
6625
6974
  };
6626
6975
  }, [client, token, version]);
6627
- const refresh = (0, import_react36.useCallback)(() => {
6976
+ const refresh = (0, import_react37.useCallback)(() => {
6628
6977
  setNotice(null);
6629
6978
  setVersion((value) => value + 1);
6630
6979
  }, []);
6631
- const shell = (content) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cls("b316-billing-portal", className), style, children: content });
6632
- if (sessionLoading) return shell(/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-card", children: "Loading\u2026" }));
6633
- 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." }));
6634
6983
  if (failed) {
6635
6984
  return shell(
6636
- /* @__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." }) })
6637
6986
  );
6638
6987
  }
6639
- 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" }));
6640
6989
  const { subscription, managedBy, quantityPriced } = overview;
6641
6990
  const canChange = Boolean(subscription) && !managedBy;
6642
6991
  return shell(
6643
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
6644
- notice ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-card b316-notice", role: "status", children: notice }) : null,
6645
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SubscriptionManager, { onChange: refresh }, `plan-${version}`),
6646
- canChange ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(UpcomingInvoice, {}, `next-${version}`) : null,
6647
- canChange && quantityPriced ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SeatManager, { unitLabel, onChange: refresh }, `seats-${version}`) : null,
6648
- 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)(
6649
6998
  PlanChangeReview,
6650
6999
  {
6651
7000
  planVersionId: reviewing,
@@ -6658,9 +7007,9 @@ function BillingPortal({
6658
7007
  );
6659
7008
  }
6660
7009
  }
6661
- ) : /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("section", { children: [
6662
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("h2", { className: "b316-billing-portal-section-title", children: subscription ? "Change plan" : "Choose a plan" }),
6663
- /* @__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)(
6664
7013
  PricingTable,
6665
7014
  {
6666
7015
  featuredPlanKey,
@@ -6672,17 +7021,17 @@ function BillingPortal({
6672
7021
  `plans-${version}`
6673
7022
  )
6674
7023
  ] }),
6675
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(CreditBalances, {}, `credits-${version}`),
6676
- managedBy ? null : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PaymentMethod, { returnUrl }, `card-${version}`),
6677
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Invoices, {}, `invoices-${version}`),
6678
- 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
6679
7028
  ] })
6680
7029
  );
6681
7030
  }
6682
7031
 
6683
7032
  // src/ApiKeyManager.tsx
6684
- var import_react37 = require("react");
6685
- var import_jsx_runtime37 = require("react/jsx-runtime");
7033
+ var import_react38 = require("react");
7034
+ var import_jsx_runtime39 = require("react/jsx-runtime");
6686
7035
  function duration(seconds) {
6687
7036
  if (seconds % 3600 === 0) {
6688
7037
  return `${seconds / 3600}h`;
@@ -6699,17 +7048,17 @@ function ApiKeyManager({
6699
7048
  audience
6700
7049
  }) {
6701
7050
  const { client, token, loading: sessionLoading } = useBase316();
6702
- const [resources, setResources] = (0, import_react37.useState)([]);
6703
- const [credentials, setCredentials] = (0, import_react37.useState)([]);
6704
- const [loading, setLoading] = (0, import_react37.useState)(true);
6705
- const [busy, setBusy] = (0, import_react37.useState)(false);
6706
- const [error, setError] = (0, import_react37.useState)(null);
6707
- const [creating, setCreating] = (0, import_react37.useState)(false);
6708
- const [name, setName] = (0, import_react37.useState)("");
6709
- const [chosen, setChosen] = (0, import_react37.useState)([]);
6710
- const [resourceId, setResourceId] = (0, import_react37.useState)(null);
6711
- const [issued, setIssued] = (0, import_react37.useState)(null);
6712
- 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 () => {
6713
7062
  if (!token) {
6714
7063
  setLoading(false);
6715
7064
  return;
@@ -6730,20 +7079,20 @@ function ApiKeyManager({
6730
7079
  setLoading(false);
6731
7080
  }
6732
7081
  }, [client, token, audience]);
6733
- (0, import_react37.useEffect)(() => {
7082
+ (0, import_react38.useEffect)(() => {
6734
7083
  void load();
6735
7084
  }, [load]);
6736
7085
  if (sessionLoading || loading) {
6737
- 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" });
6738
7087
  }
6739
7088
  if (!token) {
6740
- 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." });
6741
7090
  }
6742
7091
  if (error) {
6743
- 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 }) });
6744
7093
  }
6745
7094
  if (resources.length === 0) {
6746
- 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." });
6747
7096
  }
6748
7097
  const resource = resources.find((item) => item.id === resourceId) ?? resources[0];
6749
7098
  const reset = () => {
@@ -6752,37 +7101,37 @@ function ApiKeyManager({
6752
7101
  setChosen([]);
6753
7102
  setIssued(null);
6754
7103
  };
6755
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: cls("b316-card", className), style, children: [
6756
- error ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6757
- 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)(
6758
7107
  "select",
6759
7108
  {
6760
7109
  className: "b316-input",
6761
7110
  value: resource.id,
6762
7111
  onChange: (event) => setResourceId(event.target.value),
6763
7112
  style: { marginBottom: 14 },
6764
- 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))
6765
7114
  }
6766
- ) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-plan-name", children: resource.name }),
6767
- 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: [
6768
7117
  resource.rateLimit.requestsPerWindow,
6769
7118
  " requests per",
6770
7119
  " ",
6771
7120
  duration(resource.rateLimit.windowSeconds),
6772
7121
  resource.rateLimit.burst > resource.rateLimit.requestsPerWindow ? `, bursting to ${resource.rateLimit.burst}` : null
6773
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-muted", children: "No rate limit." }),
6774
- 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: [
6775
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { children: [
6776
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-plan-name", children: credential.name }),
6777
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-muted", children: [
6778
- /* @__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 }),
6779
7128
  credential.secretLastFour ? ` \xB7 \u2026${credential.secretLastFour}` : null,
6780
7129
  credential.disabled ? " \xB7 Disabled" : null
6781
7130
  ] }),
6782
- /* @__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(", ") })
6783
7132
  ] }),
6784
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { style: { display: "flex", gap: 8 }, children: [
6785
- /* @__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)(
6786
7135
  "button",
6787
7136
  {
6788
7137
  type: "button",
@@ -6811,7 +7160,7 @@ function ApiKeyManager({
6811
7160
  children: "Rotate"
6812
7161
  }
6813
7162
  ),
6814
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7163
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6815
7164
  ConfirmButton,
6816
7165
  {
6817
7166
  className: "b316-button b316-button-secondary",
@@ -6835,11 +7184,11 @@ function ApiKeyManager({
6835
7184
  )
6836
7185
  ] })
6837
7186
  ] }, credential.clientId)) }),
6838
- issued ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-notice", style: { marginTop: 14 }, children: [
6839
- /* @__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." }),
6840
7189
  " It is shown once and cannot be retrieved again.",
6841
- /* @__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 }) }),
6842
- /* @__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)(
6843
7192
  "button",
6844
7193
  {
6845
7194
  type: "button",
@@ -6852,7 +7201,7 @@ function ApiKeyManager({
6852
7201
  children: "Copy"
6853
7202
  }
6854
7203
  ),
6855
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7204
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6856
7205
  "button",
6857
7206
  {
6858
7207
  type: "button",
@@ -6863,8 +7212,8 @@ function ApiKeyManager({
6863
7212
  }
6864
7213
  )
6865
7214
  ] }) : null,
6866
- creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { style: { marginTop: 14 }, children: [
6867
- /* @__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)(
6868
7217
  "input",
6869
7218
  {
6870
7219
  className: "b316-input",
@@ -6873,9 +7222,9 @@ function ApiKeyManager({
6873
7222
  onChange: (event) => setName(event.target.value)
6874
7223
  }
6875
7224
  ),
6876
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { style: { marginTop: 10 }, children: [
6877
- resource.availableScopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("label", { className: "b316-checkbox", children: [
6878
- /* @__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)(
6879
7228
  "input",
6880
7229
  {
6881
7230
  type: "checkbox",
@@ -6885,19 +7234,19 @@ function ApiKeyManager({
6885
7234
  )
6886
7235
  }
6887
7236
  ),
6888
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("code", { children: scope.key }),
6889
- 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: [
6890
7239
  " \u2014 ",
6891
7240
  scope.description
6892
7241
  ] }) : null
6893
7242
  ] }, scope.key)),
6894
- resource.lockedScopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("label", { className: "b316-checkbox b316-muted", children: [
6895
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("input", { type: "checkbox", disabled: true }),
6896
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("code", { children: scope.key }),
6897
- /* @__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" })
6898
7247
  ] }, scope.key))
6899
7248
  ] }),
6900
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7249
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6901
7250
  "button",
6902
7251
  {
6903
7252
  type: "button",
@@ -6931,7 +7280,7 @@ function ApiKeyManager({
6931
7280
  children: "Create key"
6932
7281
  }
6933
7282
  ),
6934
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7283
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6935
7284
  "button",
6936
7285
  {
6937
7286
  type: "button",
@@ -6942,7 +7291,7 @@ function ApiKeyManager({
6942
7291
  }
6943
7292
  )
6944
7293
  ] }) : null,
6945
- !creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7294
+ !creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
6946
7295
  "button",
6947
7296
  {
6948
7297
  type: "button",
@@ -7017,26 +7366,45 @@ var MANIFEST = [
7017
7366
  {
7018
7367
  name: "SignIn",
7019
7368
  kind: "component",
7020
- 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`).",
7021
7370
  useWhen: "The application renders its own sign-in rather than redirecting to the hosted page.",
7022
7371
  requires: [],
7023
7372
  props: [
7024
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
+ },
7025
7379
  {
7026
7380
  name: "passkeys",
7027
- summary: "Offer passkeys where supported. On by default.",
7381
+ summary: "`false` hides passkeys; otherwise offered where the environment and browser allow.",
7028
7382
  required: false
7029
7383
  },
7384
+ { name: "magicLink", summary: "`false` hides the emailed sign-in link.", required: false },
7030
7385
  {
7031
7386
  name: "magicLinkRedirectUrl",
7032
- 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.",
7033
7400
  required: false
7034
7401
  },
7035
7402
  {
7036
- name: "phone",
7037
- 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`.",
7038
7405
  required: false
7039
7406
  },
7407
+ { name: "labels", summary: "Wording for the form, for translation.", required: false },
7040
7408
  {
7041
7409
  name: "secondFactorLabels",
7042
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.",
@@ -7046,6 +7414,38 @@ var MANIFEST = [
7046
7414
  ],
7047
7415
  seeAlso: ["SignUp", "ForgotPassword", "SecondFactorStep"]
7048
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
+ },
7049
7449
  {
7050
7450
  name: "SignUp",
7051
7451
  kind: "component",
@@ -7074,6 +7474,21 @@ var MANIFEST = [
7074
7474
  summary: "Wording for the second-factor step, for translation.",
7075
7475
  required: false
7076
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
+ },
7077
7492
  ...appearance
7078
7493
  ],
7079
7494
  seeAlso: ["SignIn", "VerifyEmail", "SecondFactorStep"]
@@ -7846,6 +8261,7 @@ function componentsRequiring(requirement) {
7846
8261
  SecondFactorStep,
7847
8262
  SignIn,
7848
8263
  SignUp,
8264
+ SocialSignIn,
7849
8265
  SubscriptionManager,
7850
8266
  TeamMembers,
7851
8267
  TwoFactorManager,