@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.js CHANGED
@@ -325,6 +325,23 @@ var STYLESHEET_EXTRA = `
325
325
  border-bottom: 2px solid transparent; margin-bottom: -1px;
326
326
  }
327
327
  .b316-tab-on { color: var(--b316-color-text); border-bottom-color: var(--b316-color-primary); }
328
+ .b316-social { display: flex; flex-direction: column; gap: 8px; }
329
+ .b316-social-button {
330
+ display: flex; align-items: center; justify-content: center; gap: 10px;
331
+ width: 100%; min-height: 40px; padding: 9px 14px;
332
+ border: 1px solid; border-radius: calc(var(--b316-radius) / 1.6);
333
+ font: inherit; font-weight: 500; cursor: pointer;
334
+ }
335
+ .b316-social-button:hover:not([disabled]) { filter: brightness(.96); }
336
+ .b316-social-button:focus-visible { outline: 2px solid var(--b316-color-primary); outline-offset: 2px; }
337
+ .b316-social-button[disabled] { opacity: .55; cursor: not-allowed; }
338
+ .b316-social-icon { display: inline-flex; width: 18px; height: 18px; flex: none; }
339
+ .b316-social-icon svg { width: 18px; height: 18px; }
340
+ .b316-divider {
341
+ display: flex; align-items: center; gap: 10px; margin: 14px 0;
342
+ color: var(--b316-color-muted); font-size: .87em;
343
+ }
344
+ .b316-divider::before, .b316-divider::after { content: ""; flex: 1; border-top: 1px solid var(--b316-color-border); }
328
345
  .b316-branding { display: flex; flex-direction: column; gap: 4px; }
329
346
  .b316-branding-logo { max-height: 40px; width: auto; align-self: flex-start; }
330
347
  .b316-branding-name { font-size: 1.5em; font-weight: 650; letter-spacing: -.01em; }
@@ -1607,7 +1624,7 @@ import {
1607
1624
  isPasskeySupported,
1608
1625
  needsSecondFactor
1609
1626
  } from "@base316/sdk";
1610
- import { useEffect as useEffect7, useRef as useRef2, useState as useState7 } from "react";
1627
+ import { useEffect as useEffect8, useRef as useRef2, useState as useState8 } from "react";
1611
1628
 
1612
1629
  // src/SecondFactorStep.tsx
1613
1630
  import {
@@ -1998,33 +2015,233 @@ function SecondFactorStep({
1998
2015
  return /* @__PURE__ */ jsx7("div", { className: cls("b316-mfa", className), style, children: body });
1999
2016
  }
2000
2017
 
2018
+ // src/sign-in-methods.ts
2019
+ import {
2020
+ OAUTH_STATE_COOKIE,
2021
+ createOAuthState
2022
+ } from "@base316/sdk";
2023
+ import { useEffect as useEffect7, useState as useState7 } from "react";
2024
+ var cache = /* @__PURE__ */ new WeakMap();
2025
+ function loadSignInMethods(client) {
2026
+ let pending = cache.get(client);
2027
+ if (!pending) {
2028
+ pending = client.auth.methods();
2029
+ cache.set(client, pending);
2030
+ pending.catch(() => cache.delete(client));
2031
+ }
2032
+ return pending;
2033
+ }
2034
+ function useSignInMethods(client) {
2035
+ const [state, setState] = useState7({ status: "loading", methods: null });
2036
+ useEffect7(() => {
2037
+ let cancelled = false;
2038
+ loadSignInMethods(client).then((methods) => {
2039
+ if (!cancelled) setState({ status: "ready", methods });
2040
+ }).catch(() => {
2041
+ if (!cancelled) setState({ status: "unavailable", methods: null });
2042
+ });
2043
+ return () => {
2044
+ cancelled = true;
2045
+ };
2046
+ }, [client]);
2047
+ return state;
2048
+ }
2049
+ function resolveMethods(methods, props, currentPage) {
2050
+ if (!methods) {
2051
+ return {
2052
+ password: props.password !== false,
2053
+ passkeys: props.passkeys !== false,
2054
+ magicLink: props.magicLink !== false ? props.magicLinkRedirectUrl ?? null : null,
2055
+ phone: props.phone === true,
2056
+ social: [],
2057
+ sso: false,
2058
+ signUp: true,
2059
+ hostedUrl: void 0
2060
+ };
2061
+ }
2062
+ const redirect = props.socialRedirectUrl;
2063
+ const only = Array.isArray(props.social) ? new Set(props.social.map((entry) => entry.toLowerCase())) : null;
2064
+ return {
2065
+ password: methods.password && props.password !== false,
2066
+ passkeys: methods.passkeys && props.passkeys !== false,
2067
+ magicLink: methods.magicLink && props.magicLink !== false ? props.magicLinkRedirectUrl ?? currentPage : null,
2068
+ phone: methods.phone && props.phone !== false,
2069
+ social: redirect && props.social !== false ? methods.social.filter(
2070
+ (option) => !only || only.has(option.slug.toLowerCase()) || only.has(option.provider.toLowerCase())
2071
+ ) : [],
2072
+ sso: Boolean(redirect) && methods.sso && props.sso !== false,
2073
+ signUp: methods.signUp,
2074
+ hostedUrl: methods.hostedUrl
2075
+ };
2076
+ }
2077
+ function beginRedirect(build, appState) {
2078
+ const { state, nonce } = createOAuthState(appState);
2079
+ const secure = window.location.protocol === "https:" ? "; Secure" : "";
2080
+ document.cookie = `${OAUTH_STATE_COOKIE}=${nonce}; Path=/; Max-Age=600; SameSite=Lax${secure}`;
2081
+ window.location.assign(build(state));
2082
+ }
2083
+ function currentPageUrl() {
2084
+ if (typeof window === "undefined") {
2085
+ return null;
2086
+ }
2087
+ return `${window.location.origin}${window.location.pathname}`;
2088
+ }
2089
+
2090
+ // src/social-icons.ts
2091
+ var PROVIDER_ICON = {
2092
+ 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>`,
2093
+ 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>`,
2094
+ 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>`,
2095
+ 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>`,
2096
+ 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>`,
2097
+ 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>`,
2098
+ 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>`,
2099
+ // The four below are the Simple Icons marks (CC0), https://simpleicons.org.
2100
+ 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>`,
2101
+ 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>`,
2102
+ 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>`,
2103
+ 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>`,
2104
+ 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>`
2105
+ };
2106
+
2107
+ // src/SocialButtons.tsx
2108
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
2109
+ function SocialButtons({
2110
+ options,
2111
+ continueWith,
2112
+ disabled,
2113
+ onChoose
2114
+ }) {
2115
+ if (options.length === 0) {
2116
+ return null;
2117
+ }
2118
+ return /* @__PURE__ */ jsx8("div", { className: "b316-social", children: options.map((option) => {
2119
+ const icon = PROVIDER_ICON[option.provider];
2120
+ const light = /^#f{3}(f{3})?$/i.test(option.buttonColor);
2121
+ return /* @__PURE__ */ jsxs7(
2122
+ "button",
2123
+ {
2124
+ type: "button",
2125
+ className: "b316-social-button",
2126
+ "data-provider": option.slug,
2127
+ disabled,
2128
+ style: {
2129
+ background: option.buttonColor,
2130
+ color: option.buttonTextColor,
2131
+ borderColor: light ? "#747775" : option.buttonColor
2132
+ },
2133
+ onClick: () => onChoose(option),
2134
+ children: [
2135
+ icon ? /* @__PURE__ */ jsx8(
2136
+ "span",
2137
+ {
2138
+ className: "b316-social-icon",
2139
+ "aria-hidden": "true",
2140
+ dangerouslySetInnerHTML: { __html: icon }
2141
+ }
2142
+ ) : null,
2143
+ /* @__PURE__ */ jsx8("span", { children: continueWith(option.name, option.provider) })
2144
+ ]
2145
+ },
2146
+ option.slug
2147
+ );
2148
+ }) });
2149
+ }
2150
+
2001
2151
  // src/SignIn.tsx
2002
- import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
2152
+ import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2153
+ var DEFAULT_SIGN_IN_LABELS = {
2154
+ email: "Email",
2155
+ password: "Password",
2156
+ mobileNumber: "Mobile number",
2157
+ code: "Code",
2158
+ tabPassword: "Password",
2159
+ tabMagicLink: "Magic link",
2160
+ tabPhone: "Text message",
2161
+ submit: "Sign in",
2162
+ working: "Working\u2026",
2163
+ emailMeALink: "Email me a link",
2164
+ textMeACode: "Text me a code",
2165
+ includeCountryCode: "Include the country code.",
2166
+ codeSent: (destination) => `We sent a code to ${destination}. It expires in ten minutes.`,
2167
+ useDifferentNumber: "Use a different number",
2168
+ or: "or",
2169
+ passkey: "Sign in with a passkey",
2170
+ continueWith: (name) => `Continue with ${name}`,
2171
+ sso: "Sign in with SSO",
2172
+ ssoEmail: "Work email",
2173
+ ssoContinue: "Continue",
2174
+ back: "Back",
2175
+ checkEmailTitle: "Check your email",
2176
+ checkEmail: (email) => `If an account exists for ${email}, a sign-in link is on its way. It expires shortly and can be used once.`,
2177
+ backToSignIn: "Back to sign in",
2178
+ wrongPassword: "That email and password did not match.",
2179
+ passkeyFailed: "That passkey did not work.",
2180
+ linkInvalid: "That sign-in link is no longer valid. Ask for a new one.",
2181
+ linkFailed: "We could not send that link. Try again.",
2182
+ wrongCode: "That code did not work. Check it, or ask for a new one.",
2183
+ codeFailed: "We could not send a code. Try again.",
2184
+ noMethods: "Signing in is not available right now."
2185
+ };
2003
2186
  function SignIn({
2004
2187
  onSignedIn,
2005
- passkeys = true,
2188
+ password: passwordProp,
2189
+ passkeys: passkeysProp,
2190
+ magicLink: magicLinkProp,
2006
2191
  magicLinkRedirectUrl,
2007
- phone = false,
2192
+ phone: phoneProp,
2193
+ social: socialProp,
2194
+ sso: ssoProp,
2195
+ socialRedirectUrl,
2196
+ socialState,
2197
+ labels: overrides,
2008
2198
  secondFactorLabels,
2009
2199
  className,
2010
2200
  style
2011
2201
  }) {
2202
+ const labels = { ...DEFAULT_SIGN_IN_LABELS, ...overrides };
2012
2203
  const { client, setToken } = useBase316();
2013
- const [email, setEmail] = useState7("");
2014
- const [password, setPassword] = useState7("");
2015
- const [code, setCode] = useState7("");
2016
- const [pending, setPending] = useState7(null);
2204
+ const loaded = useSignInMethods(client);
2205
+ const [currentPage, setCurrentPage] = useState8(null);
2206
+ const [email, setEmail] = useState8("");
2207
+ const [password, setPassword] = useState8("");
2208
+ const [code, setCode] = useState8("");
2209
+ const [pending, setPending] = useState8(null);
2017
2210
  const pendingChallenge = pending?.challengeToken ?? null;
2018
- const [phoneNumber, setPhoneNumber] = useState7("");
2019
- const [phoneChallenge, setPhoneChallenge] = useState7(
2211
+ const [phoneNumber, setPhoneNumber] = useState8("");
2212
+ const [phoneChallenge, setPhoneChallenge] = useState8(
2020
2213
  null
2021
2214
  );
2022
- const [error, setError] = useState7(null);
2023
- const [busy, setBusy] = useState7(false);
2024
- const [passkeyReady, setPasskeyReady] = useState7(false);
2025
- const [mode, setMode] = useState7("password");
2026
- const [linkSent, setLinkSent] = useState7(false);
2215
+ const [error, setError] = useState8(null);
2216
+ const [busy, setBusy] = useState8(false);
2217
+ const [passkeyReady, setPasskeyReady] = useState8(false);
2218
+ const [chosenMode, setMode] = useState8(null);
2219
+ const [linkSent, setLinkSent] = useState8(false);
2027
2220
  const abortRef = useRef2(null);
2221
+ useEffect8(() => {
2222
+ setCurrentPage(currentPageUrl());
2223
+ }, []);
2224
+ const offered = resolveMethods(
2225
+ loaded.methods,
2226
+ {
2227
+ password: passwordProp,
2228
+ passkeys: passkeysProp,
2229
+ magicLink: magicLinkProp,
2230
+ magicLinkRedirectUrl,
2231
+ phone: phoneProp,
2232
+ social: socialProp,
2233
+ sso: ssoProp,
2234
+ socialRedirectUrl
2235
+ },
2236
+ currentPage
2237
+ );
2238
+ const tabs = [
2239
+ ...offered.password ? ["password"] : [],
2240
+ ...offered.magicLink ? ["magic"] : [],
2241
+ ...offered.phone ? ["phone"] : []
2242
+ ];
2243
+ const mode = chosenMode && (chosenMode === "sso" ? offered.sso : tabs.includes(chosenMode)) ? chosenMode : tabs[0] ?? null;
2244
+ const passkeysWanted = loaded.status !== "loading" && offered.passkeys;
2028
2245
  const signInWithPasskey = async (conditional, signal) => {
2029
2246
  if (!conditional) {
2030
2247
  setBusy(true);
@@ -2042,7 +2259,7 @@ function SignIn({
2042
2259
  setError(cause.message);
2043
2260
  } else if (!conditional) {
2044
2261
  console.error("[base316] passkey sign-in failed", cause);
2045
- setError("That passkey did not work.");
2262
+ setError(labels.passkeyFailed);
2046
2263
  }
2047
2264
  } finally {
2048
2265
  if (!conditional) {
@@ -2050,8 +2267,9 @@ function SignIn({
2050
2267
  }
2051
2268
  }
2052
2269
  };
2053
- useEffect7(() => {
2054
- if (!passkeys || !isPasskeySupported() || pendingChallenge) {
2270
+ useEffect8(() => {
2271
+ if (!passkeysWanted || !isPasskeySupported() || pendingChallenge) {
2272
+ setPasskeyReady(false);
2055
2273
  return;
2056
2274
  }
2057
2275
  setPasskeyReady(true);
@@ -2065,8 +2283,8 @@ function SignIn({
2065
2283
  return () => {
2066
2284
  controller.abort();
2067
2285
  };
2068
- }, [passkeys, pendingChallenge]);
2069
- useEffect7(() => {
2286
+ }, [passkeysWanted, pendingChallenge]);
2287
+ useEffect8(() => {
2070
2288
  if (typeof window === "undefined") {
2071
2289
  return;
2072
2290
  }
@@ -2090,7 +2308,7 @@ function SignIn({
2090
2308
  onSignedIn?.();
2091
2309
  }).catch(() => {
2092
2310
  if (!cancelled) {
2093
- setError("That sign-in link is no longer valid. Ask for a new one.");
2311
+ setError(labels.linkInvalid);
2094
2312
  }
2095
2313
  });
2096
2314
  return () => {
@@ -2098,23 +2316,44 @@ function SignIn({
2098
2316
  };
2099
2317
  }, []);
2100
2318
  async function sendLink() {
2101
- if (!magicLinkRedirectUrl) {
2319
+ if (!offered.magicLink) {
2102
2320
  return;
2103
2321
  }
2104
2322
  setBusy(true);
2105
2323
  setError(null);
2106
2324
  try {
2107
- await client.auth.magicLink.request({ email, redirectUrl: magicLinkRedirectUrl });
2325
+ await client.auth.magicLink.request({ email, redirectUrl: offered.magicLink });
2108
2326
  setLinkSent(true);
2109
2327
  } catch (cause) {
2110
2328
  console.error("[base316] magic link request failed", cause);
2111
- setError("We could not send that link. Try again.");
2329
+ setError(
2330
+ cause instanceof Base316Error2 && cause.code === "INVALID_REQUEST" && cause.message ? cause.message : labels.linkFailed
2331
+ );
2112
2332
  } finally {
2113
2333
  setBusy(false);
2114
2334
  }
2115
2335
  }
2336
+ function leaveForSso() {
2337
+ if (!socialRedirectUrl) {
2338
+ return;
2339
+ }
2340
+ setBusy(true);
2341
+ beginRedirect(
2342
+ (state) => client.ssoSignInUrl({
2343
+ email,
2344
+ redirectUri: socialRedirectUrl,
2345
+ state,
2346
+ hostedUrl: offered.hostedUrl
2347
+ }),
2348
+ socialState
2349
+ );
2350
+ }
2116
2351
  async function submit(event) {
2117
2352
  event.preventDefault();
2353
+ if (mode === "sso") {
2354
+ leaveForSso();
2355
+ return;
2356
+ }
2118
2357
  setBusy(true);
2119
2358
  setError(null);
2120
2359
  try {
@@ -2151,25 +2390,23 @@ function SignIn({
2151
2390
  } catch (cause) {
2152
2391
  console.error("[base316] sign-in failed", cause);
2153
2392
  setError(
2154
- mode === "phone" ? phoneChallenge ? "That code did not work. Check it, or ask for a new one." : (
2393
+ mode === "phone" ? phoneChallenge ? labels.wrongCode : (
2155
2394
  // Why a text could not be sent is worth saying — a number in the
2156
2395
  // wrong format, or too many requests — and the server words it
2157
2396
  // without saying anything about accounts.
2158
- cause instanceof Error && cause.message ? cause.message : "We could not send a code. Try again."
2397
+ cause instanceof Error && cause.message ? cause.message : labels.codeFailed
2159
2398
  ) : (
2160
2399
  // An unconfirmed address and a throttle are worth naming; the
2161
2400
  // server words both without saying whether an account exists.
2162
- cause instanceof Base316Error2 && (cause.reason === "EMAIL_NOT_VERIFIED" || cause.code === "RATE_LIMITED") ? cause.message : "That email and password did not match."
2401
+ cause instanceof Base316Error2 && (cause.reason === "EMAIL_NOT_VERIFIED" || cause.code === "RATE_LIMITED") ? cause.message : labels.wrongPassword
2163
2402
  )
2164
2403
  );
2165
2404
  } finally {
2166
2405
  setBusy(false);
2167
2406
  }
2168
2407
  }
2169
- const magicAvailable = Boolean(magicLinkRedirectUrl) && !pendingChallenge;
2170
- const tabsShown = (magicAvailable || phone) && !pendingChallenge;
2171
2408
  if (pending) {
2172
- return /* @__PURE__ */ jsx8("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx8(
2409
+ return /* @__PURE__ */ jsx9("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx9(
2173
2410
  SecondFactorStep,
2174
2411
  {
2175
2412
  pending,
@@ -2185,59 +2422,68 @@ function SignIn({
2185
2422
  ) });
2186
2423
  }
2187
2424
  if (linkSent) {
2188
- return /* @__PURE__ */ jsxs7("div", { className: cls("b316-card", className), style, children: [
2189
- /* @__PURE__ */ jsx8("div", { style: { fontWeight: 600, marginBottom: 6 }, children: "Check your email" }),
2190
- /* @__PURE__ */ jsxs7("div", { className: "b316-muted", children: [
2191
- "If an account exists for ",
2192
- email,
2193
- ", a sign-in link is on its way. It expires shortly and can be used once."
2194
- ] }),
2195
- /* @__PURE__ */ jsx8(
2425
+ return /* @__PURE__ */ jsxs8("div", { className: cls("b316-card", className), style, children: [
2426
+ /* @__PURE__ */ jsx9("div", { style: { fontWeight: 600, marginBottom: 6 }, children: labels.checkEmailTitle }),
2427
+ /* @__PURE__ */ jsx9("div", { className: "b316-muted", children: labels.checkEmail(email) }),
2428
+ /* @__PURE__ */ jsx9(
2196
2429
  "button",
2197
2430
  {
2198
2431
  type: "button",
2199
2432
  className: "b316-button b316-button-secondary",
2200
2433
  style: { marginTop: 16 },
2201
2434
  onClick: () => setLinkSent(false),
2202
- children: "Back to sign in"
2435
+ children: labels.backToSignIn
2203
2436
  }
2204
2437
  )
2205
2438
  ] });
2206
2439
  }
2207
- return /* @__PURE__ */ jsxs7("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
2208
- error ? /* @__PURE__ */ jsx8("div", { className: "b316-error", role: "alert", children: error }) : null,
2209
- tabsShown ? /* @__PURE__ */ jsxs7("div", { className: "b316-tabs", children: [
2210
- /* @__PURE__ */ jsx8(
2211
- "button",
2440
+ const hasForm = mode !== null;
2441
+ const hasButtons = offered.social.length > 0 || passkeyReady || offered.sso && mode !== "sso";
2442
+ if (!hasForm && !hasButtons) {
2443
+ return /* @__PURE__ */ jsx9("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx9("div", { className: "b316-error", role: "alert", children: error ?? labels.noMethods }) });
2444
+ }
2445
+ const tabsShown = tabs.length > 1 && mode !== "sso";
2446
+ return /* @__PURE__ */ jsxs8("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
2447
+ error ? /* @__PURE__ */ jsx9("div", { className: "b316-error", role: "alert", children: error }) : null,
2448
+ offered.social.length > 0 && mode !== "sso" ? /* @__PURE__ */ jsxs8(Fragment4, { children: [
2449
+ /* @__PURE__ */ jsx9(
2450
+ SocialButtons,
2212
2451
  {
2213
- type: "button",
2214
- className: cls("b316-tab", mode === "password" ? "b316-tab-on" : void 0),
2215
- onClick: () => setMode("password"),
2216
- children: "Password"
2452
+ options: offered.social,
2453
+ continueWith: labels.continueWith,
2454
+ disabled: busy,
2455
+ onChoose: (option) => {
2456
+ if (!socialRedirectUrl) {
2457
+ return;
2458
+ }
2459
+ setBusy(true);
2460
+ beginRedirect(
2461
+ (state) => client.socialSignInUrl({
2462
+ provider: option.slug,
2463
+ redirectUri: socialRedirectUrl,
2464
+ state,
2465
+ hostedUrl: offered.hostedUrl
2466
+ }),
2467
+ socialState
2468
+ );
2469
+ }
2217
2470
  }
2218
2471
  ),
2219
- magicAvailable ? /* @__PURE__ */ jsx8(
2220
- "button",
2221
- {
2222
- type: "button",
2223
- className: cls("b316-tab", mode === "magic" ? "b316-tab-on" : void 0),
2224
- onClick: () => setMode("magic"),
2225
- children: "Magic link"
2226
- }
2227
- ) : null,
2228
- phone ? /* @__PURE__ */ jsx8(
2229
- "button",
2230
- {
2231
- type: "button",
2232
- className: cls("b316-tab", mode === "phone" ? "b316-tab-on" : void 0),
2233
- onClick: () => setMode("phone"),
2234
- children: "Text message"
2235
- }
2236
- ) : null
2472
+ hasForm ? /* @__PURE__ */ jsx9("div", { className: "b316-divider", children: labels.or }) : null
2237
2473
  ] }) : null,
2238
- mode === "phone" ? phoneChallenge ? /* @__PURE__ */ jsxs7("div", { className: "b316-field", children: [
2239
- /* @__PURE__ */ jsx8("label", { className: "b316-label", htmlFor: "b316-phone-code", children: "Code" }),
2240
- /* @__PURE__ */ jsx8(
2474
+ tabsShown ? /* @__PURE__ */ jsx9("div", { className: "b316-tabs", children: tabs.map((tab) => /* @__PURE__ */ jsx9(
2475
+ "button",
2476
+ {
2477
+ type: "button",
2478
+ className: cls("b316-tab", mode === tab ? "b316-tab-on" : void 0),
2479
+ onClick: () => setMode(tab),
2480
+ children: tab === "password" ? labels.tabPassword : tab === "magic" ? labels.tabMagicLink : labels.tabPhone
2481
+ },
2482
+ tab
2483
+ )) }) : null,
2484
+ mode === "phone" ? phoneChallenge ? /* @__PURE__ */ jsxs8("div", { className: "b316-field", children: [
2485
+ /* @__PURE__ */ jsx9("label", { className: "b316-label", htmlFor: "b316-phone-code", children: labels.code }),
2486
+ /* @__PURE__ */ jsx9(
2241
2487
  "input",
2242
2488
  {
2243
2489
  id: "b316-phone-code",
@@ -2249,12 +2495,10 @@ function SignIn({
2249
2495
  required: true
2250
2496
  }
2251
2497
  ),
2252
- /* @__PURE__ */ jsxs7("span", { className: "b316-muted", children: [
2253
- "We sent a code to ",
2254
- phoneChallenge.hint,
2255
- ". It expires in ten minutes.",
2498
+ /* @__PURE__ */ jsxs8("span", { className: "b316-muted", children: [
2499
+ labels.codeSent(phoneChallenge.hint),
2256
2500
  " ",
2257
- /* @__PURE__ */ jsx8(
2501
+ /* @__PURE__ */ jsx9(
2258
2502
  "button",
2259
2503
  {
2260
2504
  type: "button",
@@ -2263,13 +2507,13 @@ function SignIn({
2263
2507
  setPhoneChallenge(null);
2264
2508
  setCode("");
2265
2509
  },
2266
- children: "Use a different number"
2510
+ children: labels.useDifferentNumber
2267
2511
  }
2268
2512
  )
2269
2513
  ] })
2270
- ] }) : /* @__PURE__ */ jsxs7("div", { className: "b316-field", children: [
2271
- /* @__PURE__ */ jsx8("label", { className: "b316-label", htmlFor: "b316-phone", children: "Mobile number" }),
2272
- /* @__PURE__ */ jsx8(
2514
+ ] }) : /* @__PURE__ */ jsxs8("div", { className: "b316-field", children: [
2515
+ /* @__PURE__ */ jsx9("label", { className: "b316-label", htmlFor: "b316-phone", children: labels.mobileNumber }),
2516
+ /* @__PURE__ */ jsx9(
2273
2517
  "input",
2274
2518
  {
2275
2519
  id: "b316-phone",
@@ -2282,11 +2526,11 @@ function SignIn({
2282
2526
  required: true
2283
2527
  }
2284
2528
  ),
2285
- /* @__PURE__ */ jsx8("span", { className: "b316-muted", children: "Include the country code." })
2286
- ] }) : /* @__PURE__ */ jsxs7(Fragment4, { children: [
2287
- /* @__PURE__ */ jsxs7("div", { className: "b316-field", children: [
2288
- /* @__PURE__ */ jsx8("label", { className: "b316-label", htmlFor: "b316-email", children: "Email" }),
2289
- /* @__PURE__ */ jsx8(
2529
+ /* @__PURE__ */ jsx9("span", { className: "b316-muted", children: labels.includeCountryCode })
2530
+ ] }) : mode !== null ? /* @__PURE__ */ jsxs8(Fragment4, { children: [
2531
+ /* @__PURE__ */ jsxs8("div", { className: "b316-field", children: [
2532
+ /* @__PURE__ */ jsx9("label", { className: "b316-label", htmlFor: "b316-email", children: mode === "sso" ? labels.ssoEmail : labels.email }),
2533
+ /* @__PURE__ */ jsx9(
2290
2534
  "input",
2291
2535
  {
2292
2536
  id: "b316-email",
@@ -2294,14 +2538,14 @@ function SignIn({
2294
2538
  type: "email",
2295
2539
  value: email,
2296
2540
  onChange: (event) => setEmail(event.target.value),
2297
- autoComplete: passkeyReady ? "email webauthn" : "email",
2541
+ autoComplete: passkeyReady && mode !== "sso" ? "email webauthn" : "email",
2298
2542
  required: true
2299
2543
  }
2300
2544
  )
2301
2545
  ] }),
2302
- mode === "password" ? /* @__PURE__ */ jsxs7("div", { className: "b316-field", children: [
2303
- /* @__PURE__ */ jsx8("label", { className: "b316-label", htmlFor: "b316-password", children: "Password" }),
2304
- /* @__PURE__ */ jsx8(
2546
+ mode === "password" ? /* @__PURE__ */ jsxs8("div", { className: "b316-field", children: [
2547
+ /* @__PURE__ */ jsx9("label", { className: "b316-label", htmlFor: "b316-password", children: labels.password }),
2548
+ /* @__PURE__ */ jsx9(
2305
2549
  "input",
2306
2550
  {
2307
2551
  id: "b316-password",
@@ -2314,34 +2558,101 @@ function SignIn({
2314
2558
  }
2315
2559
  )
2316
2560
  ] }) : null
2317
- ] }),
2318
- /* @__PURE__ */ jsx8("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" }),
2319
- passkeyReady && !pendingChallenge ? /* @__PURE__ */ jsxs7(Fragment4, { children: [
2320
- /* @__PURE__ */ jsx8("div", { className: "b316-muted", style: { textAlign: "center", margin: "10px 0" }, children: "or" }),
2321
- /* @__PURE__ */ jsx8(
2561
+ ] }) : null,
2562
+ mode !== null ? /* @__PURE__ */ jsx9("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,
2563
+ mode === "sso" ? /* @__PURE__ */ jsx9(
2564
+ "button",
2565
+ {
2566
+ type: "button",
2567
+ className: "b316-button b316-button-secondary",
2568
+ style: { marginTop: 10, width: "100%" },
2569
+ disabled: busy,
2570
+ onClick: () => setMode(null),
2571
+ children: labels.back
2572
+ }
2573
+ ) : null,
2574
+ (passkeyReady || offered.sso) && mode !== "sso" ? /* @__PURE__ */ jsxs8(Fragment4, { children: [
2575
+ hasForm ? /* @__PURE__ */ jsx9("div", { className: "b316-divider", children: labels.or }) : null,
2576
+ passkeyReady ? /* @__PURE__ */ jsx9(
2322
2577
  "button",
2323
2578
  {
2324
2579
  type: "button",
2325
2580
  className: "b316-button b316-button-secondary",
2581
+ style: { width: "100%" },
2326
2582
  disabled: busy,
2327
2583
  onClick: () => {
2328
2584
  abortRef.current?.abort();
2329
2585
  void signInWithPasskey(false);
2330
2586
  },
2331
- children: "Sign in with a passkey"
2587
+ children: labels.passkey
2332
2588
  }
2333
- )
2589
+ ) : null,
2590
+ offered.sso ? /* @__PURE__ */ jsx9(
2591
+ "button",
2592
+ {
2593
+ type: "button",
2594
+ className: "b316-button b316-button-secondary",
2595
+ style: { width: "100%", marginTop: passkeyReady ? 8 : 0 },
2596
+ disabled: busy,
2597
+ onClick: () => {
2598
+ abortRef.current?.abort();
2599
+ setError(null);
2600
+ setMode("sso");
2601
+ },
2602
+ children: labels.sso
2603
+ }
2604
+ ) : null
2334
2605
  ] }) : null
2335
2606
  ] });
2336
2607
  }
2337
2608
 
2609
+ // src/SocialSignIn.tsx
2610
+ import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2611
+ function SocialSignIn({
2612
+ socialRedirectUrl,
2613
+ socialState,
2614
+ social,
2615
+ intent = "sign-in",
2616
+ divider = false,
2617
+ labels
2618
+ }) {
2619
+ const { client } = useBase316();
2620
+ const loaded = useSignInMethods(client);
2621
+ if (!loaded.methods || intent === "sign-up" && !loaded.methods.signUp) {
2622
+ return null;
2623
+ }
2624
+ const offered = resolveMethods(loaded.methods, { social, socialRedirectUrl }, null);
2625
+ if (!socialRedirectUrl || offered.social.length === 0) {
2626
+ return null;
2627
+ }
2628
+ return /* @__PURE__ */ jsxs9(Fragment5, { children: [
2629
+ /* @__PURE__ */ jsx10(
2630
+ SocialButtons,
2631
+ {
2632
+ options: offered.social,
2633
+ continueWith: labels?.continueWith ?? ((name) => `Continue with ${name}`),
2634
+ onChoose: (option) => beginRedirect(
2635
+ (state) => client.socialSignInUrl({
2636
+ provider: option.slug,
2637
+ redirectUri: socialRedirectUrl,
2638
+ state,
2639
+ hostedUrl: offered.hostedUrl
2640
+ }),
2641
+ socialState
2642
+ )
2643
+ }
2644
+ ),
2645
+ divider ? /* @__PURE__ */ jsx10("div", { className: "b316-divider", children: labels?.or ?? "or" }) : null
2646
+ ] });
2647
+ }
2648
+
2338
2649
  // src/SignUp.tsx
2339
2650
  import {
2340
2651
  Base316Error as Base316Error3,
2341
2652
  needsSecondFactor as needsSecondFactor2
2342
2653
  } from "@base316/sdk";
2343
- import { useEffect as useEffect8, useState as useState8 } from "react";
2344
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2654
+ import { useEffect as useEffect9, useState as useState9 } from "react";
2655
+ import { Fragment as Fragment6, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
2345
2656
  var DEFAULT_SIGN_UP_LABELS = {
2346
2657
  name: "Name",
2347
2658
  email: "Email",
@@ -2358,7 +2669,10 @@ var DEFAULT_SIGN_UP_LABELS = {
2358
2669
  confirmEmail: (email) => `Your account is ready. We sent a confirmation link to ${email} \u2014 open it, then sign in.`,
2359
2670
  createdSignInFailed: (reason) => `Your account was created, but we could not sign you in: ${reason}`,
2360
2671
  genericError: "We could not create that account. Try again.",
2361
- joining: (organizationName, roleName) => `You are joining ${organizationName} as ${roleName}. Sign up with the address the invitation was sent to.`
2672
+ joining: (organizationName, roleName) => `You are joining ${organizationName} as ${roleName}. Sign up with the address the invitation was sent to.`,
2673
+ continueWith: (name) => `Continue with ${name}`,
2674
+ or: "or",
2675
+ closed: "This application is not accepting new accounts right now."
2362
2676
  };
2363
2677
  function describeRules(policy, labels) {
2364
2678
  const extras = [
@@ -2377,30 +2691,35 @@ function SignUp({
2377
2691
  onJoined,
2378
2692
  labels: overrides,
2379
2693
  secondFactorLabels,
2694
+ social,
2695
+ socialRedirectUrl,
2696
+ socialState,
2380
2697
  className,
2381
2698
  style
2382
2699
  }) {
2383
2700
  const labels = { ...DEFAULT_SIGN_UP_LABELS, ...overrides };
2384
2701
  const { client, setToken } = useBase316();
2385
- const [name, setName] = useState8("");
2386
- const [email, setEmail] = useState8("");
2387
- const [password, setPassword] = useState8("");
2388
- const [error, setError] = useState8(null);
2389
- const [busy, setBusy] = useState8(false);
2390
- const [policy, setPolicy] = useState8(null);
2391
- const [pending, setPending] = useState8(null);
2392
- const [confirmEmail, setConfirmEmail] = useState8(false);
2393
- const [urlInvitation, setUrlInvitation] = useState8(null);
2394
- const [loaded, setLoaded] = useState8(null);
2702
+ const methodsState = useSignInMethods(client);
2703
+ const offered = resolveMethods(methodsState.methods, { social, socialRedirectUrl }, null);
2704
+ const [name, setName] = useState9("");
2705
+ const [email, setEmail] = useState9("");
2706
+ const [password, setPassword] = useState9("");
2707
+ const [error, setError] = useState9(null);
2708
+ const [busy, setBusy] = useState9(false);
2709
+ const [policy, setPolicy] = useState9(null);
2710
+ const [pending, setPending] = useState9(null);
2711
+ const [confirmEmail, setConfirmEmail] = useState9(false);
2712
+ const [urlInvitation, setUrlInvitation] = useState9(null);
2713
+ const [loaded, setLoaded] = useState9(null);
2395
2714
  const invitation = suppliedInvitation === void 0 ? urlInvitation : suppliedInvitation;
2396
2715
  const preview = loaded && loaded.token === invitation ? loaded.preview : null;
2397
- useEffect8(() => {
2716
+ useEffect9(() => {
2398
2717
  if (suppliedInvitation !== void 0 || typeof window === "undefined") {
2399
2718
  return;
2400
2719
  }
2401
2720
  setUrlInvitation(new URL(window.location.href).searchParams.get("invitation"));
2402
2721
  }, [suppliedInvitation]);
2403
- useEffect8(() => {
2722
+ useEffect9(() => {
2404
2723
  if (!invitation) {
2405
2724
  return;
2406
2725
  }
@@ -2415,7 +2734,7 @@ function SignUp({
2415
2734
  cancelled = true;
2416
2735
  };
2417
2736
  }, [client, invitation]);
2418
- useEffect8(() => {
2737
+ useEffect9(() => {
2419
2738
  let cancelled = false;
2420
2739
  client.auth.passwordPolicy().then((loaded2) => {
2421
2740
  if (!cancelled) {
@@ -2473,86 +2792,118 @@ function SignUp({
2473
2792
  }
2474
2793
  }
2475
2794
  if (pending) {
2476
- return /* @__PURE__ */ jsx9("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx9(SecondFactorStep, { pending, labels: secondFactorLabels, onSignedIn: onSignedUp }) });
2795
+ return /* @__PURE__ */ jsx11("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx11(SecondFactorStep, { pending, labels: secondFactorLabels, onSignedIn: onSignedUp }) });
2477
2796
  }
2478
2797
  if (confirmEmail) {
2479
- return /* @__PURE__ */ jsxs8("div", { className: cls("b316-card", className), style, children: [
2480
- /* @__PURE__ */ jsx9("h3", { className: "b316-form-title", children: labels.confirmEmailTitle }),
2481
- /* @__PURE__ */ jsx9("output", { className: "b316-muted", children: labels.confirmEmail(email) })
2798
+ return /* @__PURE__ */ jsxs10("div", { className: cls("b316-card", className), style, children: [
2799
+ /* @__PURE__ */ jsx11("h3", { className: "b316-form-title", children: labels.confirmEmailTitle }),
2800
+ /* @__PURE__ */ jsx11("output", { className: "b316-muted", children: labels.confirmEmail(email) })
2482
2801
  ] });
2483
2802
  }
2484
- return /* @__PURE__ */ jsxs8("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
2485
- preview ? /* @__PURE__ */ jsx9("p", { className: "b316-muted", children: labels.joining(preview.organizationName, preview.roleName) }) : null,
2486
- error ? /* @__PURE__ */ jsx9("div", { className: "b316-error", role: "alert", children: error }) : null,
2487
- /* @__PURE__ */ jsxs8("div", { className: "b316-field", children: [
2488
- /* @__PURE__ */ jsx9("label", { className: "b316-label", htmlFor: "b316-name", children: labels.name }),
2489
- /* @__PURE__ */ jsx9(
2490
- "input",
2491
- {
2492
- id: "b316-name",
2493
- className: "b316-input",
2494
- value: name,
2495
- onChange: (event) => setName(event.target.value),
2496
- autoComplete: "name"
2497
- }
2498
- )
2499
- ] }),
2500
- /* @__PURE__ */ jsxs8("div", { className: "b316-field", children: [
2501
- /* @__PURE__ */ jsx9("label", { className: "b316-label", htmlFor: "b316-signup-email", children: labels.email }),
2502
- /* @__PURE__ */ jsx9(
2503
- "input",
2504
- {
2505
- id: "b316-signup-email",
2506
- className: "b316-input",
2507
- type: "email",
2508
- value: email,
2509
- onChange: (event) => setEmail(event.target.value),
2510
- autoComplete: "email",
2511
- required: true
2512
- }
2513
- )
2514
- ] }),
2515
- /* @__PURE__ */ jsxs8("div", { className: "b316-field", children: [
2516
- /* @__PURE__ */ jsx9("label", { className: "b316-label", htmlFor: "b316-signup-password", children: labels.password }),
2517
- /* @__PURE__ */ jsx9(
2518
- "input",
2803
+ if (!offered.signUp && !invitation) {
2804
+ return /* @__PURE__ */ jsx11("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx11("output", { className: "b316-muted", children: labels.closed }) });
2805
+ }
2806
+ const socialOptions = invitation ? [] : offered.social;
2807
+ return /* @__PURE__ */ jsxs10("form", { onSubmit: submit, className: cls("b316-card", className), style, children: [
2808
+ socialOptions.length > 0 ? /* @__PURE__ */ jsxs10(Fragment6, { children: [
2809
+ /* @__PURE__ */ jsx11(
2810
+ SocialButtons,
2519
2811
  {
2520
- id: "b316-signup-password",
2521
- className: "b316-input",
2522
- type: "password",
2523
- value: password,
2524
- onChange: (event) => setPassword(event.target.value),
2525
- autoComplete: "new-password",
2526
- minLength: policy?.minLength,
2527
- maxLength: policy?.maxLength,
2528
- "aria-describedby": policy ? "b316-signup-password-rules" : void 0,
2529
- required: true
2812
+ options: socialOptions,
2813
+ continueWith: labels.continueWith,
2814
+ disabled: busy,
2815
+ onChoose: (option) => {
2816
+ if (!socialRedirectUrl) {
2817
+ return;
2818
+ }
2819
+ setBusy(true);
2820
+ beginRedirect(
2821
+ (state) => client.socialSignInUrl({
2822
+ provider: option.slug,
2823
+ redirectUri: socialRedirectUrl,
2824
+ state,
2825
+ hostedUrl: offered.hostedUrl
2826
+ }),
2827
+ socialState
2828
+ );
2829
+ }
2530
2830
  }
2531
2831
  ),
2532
- policy ? /* @__PURE__ */ jsx9("span", { id: "b316-signup-password-rules", className: "b316-muted", children: describeRules(policy, labels) }) : null
2533
- ] }),
2534
- /* @__PURE__ */ jsx9("button", { className: "b316-button", type: "submit", disabled: busy, children: busy ? labels.working : labels.submit })
2832
+ offered.password ? /* @__PURE__ */ jsx11("div", { className: "b316-divider", children: labels.or }) : null
2833
+ ] }) : null,
2834
+ preview ? /* @__PURE__ */ jsx11("p", { className: "b316-muted", children: labels.joining(preview.organizationName, preview.roleName) }) : null,
2835
+ error ? /* @__PURE__ */ jsx11("div", { className: "b316-error", role: "alert", children: error }) : null,
2836
+ offered.password || socialOptions.length === 0 ? /* @__PURE__ */ jsxs10(Fragment6, { children: [
2837
+ /* @__PURE__ */ jsxs10("div", { className: "b316-field", children: [
2838
+ /* @__PURE__ */ jsx11("label", { className: "b316-label", htmlFor: "b316-name", children: labels.name }),
2839
+ /* @__PURE__ */ jsx11(
2840
+ "input",
2841
+ {
2842
+ id: "b316-name",
2843
+ className: "b316-input",
2844
+ value: name,
2845
+ onChange: (event) => setName(event.target.value),
2846
+ autoComplete: "name"
2847
+ }
2848
+ )
2849
+ ] }),
2850
+ /* @__PURE__ */ jsxs10("div", { className: "b316-field", children: [
2851
+ /* @__PURE__ */ jsx11("label", { className: "b316-label", htmlFor: "b316-signup-email", children: labels.email }),
2852
+ /* @__PURE__ */ jsx11(
2853
+ "input",
2854
+ {
2855
+ id: "b316-signup-email",
2856
+ className: "b316-input",
2857
+ type: "email",
2858
+ value: email,
2859
+ onChange: (event) => setEmail(event.target.value),
2860
+ autoComplete: "email",
2861
+ required: true
2862
+ }
2863
+ )
2864
+ ] }),
2865
+ /* @__PURE__ */ jsxs10("div", { className: "b316-field", children: [
2866
+ /* @__PURE__ */ jsx11("label", { className: "b316-label", htmlFor: "b316-signup-password", children: labels.password }),
2867
+ /* @__PURE__ */ jsx11(
2868
+ "input",
2869
+ {
2870
+ id: "b316-signup-password",
2871
+ className: "b316-input",
2872
+ type: "password",
2873
+ value: password,
2874
+ onChange: (event) => setPassword(event.target.value),
2875
+ autoComplete: "new-password",
2876
+ minLength: policy?.minLength,
2877
+ maxLength: policy?.maxLength,
2878
+ "aria-describedby": policy ? "b316-signup-password-rules" : void 0,
2879
+ required: true
2880
+ }
2881
+ ),
2882
+ policy ? /* @__PURE__ */ jsx11("span", { id: "b316-signup-password-rules", className: "b316-muted", children: describeRules(policy, labels) }) : null
2883
+ ] }),
2884
+ /* @__PURE__ */ jsx11("button", { className: "b316-button", type: "submit", disabled: busy, children: busy ? labels.working : labels.submit })
2885
+ ] }) : null
2535
2886
  ] });
2536
2887
  }
2537
2888
 
2538
2889
  // src/UserProfile.tsx
2539
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2890
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
2540
2891
  function UserProfile({ className, style }) {
2541
2892
  const { session, loading, signOut } = useBase316();
2542
2893
  if (loading) {
2543
- return /* @__PURE__ */ jsx10("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
2894
+ return /* @__PURE__ */ jsx12("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
2544
2895
  }
2545
2896
  if (!session) {
2546
- return /* @__PURE__ */ jsx10("div", { className: cls("b316-card", className), style, children: "Not signed in." });
2897
+ return /* @__PURE__ */ jsx12("div", { className: cls("b316-card", className), style, children: "Not signed in." });
2547
2898
  }
2548
2899
  const user = session.user ?? {};
2549
- return /* @__PURE__ */ jsx10("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsxs9("div", { className: "b316-row", children: [
2550
- /* @__PURE__ */ jsxs9("div", { children: [
2551
- /* @__PURE__ */ jsx10("div", { style: { fontWeight: 600 }, children: user.name || user.email || "Signed in" }),
2552
- user.name && user.email ? /* @__PURE__ */ jsx10("div", { className: "b316-muted", children: user.email }) : null,
2553
- user.emailVerified === false ? /* @__PURE__ */ jsx10("div", { className: "b316-muted", children: "Email not verified" }) : null
2900
+ return /* @__PURE__ */ jsx12("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsxs11("div", { className: "b316-row", children: [
2901
+ /* @__PURE__ */ jsxs11("div", { children: [
2902
+ /* @__PURE__ */ jsx12("div", { style: { fontWeight: 600 }, children: user.name || user.email || "Signed in" }),
2903
+ user.name && user.email ? /* @__PURE__ */ jsx12("div", { className: "b316-muted", children: user.email }) : null,
2904
+ user.emailVerified === false ? /* @__PURE__ */ jsx12("div", { className: "b316-muted", children: "Email not verified" }) : null
2554
2905
  ] }),
2555
- /* @__PURE__ */ jsx10(
2906
+ /* @__PURE__ */ jsx12(
2556
2907
  "button",
2557
2908
  {
2558
2909
  type: "button",
@@ -2566,11 +2917,11 @@ function UserProfile({ className, style }) {
2566
2917
 
2567
2918
  // src/PasskeyManager.tsx
2568
2919
  import { isPasskeySupported as isPasskeySupported2 } from "@base316/sdk";
2569
- import { useCallback as useCallback5, useEffect as useEffect10, useState as useState10 } from "react";
2920
+ import { useCallback as useCallback5, useEffect as useEffect11, useState as useState11 } from "react";
2570
2921
 
2571
2922
  // src/confirm.tsx
2572
- import { useEffect as useEffect9, useRef as useRef3, useState as useState9 } from "react";
2573
- import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
2923
+ import { useEffect as useEffect10, useRef as useRef3, useState as useState10 } from "react";
2924
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
2574
2925
  var DEFAULT_TIMEOUT_MS = 5e3;
2575
2926
  function ConfirmButton({
2576
2927
  children,
@@ -2580,9 +2931,9 @@ function ConfirmButton({
2580
2931
  disabled,
2581
2932
  timeoutMs = DEFAULT_TIMEOUT_MS
2582
2933
  }) {
2583
- const [armed, setArmed] = useState9(false);
2934
+ const [armed, setArmed] = useState10(false);
2584
2935
  const confirmRef = useRef3(null);
2585
- useEffect9(() => {
2936
+ useEffect10(() => {
2586
2937
  if (!armed) {
2587
2938
  return;
2588
2939
  }
@@ -2591,7 +2942,7 @@ function ConfirmButton({
2591
2942
  return () => clearTimeout(timer);
2592
2943
  }, [armed, timeoutMs]);
2593
2944
  if (!armed) {
2594
- return /* @__PURE__ */ jsx11(
2945
+ return /* @__PURE__ */ jsx13(
2595
2946
  "button",
2596
2947
  {
2597
2948
  type: "button",
@@ -2605,8 +2956,8 @@ function ConfirmButton({
2605
2956
  return (
2606
2957
  // No `role="group"`: both buttons already say what they do, and the
2607
2958
  // grouping would only repeat the question a screen reader has just read.
2608
- /* @__PURE__ */ jsxs10("span", { className: "b316-confirm", children: [
2609
- /* @__PURE__ */ jsx11(
2959
+ /* @__PURE__ */ jsxs12("span", { className: "b316-confirm", children: [
2960
+ /* @__PURE__ */ jsx13(
2610
2961
  "button",
2611
2962
  {
2612
2963
  ref: confirmRef,
@@ -2620,7 +2971,7 @@ function ConfirmButton({
2620
2971
  children: confirmLabel
2621
2972
  }
2622
2973
  ),
2623
- /* @__PURE__ */ jsx11(
2974
+ /* @__PURE__ */ jsx13(
2624
2975
  "button",
2625
2976
  {
2626
2977
  type: "button",
@@ -2634,18 +2985,18 @@ function ConfirmButton({
2634
2985
  }
2635
2986
 
2636
2987
  // src/PasskeyManager.tsx
2637
- import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
2988
+ import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
2638
2989
  function PasskeyManager({
2639
2990
  className,
2640
2991
  style,
2641
2992
  title = "Passkeys"
2642
2993
  }) {
2643
2994
  const { client, token, session } = useBase316();
2644
- const [passkeys, setPasskeys] = useState10(null);
2645
- const [busy, setBusy] = useState10(false);
2646
- const [error, setError] = useState10(null);
2647
- const [name, setName] = useState10("");
2648
- const [supported, setSupported] = useState10(false);
2995
+ const [passkeys, setPasskeys] = useState11(null);
2996
+ const [busy, setBusy] = useState11(false);
2997
+ const [error, setError] = useState11(null);
2998
+ const [name, setName] = useState11("");
2999
+ const [supported, setSupported] = useState11(false);
2649
3000
  const load = useCallback5(async () => {
2650
3001
  if (!token) {
2651
3002
  return;
@@ -2659,7 +3010,7 @@ function PasskeyManager({
2659
3010
  setPasskeys(null);
2660
3011
  }
2661
3012
  }, [client, token]);
2662
- useEffect10(() => {
3013
+ useEffect11(() => {
2663
3014
  if (!isPasskeySupported2()) {
2664
3015
  return;
2665
3016
  }
@@ -2695,18 +3046,18 @@ function PasskeyManager({
2695
3046
  setError(caught instanceof Error ? caught.message : "That did not work.");
2696
3047
  }
2697
3048
  };
2698
- return /* @__PURE__ */ jsxs11("div", { className: cls("b316-card", className), style, children: [
2699
- /* @__PURE__ */ jsx12("div", { style: { fontWeight: 600, marginBottom: 4 }, children: title }),
2700
- /* @__PURE__ */ jsx12("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." }),
2701
- passkeys === null ? /* @__PURE__ */ jsx12("div", { className: "b316-muted", children: "Loading\u2026" }) : passkeys.length === 0 ? /* @__PURE__ */ jsx12("div", { className: "b316-muted", children: "No passkeys yet." }) : /* @__PURE__ */ jsx12("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: passkeys.map((passkey) => /* @__PURE__ */ jsxs11("li", { className: "b316-row", style: { padding: "8px 0" }, children: [
2702
- /* @__PURE__ */ jsxs11("div", { children: [
2703
- /* @__PURE__ */ jsx12("div", { children: passkey.name || "Passkey" }),
2704
- /* @__PURE__ */ jsxs11("div", { className: "b316-muted", children: [
3049
+ return /* @__PURE__ */ jsxs13("div", { className: cls("b316-card", className), style, children: [
3050
+ /* @__PURE__ */ jsx14("div", { style: { fontWeight: 600, marginBottom: 4 }, children: title }),
3051
+ /* @__PURE__ */ jsx14("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." }),
3052
+ passkeys === null ? /* @__PURE__ */ jsx14("div", { className: "b316-muted", children: "Loading\u2026" }) : passkeys.length === 0 ? /* @__PURE__ */ jsx14("div", { className: "b316-muted", children: "No passkeys yet." }) : /* @__PURE__ */ jsx14("ul", { style: { listStyle: "none", margin: 0, padding: 0 }, children: passkeys.map((passkey) => /* @__PURE__ */ jsxs13("li", { className: "b316-row", style: { padding: "8px 0" }, children: [
3053
+ /* @__PURE__ */ jsxs13("div", { children: [
3054
+ /* @__PURE__ */ jsx14("div", { children: passkey.name || "Passkey" }),
3055
+ /* @__PURE__ */ jsxs13("div", { className: "b316-muted", children: [
2705
3056
  passkey.lastUsedAt ? `Last used ${formatDate(passkey.lastUsedAt)}` : `Added ${formatDate(passkey.createdAt)}`,
2706
3057
  passkey.backedUp ? "" : " \xB7 this device only"
2707
3058
  ] })
2708
3059
  ] }),
2709
- /* @__PURE__ */ jsx12(
3060
+ /* @__PURE__ */ jsx14(
2710
3061
  ConfirmButton,
2711
3062
  {
2712
3063
  className: "b316-button b316-button-secondary",
@@ -2716,9 +3067,9 @@ function PasskeyManager({
2716
3067
  }
2717
3068
  )
2718
3069
  ] }, passkey.id)) }),
2719
- error ? /* @__PURE__ */ jsx12("div", { className: "b316-error", role: "alert", style: { marginTop: 12 }, children: error }) : null,
2720
- /* @__PURE__ */ jsxs11("div", { className: "b316-row", style: { marginTop: 12, gap: 8 }, children: [
2721
- /* @__PURE__ */ jsx12(
3070
+ error ? /* @__PURE__ */ jsx14("div", { className: "b316-error", role: "alert", style: { marginTop: 12 }, children: error }) : null,
3071
+ /* @__PURE__ */ jsxs13("div", { className: "b316-row", style: { marginTop: 12, gap: 8 }, children: [
3072
+ /* @__PURE__ */ jsx14(
2722
3073
  "input",
2723
3074
  {
2724
3075
  className: "b316-input",
@@ -2727,7 +3078,7 @@ function PasskeyManager({
2727
3078
  onChange: (event) => setName(event.target.value)
2728
3079
  }
2729
3080
  ),
2730
- /* @__PURE__ */ jsx12("button", { type: "button", className: "b316-button", disabled: busy, onClick: () => void add(), children: busy ? "Waiting\u2026" : "Add a passkey" })
3081
+ /* @__PURE__ */ jsx14("button", { type: "button", className: "b316-button", disabled: busy, onClick: () => void add(), children: busy ? "Waiting\u2026" : "Add a passkey" })
2731
3082
  ] })
2732
3083
  ] });
2733
3084
  }
@@ -2737,8 +3088,8 @@ function formatDate(value) {
2737
3088
  }
2738
3089
 
2739
3090
  // src/ActiveSessions.tsx
2740
- import { useCallback as useCallback6, useEffect as useEffect11, useState as useState11 } from "react";
2741
- import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
3091
+ import { useCallback as useCallback6, useEffect as useEffect12, useState as useState12 } from "react";
3092
+ import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
2742
3093
  function describeDevice(userAgent) {
2743
3094
  if (!userAgent) {
2744
3095
  return null;
@@ -2756,9 +3107,9 @@ function when(value) {
2756
3107
  }
2757
3108
  function ActiveSessions({ onRevoked, className, style }) {
2758
3109
  const { client, token } = useBase316();
2759
- const [sessions, setSessions] = useState11(null);
2760
- const [error, setError] = useState11(null);
2761
- const [busy, setBusy] = useState11(false);
3110
+ const [sessions, setSessions] = useState12(null);
3111
+ const [error, setError] = useState12(null);
3112
+ const [busy, setBusy] = useState12(false);
2762
3113
  const load = useCallback6(() => {
2763
3114
  if (!token) {
2764
3115
  return;
@@ -2770,15 +3121,15 @@ function ActiveSessions({ onRevoked, className, style }) {
2770
3121
  setError(cause instanceof Error ? cause.message : "Could not load your sessions.");
2771
3122
  });
2772
3123
  }, [client, token]);
2773
- useEffect11(load, [load]);
3124
+ useEffect12(load, [load]);
2774
3125
  if (!token) {
2775
3126
  return null;
2776
3127
  }
2777
3128
  if (error) {
2778
- return /* @__PURE__ */ jsx13("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx13("div", { className: "b316-error", role: "alert", children: error }) });
3129
+ return /* @__PURE__ */ jsx15("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx15("div", { className: "b316-error", role: "alert", children: error }) });
2779
3130
  }
2780
3131
  if (!sessions) {
2781
- return /* @__PURE__ */ jsx13("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
3132
+ return /* @__PURE__ */ jsx15("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
2782
3133
  }
2783
3134
  async function revokeOthers() {
2784
3135
  setBusy(true);
@@ -2792,32 +3143,32 @@ function ActiveSessions({ onRevoked, className, style }) {
2792
3143
  setBusy(false);
2793
3144
  }
2794
3145
  }
2795
- return /* @__PURE__ */ jsxs12("div", { className: cls("b316-card b316-sessions", className), style, children: [
2796
- /* @__PURE__ */ jsxs12("div", { className: "b316-sessions-head", children: [
2797
- /* @__PURE__ */ jsx13("h3", { className: "b316-sessions-title", children: "Where you are signed in" }),
2798
- sessions.length > 1 ? /* @__PURE__ */ jsx13("button", { type: "button", className: "b316-button", disabled: busy, onClick: revokeOthers, children: busy ? "Ending\u2026" : "Sign out other devices" }) : null
3146
+ return /* @__PURE__ */ jsxs14("div", { className: cls("b316-card b316-sessions", className), style, children: [
3147
+ /* @__PURE__ */ jsxs14("div", { className: "b316-sessions-head", children: [
3148
+ /* @__PURE__ */ jsx15("h3", { className: "b316-sessions-title", children: "Where you are signed in" }),
3149
+ sessions.length > 1 ? /* @__PURE__ */ jsx15("button", { type: "button", className: "b316-button", disabled: busy, onClick: revokeOthers, children: busy ? "Ending\u2026" : "Sign out other devices" }) : null
2799
3150
  ] }),
2800
- /* @__PURE__ */ jsx13("ul", { className: "b316-sessions-list", children: sessions.map((session) => /* @__PURE__ */ jsxs12("li", { className: "b316-session", children: [
2801
- /* @__PURE__ */ jsxs12("div", { className: "b316-session-device", children: [
3151
+ /* @__PURE__ */ jsx15("ul", { className: "b316-sessions-list", children: sessions.map((session) => /* @__PURE__ */ jsxs14("li", { className: "b316-session", children: [
3152
+ /* @__PURE__ */ jsxs14("div", { className: "b316-session-device", children: [
2802
3153
  describeDevice(session.userAgent) ?? "Unknown device",
2803
3154
  session.impersonatedBy ? (
2804
3155
  // Worth saying loudly: somebody is acting as this account.
2805
- /* @__PURE__ */ jsx13("span", { className: "b316-chip", children: " Support access" })
3156
+ /* @__PURE__ */ jsx15("span", { className: "b316-chip", children: " Support access" })
2806
3157
  ) : null
2807
3158
  ] }),
2808
- /* @__PURE__ */ jsxs12("div", { className: "b316-muted", children: [
3159
+ /* @__PURE__ */ jsxs14("div", { className: "b316-muted", children: [
2809
3160
  session.ipAddress ? `${session.ipAddress} \xB7 ` : "",
2810
3161
  "last used ",
2811
3162
  when(session.lastSeenAt)
2812
3163
  ] })
2813
3164
  ] }, session.id)) }),
2814
- sessions.length === 0 ? /* @__PURE__ */ jsx13("div", { className: "b316-muted", children: "No active sessions." }) : null
3165
+ sessions.length === 0 ? /* @__PURE__ */ jsx15("div", { className: "b316-muted", children: "No active sessions." }) : null
2815
3166
  ] });
2816
3167
  }
2817
3168
 
2818
3169
  // src/DeviceApproval.tsx
2819
- import { useState as useState12 } from "react";
2820
- import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
3170
+ import { useState as useState13 } from "react";
3171
+ import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
2821
3172
  function DeviceApproval({
2822
3173
  userCode = "",
2823
3174
  onDecided,
@@ -2825,11 +3176,11 @@ function DeviceApproval({
2825
3176
  style
2826
3177
  }) {
2827
3178
  const { client, token } = useBase316();
2828
- const [code, setCode] = useState12(userCode);
2829
- const [request, setRequest] = useState12(null);
2830
- const [decided, setDecided] = useState12(null);
2831
- const [error, setError] = useState12(null);
2832
- const [busy, setBusy] = useState12(false);
3179
+ const [code, setCode] = useState13(userCode);
3180
+ const [request, setRequest] = useState13(null);
3181
+ const [decided, setDecided] = useState13(null);
3182
+ const [error, setError] = useState13(null);
3183
+ const [busy, setBusy] = useState13(false);
2833
3184
  if (!token) {
2834
3185
  return null;
2835
3186
  }
@@ -2862,25 +3213,25 @@ function DeviceApproval({
2862
3213
  }
2863
3214
  }
2864
3215
  if (decided !== null) {
2865
- return /* @__PURE__ */ jsxs13("div", { className: cls("b316-card b316-device", className), style, children: [
2866
- /* @__PURE__ */ jsx14("h3", { className: "b316-device-title", children: decided ? "You're all set" : "Not approved" }),
2867
- /* @__PURE__ */ jsx14("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." })
3216
+ return /* @__PURE__ */ jsxs15("div", { className: cls("b316-card b316-device", className), style, children: [
3217
+ /* @__PURE__ */ jsx16("h3", { className: "b316-device-title", children: decided ? "You're all set" : "Not approved" }),
3218
+ /* @__PURE__ */ jsx16("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." })
2868
3219
  ] });
2869
3220
  }
2870
3221
  if (request) {
2871
- return /* @__PURE__ */ jsxs13("div", { className: cls("b316-card b316-device", className), style, children: [
2872
- /* @__PURE__ */ jsxs13("h3", { className: "b316-device-title", children: [
3222
+ return /* @__PURE__ */ jsxs15("div", { className: cls("b316-card b316-device", className), style, children: [
3223
+ /* @__PURE__ */ jsxs15("h3", { className: "b316-device-title", children: [
2873
3224
  "Sign in to ",
2874
3225
  request.clientName
2875
3226
  ] }),
2876
- /* @__PURE__ */ jsxs13("p", { className: "b316-muted", children: [
3227
+ /* @__PURE__ */ jsxs15("p", { className: "b316-muted", children: [
2877
3228
  request.clientName,
2878
3229
  " is asking to sign in as you."
2879
3230
  ] }),
2880
- request.scopes.length > 0 ? /* @__PURE__ */ jsx14("ul", { className: "b316-device-scopes", children: request.scopes.map((scope) => /* @__PURE__ */ jsx14("li", { children: scope }, scope)) }) : null,
2881
- error ? /* @__PURE__ */ jsx14("div", { className: "b316-error", role: "alert", children: error }) : null,
2882
- /* @__PURE__ */ jsxs13("div", { className: "b316-device-actions", children: [
2883
- /* @__PURE__ */ jsx14(
3231
+ request.scopes.length > 0 ? /* @__PURE__ */ jsx16("ul", { className: "b316-device-scopes", children: request.scopes.map((scope) => /* @__PURE__ */ jsx16("li", { children: scope }, scope)) }) : null,
3232
+ error ? /* @__PURE__ */ jsx16("div", { className: "b316-error", role: "alert", children: error }) : null,
3233
+ /* @__PURE__ */ jsxs15("div", { className: "b316-device-actions", children: [
3234
+ /* @__PURE__ */ jsx16(
2884
3235
  "button",
2885
3236
  {
2886
3237
  type: "button",
@@ -2890,7 +3241,7 @@ function DeviceApproval({
2890
3241
  children: busy ? "Approving\u2026" : "Approve"
2891
3242
  }
2892
3243
  ),
2893
- /* @__PURE__ */ jsx14(
3244
+ /* @__PURE__ */ jsx16(
2894
3245
  "button",
2895
3246
  {
2896
3247
  type: "button",
@@ -2903,11 +3254,11 @@ function DeviceApproval({
2903
3254
  ] })
2904
3255
  ] });
2905
3256
  }
2906
- return /* @__PURE__ */ jsxs13("form", { className: cls("b316-card b316-device", className), style, onSubmit: lookUp, children: [
2907
- /* @__PURE__ */ jsx14("h3", { className: "b316-device-title", children: "Connect your device" }),
2908
- /* @__PURE__ */ jsx14("p", { className: "b316-muted", children: "Enter the code shown on your device." }),
2909
- error ? /* @__PURE__ */ jsx14("div", { className: "b316-error", role: "alert", children: error }) : null,
2910
- /* @__PURE__ */ jsx14(
3257
+ return /* @__PURE__ */ jsxs15("form", { className: cls("b316-card b316-device", className), style, onSubmit: lookUp, children: [
3258
+ /* @__PURE__ */ jsx16("h3", { className: "b316-device-title", children: "Connect your device" }),
3259
+ /* @__PURE__ */ jsx16("p", { className: "b316-muted", children: "Enter the code shown on your device." }),
3260
+ error ? /* @__PURE__ */ jsx16("div", { className: "b316-error", role: "alert", children: error }) : null,
3261
+ /* @__PURE__ */ jsx16(
2911
3262
  "input",
2912
3263
  {
2913
3264
  className: "b316-input",
@@ -2920,13 +3271,13 @@ function DeviceApproval({
2920
3271
  "aria-label": "Device code"
2921
3272
  }
2922
3273
  ),
2923
- /* @__PURE__ */ jsx14("button", { type: "submit", className: "b316-button", disabled: busy || code.trim().length < 4, children: busy ? "Checking\u2026" : "Continue" })
3274
+ /* @__PURE__ */ jsx16("button", { type: "submit", className: "b316-button", disabled: busy || code.trim().length < 4, children: busy ? "Checking\u2026" : "Continue" })
2924
3275
  ] });
2925
3276
  }
2926
3277
 
2927
3278
  // src/PrivacyControls.tsx
2928
- import { useState as useState13 } from "react";
2929
- import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
3279
+ import { useState as useState14 } from "react";
3280
+ import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
2930
3281
  function PrivacyControls({
2931
3282
  confirmWord = "DELETE",
2932
3283
  onErased,
@@ -2934,10 +3285,10 @@ function PrivacyControls({
2934
3285
  style
2935
3286
  }) {
2936
3287
  const { client, token } = useBase316();
2937
- const [confirming, setConfirming] = useState13(false);
2938
- const [typed, setTyped] = useState13("");
2939
- const [error, setError] = useState13(null);
2940
- const [busy, setBusy] = useState13(false);
3288
+ const [confirming, setConfirming] = useState14(false);
3289
+ const [typed, setTyped] = useState14("");
3290
+ const [error, setError] = useState14(null);
3291
+ const [busy, setBusy] = useState14(false);
2941
3292
  if (!token) {
2942
3293
  return null;
2943
3294
  }
@@ -2972,22 +3323,22 @@ function PrivacyControls({
2972
3323
  setBusy(false);
2973
3324
  }
2974
3325
  }
2975
- return /* @__PURE__ */ jsxs14("div", { className: cls("b316-card b316-privacy", className), style, children: [
2976
- /* @__PURE__ */ jsx15("h3", { className: "b316-privacy-title", children: "Your data" }),
2977
- error ? /* @__PURE__ */ jsx15("div", { className: "b316-error", role: "alert", children: error }) : null,
2978
- /* @__PURE__ */ jsxs14("div", { className: "b316-privacy-row", children: [
2979
- /* @__PURE__ */ jsxs14("div", { children: [
2980
- /* @__PURE__ */ jsx15("p", { children: "Download a copy" }),
2981
- /* @__PURE__ */ jsx15("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." })
3326
+ return /* @__PURE__ */ jsxs16("div", { className: cls("b316-card b316-privacy", className), style, children: [
3327
+ /* @__PURE__ */ jsx17("h3", { className: "b316-privacy-title", children: "Your data" }),
3328
+ error ? /* @__PURE__ */ jsx17("div", { className: "b316-error", role: "alert", children: error }) : null,
3329
+ /* @__PURE__ */ jsxs16("div", { className: "b316-privacy-row", children: [
3330
+ /* @__PURE__ */ jsxs16("div", { children: [
3331
+ /* @__PURE__ */ jsx17("p", { children: "Download a copy" }),
3332
+ /* @__PURE__ */ jsx17("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." })
2982
3333
  ] }),
2983
- /* @__PURE__ */ jsx15("button", { type: "button", className: "b316-button-quiet", disabled: busy, onClick: download, children: busy ? "Preparing\u2026" : "Download" })
3334
+ /* @__PURE__ */ jsx17("button", { type: "button", className: "b316-button-quiet", disabled: busy, onClick: download, children: busy ? "Preparing\u2026" : "Download" })
2984
3335
  ] }),
2985
- /* @__PURE__ */ jsxs14("div", { className: "b316-privacy-row", children: [
2986
- /* @__PURE__ */ jsxs14("div", { children: [
2987
- /* @__PURE__ */ jsx15("p", { children: "Delete your account" }),
2988
- /* @__PURE__ */ jsx15("p", { className: "b316-muted", children: "Permanent. Invoices already raised are kept, because the law requires it; everything that identifies you is removed from them." })
3336
+ /* @__PURE__ */ jsxs16("div", { className: "b316-privacy-row", children: [
3337
+ /* @__PURE__ */ jsxs16("div", { children: [
3338
+ /* @__PURE__ */ jsx17("p", { children: "Delete your account" }),
3339
+ /* @__PURE__ */ jsx17("p", { className: "b316-muted", children: "Permanent. Invoices already raised are kept, because the law requires it; everything that identifies you is removed from them." })
2989
3340
  ] }),
2990
- confirming ? null : /* @__PURE__ */ jsx15(
3341
+ confirming ? null : /* @__PURE__ */ jsx17(
2991
3342
  "button",
2992
3343
  {
2993
3344
  type: "button",
@@ -2998,13 +3349,13 @@ function PrivacyControls({
2998
3349
  }
2999
3350
  )
3000
3351
  ] }),
3001
- confirming ? /* @__PURE__ */ jsxs14("div", { className: "b316-privacy-confirm", children: [
3002
- /* @__PURE__ */ jsxs14("label", { className: "b316-label", htmlFor: "b316-privacy-confirm", children: [
3352
+ confirming ? /* @__PURE__ */ jsxs16("div", { className: "b316-privacy-confirm", children: [
3353
+ /* @__PURE__ */ jsxs16("label", { className: "b316-label", htmlFor: "b316-privacy-confirm", children: [
3003
3354
  "Type ",
3004
3355
  confirmWord,
3005
3356
  " to confirm"
3006
3357
  ] }),
3007
- /* @__PURE__ */ jsx15(
3358
+ /* @__PURE__ */ jsx17(
3008
3359
  "input",
3009
3360
  {
3010
3361
  id: "b316-privacy-confirm",
@@ -3014,8 +3365,8 @@ function PrivacyControls({
3014
3365
  onChange: (event) => setTyped(event.target.value)
3015
3366
  }
3016
3367
  ),
3017
- /* @__PURE__ */ jsxs14("div", { className: "b316-privacy-actions", children: [
3018
- /* @__PURE__ */ jsx15(
3368
+ /* @__PURE__ */ jsxs16("div", { className: "b316-privacy-actions", children: [
3369
+ /* @__PURE__ */ jsx17(
3019
3370
  "button",
3020
3371
  {
3021
3372
  type: "button",
@@ -3027,7 +3378,7 @@ function PrivacyControls({
3027
3378
  children: "Cancel"
3028
3379
  }
3029
3380
  ),
3030
- /* @__PURE__ */ jsx15(
3381
+ /* @__PURE__ */ jsx17(
3031
3382
  "button",
3032
3383
  {
3033
3384
  type: "button",
@@ -3043,12 +3394,12 @@ function PrivacyControls({
3043
3394
  }
3044
3395
 
3045
3396
  // src/TwoFactorManager.tsx
3046
- import { useState as useState14 } from "react";
3397
+ import { useState as useState15 } from "react";
3047
3398
 
3048
3399
  // src/QrCode.tsx
3049
3400
  import qrcode from "qrcode-generator";
3050
3401
  import { useMemo as useMemo2 } from "react";
3051
- import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
3402
+ import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
3052
3403
  var QUIET_ZONE = 4;
3053
3404
  function utf8Binary(value) {
3054
3405
  let binary = "";
@@ -3075,7 +3426,7 @@ function qrPath(value) {
3075
3426
  function QrCode({ value, label, size = 180, className }) {
3076
3427
  const { path, modules } = useMemo2(() => qrPath(value), [value]);
3077
3428
  const extent = modules + QUIET_ZONE * 2;
3078
- return /* @__PURE__ */ jsxs15(
3429
+ return /* @__PURE__ */ jsxs17(
3079
3430
  "svg",
3080
3431
  {
3081
3432
  className,
@@ -3087,15 +3438,15 @@ function QrCode({ value, label, size = 180, className }) {
3087
3438
  shapeRendering: "crispEdges",
3088
3439
  xmlns: "http://www.w3.org/2000/svg",
3089
3440
  children: [
3090
- /* @__PURE__ */ jsx16("rect", { width: extent, height: extent, fill: "#ffffff" }),
3091
- /* @__PURE__ */ jsx16("path", { d: path, fill: "#000000" })
3441
+ /* @__PURE__ */ jsx18("rect", { width: extent, height: extent, fill: "#ffffff" }),
3442
+ /* @__PURE__ */ jsx18("path", { d: path, fill: "#000000" })
3092
3443
  ]
3093
3444
  }
3094
3445
  );
3095
3446
  }
3096
3447
 
3097
3448
  // src/TwoFactorManager.tsx
3098
- import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
3449
+ import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
3099
3450
  function groupKey(secret) {
3100
3451
  return secret.replace(/\s+/g, "").replace(/(.{4})(?=.)/g, "$1 ");
3101
3452
  }
@@ -3108,12 +3459,12 @@ function TwoFactorManager({
3108
3459
  style
3109
3460
  }) {
3110
3461
  const { client, token } = useBase316();
3111
- const [stage, setStage] = useState14({ name: "idle" });
3112
- const [on, setOn] = useState14(enabled);
3113
- const [code, setCode] = useState14("");
3114
- const [phone, setPhone] = useState14("");
3115
- const [error, setError] = useState14(null);
3116
- const [busy, setBusy] = useState14(false);
3462
+ const [stage, setStage] = useState15({ name: "idle" });
3463
+ const [on, setOn] = useState15(enabled);
3464
+ const [code, setCode] = useState15("");
3465
+ const [phone, setPhone] = useState15("");
3466
+ const [error, setError] = useState15(null);
3467
+ const [busy, setBusy] = useState15(false);
3117
3468
  if (!token) {
3118
3469
  return null;
3119
3470
  }
@@ -3191,17 +3542,17 @@ function TwoFactorManager({
3191
3542
  setBusy(false);
3192
3543
  }
3193
3544
  }
3194
- return /* @__PURE__ */ jsxs16("div", { className: cls("b316-card b316-mfa", className), style, children: [
3195
- /* @__PURE__ */ jsx17("h3", { className: "b316-mfa-title", children: "Two-factor authentication" }),
3196
- error ? /* @__PURE__ */ jsx17("div", { className: "b316-error", role: "alert", children: error }) : null,
3197
- stage.name === "saved" ? /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-codes", children: [
3198
- /* @__PURE__ */ jsx17("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." }),
3199
- /* @__PURE__ */ jsx17("ul", { className: "b316-mfa-code-list", children: stage.recoveryCodes.map((recovery) => /* @__PURE__ */ jsx17("li", { children: /* @__PURE__ */ jsx17("code", { children: recovery }) }, recovery)) }),
3200
- /* @__PURE__ */ jsx17("button", { type: "button", className: "b316-button", onClick: () => setStage({ name: "idle" }), children: "I have saved them" })
3201
- ] }) : stage.name === "smsNumber" ? /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-enrol", children: [
3202
- /* @__PURE__ */ jsx17("p", { children: "We will text a code to this number now, and each time you sign in." }),
3203
- /* @__PURE__ */ jsx17("label", { className: "b316-label", htmlFor: "b316-mfa-phone", children: "Mobile number" }),
3204
- /* @__PURE__ */ jsx17(
3545
+ return /* @__PURE__ */ jsxs18("div", { className: cls("b316-card b316-mfa", className), style, children: [
3546
+ /* @__PURE__ */ jsx19("h3", { className: "b316-mfa-title", children: "Two-factor authentication" }),
3547
+ error ? /* @__PURE__ */ jsx19("div", { className: "b316-error", role: "alert", children: error }) : null,
3548
+ stage.name === "saved" ? /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-codes", children: [
3549
+ /* @__PURE__ */ jsx19("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." }),
3550
+ /* @__PURE__ */ jsx19("ul", { className: "b316-mfa-code-list", children: stage.recoveryCodes.map((recovery) => /* @__PURE__ */ jsx19("li", { children: /* @__PURE__ */ jsx19("code", { children: recovery }) }, recovery)) }),
3551
+ /* @__PURE__ */ jsx19("button", { type: "button", className: "b316-button", onClick: () => setStage({ name: "idle" }), children: "I have saved them" })
3552
+ ] }) : stage.name === "smsNumber" ? /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-enrol", children: [
3553
+ /* @__PURE__ */ jsx19("p", { children: "We will text a code to this number now, and each time you sign in." }),
3554
+ /* @__PURE__ */ jsx19("label", { className: "b316-label", htmlFor: "b316-mfa-phone", children: "Mobile number" }),
3555
+ /* @__PURE__ */ jsx19(
3205
3556
  "input",
3206
3557
  {
3207
3558
  id: "b316-mfa-phone",
@@ -3213,8 +3564,8 @@ function TwoFactorManager({
3213
3564
  onChange: (event) => setPhone(event.target.value)
3214
3565
  }
3215
3566
  ),
3216
- /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-actions", children: [
3217
- /* @__PURE__ */ jsx17(
3567
+ /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-actions", children: [
3568
+ /* @__PURE__ */ jsx19(
3218
3569
  "button",
3219
3570
  {
3220
3571
  type: "button",
@@ -3223,16 +3574,16 @@ function TwoFactorManager({
3223
3574
  children: "Cancel"
3224
3575
  }
3225
3576
  ),
3226
- /* @__PURE__ */ jsx17("button", { type: "button", className: "b316-button", disabled: busy, onClick: beginSms, children: busy ? "Sending\u2026" : "Send code" })
3577
+ /* @__PURE__ */ jsx19("button", { type: "button", className: "b316-button", disabled: busy, onClick: beginSms, children: busy ? "Sending\u2026" : "Send code" })
3227
3578
  ] })
3228
- ] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-enrol", children: [
3229
- /* @__PURE__ */ jsxs16("p", { children: [
3579
+ ] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-enrol", children: [
3580
+ /* @__PURE__ */ jsxs18("p", { children: [
3230
3581
  "We sent a code to ",
3231
3582
  stage.destinationHint,
3232
3583
  ". Enter it below to turn this on."
3233
3584
  ] }),
3234
- /* @__PURE__ */ jsx17("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3235
- /* @__PURE__ */ jsx17(
3585
+ /* @__PURE__ */ jsx19("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3586
+ /* @__PURE__ */ jsx19(
3236
3587
  "input",
3237
3588
  {
3238
3589
  id: "b316-mfa-code",
@@ -3243,8 +3594,8 @@ function TwoFactorManager({
3243
3594
  onChange: (event) => setCode(event.target.value)
3244
3595
  }
3245
3596
  ),
3246
- /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-actions", children: [
3247
- /* @__PURE__ */ jsx17(
3597
+ /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-actions", children: [
3598
+ /* @__PURE__ */ jsx19(
3248
3599
  "button",
3249
3600
  {
3250
3601
  type: "button",
@@ -3253,7 +3604,7 @@ function TwoFactorManager({
3253
3604
  children: "Cancel"
3254
3605
  }
3255
3606
  ),
3256
- /* @__PURE__ */ jsx17(
3607
+ /* @__PURE__ */ jsx19(
3257
3608
  "button",
3258
3609
  {
3259
3610
  type: "button",
@@ -3264,9 +3615,9 @@ function TwoFactorManager({
3264
3615
  }
3265
3616
  )
3266
3617
  ] })
3267
- ] }) : stage.name === "enrolling" ? /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-enrol", children: [
3268
- /* @__PURE__ */ jsx17("p", { children: "Scan this with your authenticator app (Google Authenticator, 1Password, Authy\u2026), then enter the six-digit code it shows." }),
3269
- /* @__PURE__ */ jsx17(
3618
+ ] }) : stage.name === "enrolling" ? /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-enrol", children: [
3619
+ /* @__PURE__ */ jsx19("p", { children: "Scan this with your authenticator app (Google Authenticator, 1Password, Authy\u2026), then enter the six-digit code it shows." }),
3620
+ /* @__PURE__ */ jsx19(
3270
3621
  QrCode,
3271
3622
  {
3272
3623
  className: "b316-mfa-qr",
@@ -3274,13 +3625,13 @@ function TwoFactorManager({
3274
3625
  label: "QR code for your authenticator app"
3275
3626
  }
3276
3627
  ),
3277
- /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-secret", children: [
3278
- /* @__PURE__ */ jsx17("span", { className: "b316-label", id: "b316-mfa-manual-key", children: "Can't scan? Enter this key" }),
3279
- /* @__PURE__ */ jsx17("code", { "aria-labelledby": "b316-mfa-manual-key", children: groupKey(stage.secret) })
3628
+ /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-secret", children: [
3629
+ /* @__PURE__ */ jsx19("span", { className: "b316-label", id: "b316-mfa-manual-key", children: "Can't scan? Enter this key" }),
3630
+ /* @__PURE__ */ jsx19("code", { "aria-labelledby": "b316-mfa-manual-key", children: groupKey(stage.secret) })
3280
3631
  ] }),
3281
- /* @__PURE__ */ jsx17("a", { className: "b316-mfa-uri", href: stage.uri, children: "Open in an authenticator app" }),
3282
- /* @__PURE__ */ jsx17("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3283
- /* @__PURE__ */ jsx17(
3632
+ /* @__PURE__ */ jsx19("a", { className: "b316-mfa-uri", href: stage.uri, children: "Open in an authenticator app" }),
3633
+ /* @__PURE__ */ jsx19("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3634
+ /* @__PURE__ */ jsx19(
3284
3635
  "input",
3285
3636
  {
3286
3637
  id: "b316-mfa-code",
@@ -3291,8 +3642,8 @@ function TwoFactorManager({
3291
3642
  onChange: (event) => setCode(event.target.value)
3292
3643
  }
3293
3644
  ),
3294
- /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-actions", children: [
3295
- /* @__PURE__ */ jsx17(
3645
+ /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-actions", children: [
3646
+ /* @__PURE__ */ jsx19(
3296
3647
  "button",
3297
3648
  {
3298
3649
  type: "button",
@@ -3301,7 +3652,7 @@ function TwoFactorManager({
3301
3652
  children: "Cancel"
3302
3653
  }
3303
3654
  ),
3304
- /* @__PURE__ */ jsx17(
3655
+ /* @__PURE__ */ jsx19(
3305
3656
  "button",
3306
3657
  {
3307
3658
  type: "button",
@@ -3312,9 +3663,9 @@ function TwoFactorManager({
3312
3663
  }
3313
3664
  )
3314
3665
  ] })
3315
- ] }) : on ? /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-on", children: [
3316
- /* @__PURE__ */ jsx17("p", { className: "b316-muted", children: "On. You will be asked for a code when you sign in." }),
3317
- /* @__PURE__ */ jsx17(
3666
+ ] }) : on ? /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-on", children: [
3667
+ /* @__PURE__ */ jsx19("p", { className: "b316-muted", children: "On. You will be asked for a code when you sign in." }),
3668
+ /* @__PURE__ */ jsx19(
3318
3669
  ConfirmButton,
3319
3670
  {
3320
3671
  className: "b316-button-quiet b316-danger",
@@ -3324,11 +3675,11 @@ function TwoFactorManager({
3324
3675
  children: "Turn off"
3325
3676
  }
3326
3677
  )
3327
- ] }) : /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-off", children: [
3328
- /* @__PURE__ */ jsx17("p", { className: "b316-muted", children: "Off. Turning it on means a code as well as your password, every time you sign in." }),
3329
- /* @__PURE__ */ jsxs16("div", { className: "b316-mfa-actions", children: [
3330
- /* @__PURE__ */ jsx17("button", { type: "button", className: "b316-button", disabled: busy, onClick: begin, children: busy ? "Starting\u2026" : "Use an authenticator app" }),
3331
- /* @__PURE__ */ jsx17(
3678
+ ] }) : /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-off", children: [
3679
+ /* @__PURE__ */ jsx19("p", { className: "b316-muted", children: "Off. Turning it on means a code as well as your password, every time you sign in." }),
3680
+ /* @__PURE__ */ jsxs18("div", { className: "b316-mfa-actions", children: [
3681
+ /* @__PURE__ */ jsx19("button", { type: "button", className: "b316-button", disabled: busy, onClick: begin, children: busy ? "Starting\u2026" : "Use an authenticator app" }),
3682
+ /* @__PURE__ */ jsx19(
3332
3683
  "button",
3333
3684
  {
3334
3685
  type: "button",
@@ -3338,7 +3689,7 @@ function TwoFactorManager({
3338
3689
  children: "Email me a code"
3339
3690
  }
3340
3691
  ),
3341
- allowSms ? /* @__PURE__ */ jsx17(
3692
+ allowSms ? /* @__PURE__ */ jsx19(
3342
3693
  "button",
3343
3694
  {
3344
3695
  type: "button",
@@ -3354,14 +3705,14 @@ function TwoFactorManager({
3354
3705
  }
3355
3706
 
3356
3707
  // src/ForgotPassword.tsx
3357
- import { useState as useState15 } from "react";
3358
- import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
3708
+ import { useState as useState16 } from "react";
3709
+ import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
3359
3710
  function ForgotPassword({ onSent, signInUrl, className, style }) {
3360
3711
  const { client } = useBase316();
3361
- const [email, setEmail] = useState15("");
3362
- const [sent, setSent] = useState15(false);
3363
- const [busy, setBusy] = useState15(false);
3364
- const [error, setError] = useState15(null);
3712
+ const [email, setEmail] = useState16("");
3713
+ const [sent, setSent] = useState16(false);
3714
+ const [busy, setBusy] = useState16(false);
3715
+ const [error, setError] = useState16(null);
3365
3716
  async function submit(event) {
3366
3717
  event.preventDefault();
3367
3718
  setBusy(true);
@@ -3377,22 +3728,22 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
3377
3728
  }
3378
3729
  }
3379
3730
  if (sent) {
3380
- return /* @__PURE__ */ jsxs17("div", { className: cls("b316-card", className), style, children: [
3381
- /* @__PURE__ */ jsx18("h3", { className: "b316-form-title", children: "Check your email" }),
3382
- /* @__PURE__ */ jsxs17("p", { className: "b316-muted", children: [
3731
+ return /* @__PURE__ */ jsxs19("div", { className: cls("b316-card", className), style, children: [
3732
+ /* @__PURE__ */ jsx20("h3", { className: "b316-form-title", children: "Check your email" }),
3733
+ /* @__PURE__ */ jsxs19("p", { className: "b316-muted", children: [
3383
3734
  "If there is an account for ",
3384
3735
  email.trim(),
3385
3736
  ", a link to set a new password is on its way."
3386
3737
  ] }),
3387
- signInUrl ? /* @__PURE__ */ jsx18("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3738
+ signInUrl ? /* @__PURE__ */ jsx20("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3388
3739
  ] });
3389
3740
  }
3390
- return /* @__PURE__ */ jsxs17("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3391
- /* @__PURE__ */ jsx18("h3", { className: "b316-form-title", children: "Reset your password" }),
3392
- error ? /* @__PURE__ */ jsx18("div", { className: "b316-error", role: "alert", children: error }) : null,
3393
- /* @__PURE__ */ jsxs17("div", { className: "b316-field", children: [
3394
- /* @__PURE__ */ jsx18("label", { className: "b316-label", htmlFor: "b316-forgot-email", children: "Email" }),
3395
- /* @__PURE__ */ jsx18(
3741
+ return /* @__PURE__ */ jsxs19("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3742
+ /* @__PURE__ */ jsx20("h3", { className: "b316-form-title", children: "Reset your password" }),
3743
+ error ? /* @__PURE__ */ jsx20("div", { className: "b316-error", role: "alert", children: error }) : null,
3744
+ /* @__PURE__ */ jsxs19("div", { className: "b316-field", children: [
3745
+ /* @__PURE__ */ jsx20("label", { className: "b316-label", htmlFor: "b316-forgot-email", children: "Email" }),
3746
+ /* @__PURE__ */ jsx20(
3396
3747
  "input",
3397
3748
  {
3398
3749
  id: "b316-forgot-email",
@@ -3405,14 +3756,14 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
3405
3756
  }
3406
3757
  )
3407
3758
  ] }),
3408
- /* @__PURE__ */ jsx18("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Send reset link" }),
3409
- signInUrl ? /* @__PURE__ */ jsx18("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3759
+ /* @__PURE__ */ jsx20("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Send reset link" }),
3760
+ signInUrl ? /* @__PURE__ */ jsx20("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3410
3761
  ] });
3411
3762
  }
3412
3763
 
3413
3764
  // src/ResetPassword.tsx
3414
- import { useEffect as useEffect12, useState as useState16 } from "react";
3415
- import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
3765
+ import { useEffect as useEffect13, useState as useState17 } from "react";
3766
+ import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
3416
3767
  function ResetPassword({
3417
3768
  token: supplied,
3418
3769
  onReset,
@@ -3421,13 +3772,13 @@ function ResetPassword({
3421
3772
  style
3422
3773
  }) {
3423
3774
  const { client } = useBase316();
3424
- const [token, setToken] = useState16(supplied ?? null);
3425
- const [password, setPassword] = useState16("");
3426
- const [confirmation, setConfirmation] = useState16("");
3427
- const [done, setDone] = useState16(false);
3428
- const [busy, setBusy] = useState16(false);
3429
- const [error, setError] = useState16(null);
3430
- useEffect12(() => {
3775
+ const [token, setToken] = useState17(supplied ?? null);
3776
+ const [password, setPassword] = useState17("");
3777
+ const [confirmation, setConfirmation] = useState17("");
3778
+ const [done, setDone] = useState17(false);
3779
+ const [busy, setBusy] = useState17(false);
3780
+ const [error, setError] = useState17(null);
3781
+ useEffect13(() => {
3431
3782
  if (supplied || typeof window === "undefined") {
3432
3783
  return;
3433
3784
  }
@@ -3462,24 +3813,24 @@ function ResetPassword({
3462
3813
  }
3463
3814
  }
3464
3815
  if (done) {
3465
- return /* @__PURE__ */ jsxs18("div", { className: cls("b316-card", className), style, children: [
3466
- /* @__PURE__ */ jsx19("h3", { className: "b316-form-title", children: "Password changed" }),
3467
- /* @__PURE__ */ jsx19("p", { className: "b316-muted", children: "You can sign in with your new password." }),
3468
- signInUrl ? /* @__PURE__ */ jsx19("a", { className: "b316-button-link", href: signInUrl, children: "Sign in" }) : null
3816
+ return /* @__PURE__ */ jsxs20("div", { className: cls("b316-card", className), style, children: [
3817
+ /* @__PURE__ */ jsx21("h3", { className: "b316-form-title", children: "Password changed" }),
3818
+ /* @__PURE__ */ jsx21("p", { className: "b316-muted", children: "You can sign in with your new password." }),
3819
+ signInUrl ? /* @__PURE__ */ jsx21("a", { className: "b316-button-link", href: signInUrl, children: "Sign in" }) : null
3469
3820
  ] });
3470
3821
  }
3471
3822
  if (!token) {
3472
- return /* @__PURE__ */ jsxs18("div", { className: cls("b316-card", className), style, children: [
3473
- /* @__PURE__ */ jsx19("h3", { className: "b316-form-title", children: "Nothing to reset" }),
3474
- /* @__PURE__ */ jsx19("p", { className: "b316-muted", children: "This page needs the link from your email. Request a new one if yours has expired." })
3823
+ return /* @__PURE__ */ jsxs20("div", { className: cls("b316-card", className), style, children: [
3824
+ /* @__PURE__ */ jsx21("h3", { className: "b316-form-title", children: "Nothing to reset" }),
3825
+ /* @__PURE__ */ jsx21("p", { className: "b316-muted", children: "This page needs the link from your email. Request a new one if yours has expired." })
3475
3826
  ] });
3476
3827
  }
3477
- return /* @__PURE__ */ jsxs18("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3478
- /* @__PURE__ */ jsx19("h3", { className: "b316-form-title", children: "Choose a new password" }),
3479
- error ? /* @__PURE__ */ jsx19("div", { className: "b316-error", role: "alert", children: error }) : null,
3480
- /* @__PURE__ */ jsxs18("div", { className: "b316-field", children: [
3481
- /* @__PURE__ */ jsx19("label", { className: "b316-label", htmlFor: "b316-reset-password", children: "New password" }),
3482
- /* @__PURE__ */ jsx19(
3828
+ return /* @__PURE__ */ jsxs20("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3829
+ /* @__PURE__ */ jsx21("h3", { className: "b316-form-title", children: "Choose a new password" }),
3830
+ error ? /* @__PURE__ */ jsx21("div", { className: "b316-error", role: "alert", children: error }) : null,
3831
+ /* @__PURE__ */ jsxs20("div", { className: "b316-field", children: [
3832
+ /* @__PURE__ */ jsx21("label", { className: "b316-label", htmlFor: "b316-reset-password", children: "New password" }),
3833
+ /* @__PURE__ */ jsx21(
3483
3834
  "input",
3484
3835
  {
3485
3836
  id: "b316-reset-password",
@@ -3492,9 +3843,9 @@ function ResetPassword({
3492
3843
  }
3493
3844
  )
3494
3845
  ] }),
3495
- /* @__PURE__ */ jsxs18("div", { className: "b316-field", children: [
3496
- /* @__PURE__ */ jsx19("label", { className: "b316-label", htmlFor: "b316-reset-confirm", children: "Repeat it" }),
3497
- /* @__PURE__ */ jsx19(
3846
+ /* @__PURE__ */ jsxs20("div", { className: "b316-field", children: [
3847
+ /* @__PURE__ */ jsx21("label", { className: "b316-label", htmlFor: "b316-reset-confirm", children: "Repeat it" }),
3848
+ /* @__PURE__ */ jsx21(
3498
3849
  "input",
3499
3850
  {
3500
3851
  id: "b316-reset-confirm",
@@ -3507,13 +3858,13 @@ function ResetPassword({
3507
3858
  }
3508
3859
  )
3509
3860
  ] }),
3510
- /* @__PURE__ */ jsx19("button", { type: "submit", className: "b316-button", disabled: busy || !password, children: busy ? "Saving\u2026" : "Set password" })
3861
+ /* @__PURE__ */ jsx21("button", { type: "submit", className: "b316-button", disabled: busy || !password, children: busy ? "Saving\u2026" : "Set password" })
3511
3862
  ] });
3512
3863
  }
3513
3864
 
3514
3865
  // src/VerifyEmail.tsx
3515
- import { useEffect as useEffect13, useRef as useRef4, useState as useState17 } from "react";
3516
- import { Fragment as Fragment5, jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
3866
+ import { useEffect as useEffect14, useRef as useRef4, useState as useState18 } from "react";
3867
+ import { Fragment as Fragment7, jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
3517
3868
  function VerifyEmail({
3518
3869
  token: supplied,
3519
3870
  onVerified,
@@ -3522,9 +3873,9 @@ function VerifyEmail({
3522
3873
  style
3523
3874
  }) {
3524
3875
  const { client } = useBase316();
3525
- const [state, setState] = useState17("waiting");
3876
+ const [state, setState] = useState18("waiting");
3526
3877
  const spent = useRef4(false);
3527
- useEffect13(() => {
3878
+ useEffect14(() => {
3528
3879
  if (spent.current) {
3529
3880
  return;
3530
3881
  }
@@ -3550,22 +3901,22 @@ function VerifyEmail({
3550
3901
  setState("failed");
3551
3902
  });
3552
3903
  }, [client, supplied, onVerified]);
3553
- return /* @__PURE__ */ jsx20("div", { className: cls("b316-card", className), style, children: state === "verified" ? /* @__PURE__ */ jsxs19(Fragment5, { children: [
3554
- /* @__PURE__ */ jsx20("h3", { className: "b316-form-title", children: "Email confirmed" }),
3555
- /* @__PURE__ */ jsx20("p", { className: "b316-muted", children: "Thanks \u2014 your address is verified." }),
3556
- continueUrl ? /* @__PURE__ */ jsx20("a", { className: "b316-button-link", href: continueUrl, children: "Continue" }) : null
3557
- ] }) : state === "failed" ? /* @__PURE__ */ jsxs19(Fragment5, { children: [
3558
- /* @__PURE__ */ jsx20("h3", { className: "b316-form-title", children: "That link did not work" }),
3559
- /* @__PURE__ */ jsx20("p", { className: "b316-muted", children: "It may have expired or already been used. Ask for a new one and try again." })
3560
- ] }) : state === "missing" ? /* @__PURE__ */ jsxs19(Fragment5, { children: [
3561
- /* @__PURE__ */ jsx20("h3", { className: "b316-form-title", children: "Nothing to confirm" }),
3562
- /* @__PURE__ */ jsx20("p", { className: "b316-muted", children: "This page needs the link from your email." })
3563
- ] }) : /* @__PURE__ */ jsx20("p", { className: "b316-muted", children: "Confirming your email\u2026" }) });
3904
+ return /* @__PURE__ */ jsx22("div", { className: cls("b316-card", className), style, children: state === "verified" ? /* @__PURE__ */ jsxs21(Fragment7, { children: [
3905
+ /* @__PURE__ */ jsx22("h3", { className: "b316-form-title", children: "Email confirmed" }),
3906
+ /* @__PURE__ */ jsx22("p", { className: "b316-muted", children: "Thanks \u2014 your address is verified." }),
3907
+ continueUrl ? /* @__PURE__ */ jsx22("a", { className: "b316-button-link", href: continueUrl, children: "Continue" }) : null
3908
+ ] }) : state === "failed" ? /* @__PURE__ */ jsxs21(Fragment7, { children: [
3909
+ /* @__PURE__ */ jsx22("h3", { className: "b316-form-title", children: "That link did not work" }),
3910
+ /* @__PURE__ */ jsx22("p", { className: "b316-muted", children: "It may have expired or already been used. Ask for a new one and try again." })
3911
+ ] }) : state === "missing" ? /* @__PURE__ */ jsxs21(Fragment7, { children: [
3912
+ /* @__PURE__ */ jsx22("h3", { className: "b316-form-title", children: "Nothing to confirm" }),
3913
+ /* @__PURE__ */ jsx22("p", { className: "b316-muted", children: "This page needs the link from your email." })
3914
+ ] }) : /* @__PURE__ */ jsx22("p", { className: "b316-muted", children: "Confirming your email\u2026" }) });
3564
3915
  }
3565
3916
 
3566
3917
  // src/TeamMembers.tsx
3567
- import { useCallback as useCallback7, useEffect as useEffect14, useState as useState18 } from "react";
3568
- import { Fragment as Fragment6, jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
3918
+ import { useCallback as useCallback7, useEffect as useEffect15, useState as useState19 } from "react";
3919
+ import { Fragment as Fragment8, jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
3569
3920
  function TeamMembers({
3570
3921
  organizationId,
3571
3922
  onInvited,
@@ -3575,13 +3926,13 @@ function TeamMembers({
3575
3926
  style
3576
3927
  }) {
3577
3928
  const { client, token, session } = useBase316();
3578
- const [teams, setTeams] = useState18(null);
3579
- const [members, setMembers] = useState18(null);
3580
- const [invitations, setInvitations] = useState18(null);
3581
- const [email, setEmail] = useState18("");
3582
- const [busy, setBusy] = useState18(false);
3583
- const [error, setError] = useState18(null);
3584
- const [copied, setCopied] = useState18(null);
3929
+ const [teams, setTeams] = useState19(null);
3930
+ const [members, setMembers] = useState19(null);
3931
+ const [invitations, setInvitations] = useState19(null);
3932
+ const [email, setEmail] = useState19("");
3933
+ const [busy, setBusy] = useState19(false);
3934
+ const [error, setError] = useState19(null);
3935
+ const [copied, setCopied] = useState19(null);
3585
3936
  const chosen = organizationId ?? (teams?.length === 1 ? teams[0].id : null);
3586
3937
  const team = teams?.find((candidate) => candidate.id === chosen) ?? null;
3587
3938
  const load = useCallback7(() => {
@@ -3592,8 +3943,8 @@ function TeamMembers({
3592
3943
  (cause) => setError(cause instanceof Error ? cause.message : "Could not load your teams.")
3593
3944
  );
3594
3945
  }, [client, token]);
3595
- useEffect14(load, [load]);
3596
- useEffect14(() => {
3946
+ useEffect15(load, [load]);
3947
+ useEffect15(() => {
3597
3948
  if (!token || !chosen) {
3598
3949
  return;
3599
3950
  }
@@ -3624,10 +3975,10 @@ function TeamMembers({
3624
3975
  return null;
3625
3976
  }
3626
3977
  if (!teams) {
3627
- return /* @__PURE__ */ jsx21("div", { className: cls("b316-card", className), style, children: error ?? "Loading\u2026" });
3978
+ return /* @__PURE__ */ jsx23("div", { className: cls("b316-card", className), style, children: error ?? "Loading\u2026" });
3628
3979
  }
3629
3980
  if (!chosen) {
3630
- return /* @__PURE__ */ jsx21("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." });
3981
+ return /* @__PURE__ */ jsx23("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." });
3631
3982
  }
3632
3983
  const canManage = invitations !== null;
3633
3984
  async function invite(event) {
@@ -3677,30 +4028,30 @@ function TeamMembers({
3677
4028
  setError(cause instanceof Error ? cause.message : "That invitation could not be withdrawn.");
3678
4029
  }
3679
4030
  }
3680
- return /* @__PURE__ */ jsxs20("div", { className: cls("b316-card b316-team", className), style, children: [
3681
- /* @__PURE__ */ jsx21("h3", { className: "b316-team-title", children: team?.name ?? "Team" }),
4031
+ return /* @__PURE__ */ jsxs22("div", { className: cls("b316-card b316-team", className), style, children: [
4032
+ /* @__PURE__ */ jsx23("h3", { className: "b316-team-title", children: team?.name ?? "Team" }),
3682
4033
  team?.inherited ? (
3683
4034
  // Not a member of this team, so not in the list below and with nothing
3684
4035
  // to leave: access comes from the team that manages it, and ends there.
3685
- /* @__PURE__ */ jsxs20("div", { className: "b316-muted", children: [
4036
+ /* @__PURE__ */ jsxs22("div", { className: "b316-muted", children: [
3686
4037
  "You have access through",
3687
4038
  " ",
3688
4039
  teams.find((candidate) => candidate.id === team.via)?.name ?? "the organization that manages this team",
3689
4040
  "."
3690
4041
  ] })
3691
4042
  ) : null,
3692
- error ? /* @__PURE__ */ jsx21("div", { className: "b316-error", role: "alert", children: error }) : null,
3693
- /* @__PURE__ */ jsx21("ul", { className: "b316-team-list", children: (members ?? []).map((member) => /* @__PURE__ */ jsxs20("li", { className: "b316-team-member", children: [
3694
- /* @__PURE__ */ jsxs20("div", { children: [
3695
- /* @__PURE__ */ jsx21("div", { children: member.user.name ?? member.user.email ?? "Someone" }),
3696
- /* @__PURE__ */ jsxs20("div", { className: "b316-muted", children: [
4043
+ error ? /* @__PURE__ */ jsx23("div", { className: "b316-error", role: "alert", children: error }) : null,
4044
+ /* @__PURE__ */ jsx23("ul", { className: "b316-team-list", children: (members ?? []).map((member) => /* @__PURE__ */ jsxs22("li", { className: "b316-team-member", children: [
4045
+ /* @__PURE__ */ jsxs22("div", { children: [
4046
+ /* @__PURE__ */ jsx23("div", { children: member.user.name ?? member.user.email ?? "Someone" }),
4047
+ /* @__PURE__ */ jsxs22("div", { className: "b316-muted", children: [
3697
4048
  member.user.email,
3698
4049
  member.user.id === session?.userId ? " \xB7 you" : ""
3699
4050
  ] })
3700
4051
  ] }),
3701
- /* @__PURE__ */ jsxs20("div", { className: "b316-team-member-side", children: [
3702
- /* @__PURE__ */ jsx21("span", { className: "b316-chip", children: member.role.name }),
3703
- canManage || member.user.id === session?.userId ? /* @__PURE__ */ jsx21(
4052
+ /* @__PURE__ */ jsxs22("div", { className: "b316-team-member-side", children: [
4053
+ /* @__PURE__ */ jsx23("span", { className: "b316-chip", children: member.role.name }),
4054
+ canManage || member.user.id === session?.userId ? /* @__PURE__ */ jsx23(
3704
4055
  ConfirmButton,
3705
4056
  {
3706
4057
  className: "b316-button-quiet b316-danger",
@@ -3712,19 +4063,19 @@ function TeamMembers({
3712
4063
  ) : null
3713
4064
  ] })
3714
4065
  ] }, member.id)) }),
3715
- canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */ jsxs20(Fragment6, { children: [
3716
- /* @__PURE__ */ jsx21("h4", { className: "b316-team-subtitle", children: "Invited" }),
3717
- /* @__PURE__ */ jsx21("ul", { className: "b316-team-list", children: (invitations ?? []).map((invitation) => /* @__PURE__ */ jsxs20("li", { className: "b316-team-member", children: [
3718
- /* @__PURE__ */ jsxs20("div", { children: [
3719
- /* @__PURE__ */ jsx21("div", { children: invitation.email }),
3720
- /* @__PURE__ */ jsxs20("div", { className: "b316-muted", children: [
4066
+ canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */ jsxs22(Fragment8, { children: [
4067
+ /* @__PURE__ */ jsx23("h4", { className: "b316-team-subtitle", children: "Invited" }),
4068
+ /* @__PURE__ */ jsx23("ul", { className: "b316-team-list", children: (invitations ?? []).map((invitation) => /* @__PURE__ */ jsxs22("li", { className: "b316-team-member", children: [
4069
+ /* @__PURE__ */ jsxs22("div", { children: [
4070
+ /* @__PURE__ */ jsx23("div", { children: invitation.email }),
4071
+ /* @__PURE__ */ jsxs22("div", { className: "b316-muted", children: [
3721
4072
  invitation.role.name,
3722
4073
  " \xB7 expires",
3723
4074
  " ",
3724
4075
  new Date(invitation.expiresAt).toLocaleDateString()
3725
4076
  ] })
3726
4077
  ] }),
3727
- /* @__PURE__ */ jsx21(
4078
+ /* @__PURE__ */ jsx23(
3728
4079
  "button",
3729
4080
  {
3730
4081
  type: "button",
@@ -3735,10 +4086,10 @@ function TeamMembers({
3735
4086
  )
3736
4087
  ] }, invitation.id)) })
3737
4088
  ] }) : null,
3738
- canManage ? /* @__PURE__ */ jsxs20("form", { className: "b316-team-invite", onSubmit: invite, children: [
3739
- /* @__PURE__ */ jsx21("label", { className: "b316-label", htmlFor: "b316-invite-email", children: "Invite by email" }),
3740
- /* @__PURE__ */ jsxs20("div", { className: "b316-team-invite-row", children: [
3741
- /* @__PURE__ */ jsx21(
4089
+ canManage ? /* @__PURE__ */ jsxs22("form", { className: "b316-team-invite", onSubmit: invite, children: [
4090
+ /* @__PURE__ */ jsx23("label", { className: "b316-label", htmlFor: "b316-invite-email", children: "Invite by email" }),
4091
+ /* @__PURE__ */ jsxs22("div", { className: "b316-team-invite-row", children: [
4092
+ /* @__PURE__ */ jsx23(
3742
4093
  "input",
3743
4094
  {
3744
4095
  id: "b316-invite-email",
@@ -3750,19 +4101,19 @@ function TeamMembers({
3750
4101
  onChange: (event) => setEmail(event.target.value)
3751
4102
  }
3752
4103
  ),
3753
- /* @__PURE__ */ jsx21("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Invite" })
4104
+ /* @__PURE__ */ jsx23("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Invite" })
3754
4105
  ] })
3755
4106
  ] }) : null,
3756
- copied ? /* @__PURE__ */ jsxs20("div", { className: "b316-team-link", children: [
3757
- /* @__PURE__ */ jsx21("div", { className: "b316-muted", children: "Send them this link. It is shown once and cannot be fetched again." }),
3758
- /* @__PURE__ */ jsx21("code", { children: copied })
4107
+ copied ? /* @__PURE__ */ jsxs22("div", { className: "b316-team-link", children: [
4108
+ /* @__PURE__ */ jsx23("div", { className: "b316-muted", children: "Send them this link. It is shown once and cannot be fetched again." }),
4109
+ /* @__PURE__ */ jsx23("code", { children: copied })
3759
4110
  ] }) : null
3760
4111
  ] });
3761
4112
  }
3762
4113
 
3763
4114
  // src/AcceptInvitation.tsx
3764
- import { useEffect as useEffect15, useState as useState19 } from "react";
3765
- import { Fragment as Fragment7, jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
4115
+ import { useEffect as useEffect16, useState as useState20 } from "react";
4116
+ import { Fragment as Fragment9, jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
3766
4117
  function signUpUrlWithInvitation(url, token) {
3767
4118
  const [beforeHash, ...hash] = url.split("#");
3768
4119
  const base = beforeHash ?? "";
@@ -3781,18 +4132,18 @@ function AcceptInvitation({
3781
4132
  style
3782
4133
  }) {
3783
4134
  const { client, token: session, session: user } = useBase316();
3784
- const [invitationToken, setInvitationToken] = useState19(supplied ?? null);
3785
- const [preview, setPreview] = useState19(null);
3786
- const [state, setState] = useState19("loading");
3787
- const [error, setError] = useState19(null);
3788
- const [busy, setBusy] = useState19(false);
3789
- useEffect15(() => {
4135
+ const [invitationToken, setInvitationToken] = useState20(supplied ?? null);
4136
+ const [preview, setPreview] = useState20(null);
4137
+ const [state, setState] = useState20("loading");
4138
+ const [error, setError] = useState20(null);
4139
+ const [busy, setBusy] = useState20(false);
4140
+ useEffect16(() => {
3790
4141
  if (supplied || typeof window === "undefined") {
3791
4142
  return;
3792
4143
  }
3793
4144
  setInvitationToken(new URL(window.location.href).searchParams.get("invitation"));
3794
4145
  }, [supplied]);
3795
- useEffect15(() => {
4146
+ useEffect16(() => {
3796
4147
  if (!invitationToken) {
3797
4148
  setState(supplied === void 0 ? "loading" : "invalid");
3798
4149
  return;
@@ -3829,42 +4180,42 @@ function AcceptInvitation({
3829
4180
  }
3830
4181
  }
3831
4182
  if (state === "loading") {
3832
- return /* @__PURE__ */ jsx22("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
4183
+ return /* @__PURE__ */ jsx24("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
3833
4184
  }
3834
4185
  if (state === "invalid") {
3835
- return /* @__PURE__ */ jsxs21("div", { className: cls("b316-card", className), style, children: [
3836
- /* @__PURE__ */ jsx22("h3", { className: "b316-form-title", children: "That invitation is no longer valid" }),
3837
- /* @__PURE__ */ jsx22("p", { className: "b316-muted", children: "It may have expired, been withdrawn, or already been used. Ask for a new one." })
4186
+ return /* @__PURE__ */ jsxs23("div", { className: cls("b316-card", className), style, children: [
4187
+ /* @__PURE__ */ jsx24("h3", { className: "b316-form-title", children: "That invitation is no longer valid" }),
4188
+ /* @__PURE__ */ jsx24("p", { className: "b316-muted", children: "It may have expired, been withdrawn, or already been used. Ask for a new one." })
3838
4189
  ] });
3839
4190
  }
3840
4191
  if (state === "accepted") {
3841
- return /* @__PURE__ */ jsx22("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsxs21("h3", { className: "b316-form-title", children: [
4192
+ return /* @__PURE__ */ jsx24("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsxs23("h3", { className: "b316-form-title", children: [
3842
4193
  "You have joined ",
3843
4194
  preview?.organizationName
3844
4195
  ] }) });
3845
4196
  }
3846
4197
  const matches = !user || (user.user.email ?? "").toLowerCase() === preview?.email.toLowerCase();
3847
- return /* @__PURE__ */ jsxs21("div", { className: cls("b316-card b316-invitation", className), style, children: [
3848
- /* @__PURE__ */ jsxs21("h3", { className: "b316-form-title", children: [
4198
+ return /* @__PURE__ */ jsxs23("div", { className: cls("b316-card b316-invitation", className), style, children: [
4199
+ /* @__PURE__ */ jsxs23("h3", { className: "b316-form-title", children: [
3849
4200
  "Join ",
3850
4201
  preview?.organizationName
3851
4202
  ] }),
3852
- /* @__PURE__ */ jsxs21("p", { className: "b316-muted", children: [
4203
+ /* @__PURE__ */ jsxs23("p", { className: "b316-muted", children: [
3853
4204
  "Invited as ",
3854
4205
  preview?.email,
3855
4206
  " \xB7 ",
3856
4207
  preview?.roleName
3857
4208
  ] }),
3858
- error ? /* @__PURE__ */ jsx22("div", { className: "b316-error", role: "alert", children: error }) : null,
3859
- !session ? /* @__PURE__ */ jsxs21(Fragment7, { children: [
3860
- /* @__PURE__ */ jsxs21("p", { children: [
4209
+ error ? /* @__PURE__ */ jsx24("div", { className: "b316-error", role: "alert", children: error }) : null,
4210
+ !session ? /* @__PURE__ */ jsxs23(Fragment9, { children: [
4211
+ /* @__PURE__ */ jsxs23("p", { children: [
3861
4212
  "Sign in as ",
3862
4213
  preview?.email,
3863
4214
  " to accept."
3864
4215
  ] }),
3865
- /* @__PURE__ */ jsxs21("div", { className: "b316-invitation-actions", children: [
3866
- signInUrl ? /* @__PURE__ */ jsx22("a", { className: "b316-button", href: signInUrl, children: "Sign in" }) : null,
3867
- signUpUrl ? /* @__PURE__ */ jsx22(
4216
+ /* @__PURE__ */ jsxs23("div", { className: "b316-invitation-actions", children: [
4217
+ signInUrl ? /* @__PURE__ */ jsx24("a", { className: "b316-button", href: signInUrl, children: "Sign in" }) : null,
4218
+ signUpUrl ? /* @__PURE__ */ jsx24(
3868
4219
  "a",
3869
4220
  {
3870
4221
  className: "b316-button-link",
@@ -3877,20 +4228,20 @@ function AcceptInvitation({
3877
4228
  // Said before they press anything. The server refuses this, but
3878
4229
  // finding out after a click reads as a broken invitation rather than
3879
4230
  // as being signed in as the wrong person.
3880
- /* @__PURE__ */ jsxs21("p", { children: [
4231
+ /* @__PURE__ */ jsxs23("p", { children: [
3881
4232
  "You are signed in as ",
3882
4233
  user?.user.email,
3883
4234
  ". This invitation was sent to ",
3884
4235
  preview?.email,
3885
4236
  " \u2014 sign in as that address to accept it."
3886
4237
  ] })
3887
- ) : /* @__PURE__ */ jsx22("button", { type: "button", className: "b316-button", disabled: busy, onClick: accept, children: busy ? "Joining\u2026" : `Join ${preview?.organizationName}` })
4238
+ ) : /* @__PURE__ */ jsx24("button", { type: "button", className: "b316-button", disabled: busy, onClick: accept, children: busy ? "Joining\u2026" : `Join ${preview?.organizationName}` })
3888
4239
  ] });
3889
4240
  }
3890
4241
 
3891
4242
  // src/PayInvoice.tsx
3892
- import { useEffect as useEffect16, useRef as useRef5, useState as useState20 } from "react";
3893
- import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
4243
+ import { useEffect as useEffect17, useRef as useRef5, useState as useState21 } from "react";
4244
+ import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
3894
4245
  var STRIPE_SRC = "https://js.stripe.com/v3/";
3895
4246
  function loadStripeScript() {
3896
4247
  if (typeof window === "undefined") {
@@ -3925,11 +4276,11 @@ function PayInvoice({
3925
4276
  const mountRef = useRef5(null);
3926
4277
  const stripeRef = useRef5(null);
3927
4278
  const elementsRef = useRef5(null);
3928
- const [ready, setReady] = useState20(false);
3929
- const [paying, setPaying] = useState20(false);
3930
- const [done, setDone] = useState20(false);
3931
- const [error, setError] = useState20(null);
3932
- useEffect16(() => {
4279
+ const [ready, setReady] = useState21(false);
4280
+ const [paying, setPaying] = useState21(false);
4281
+ const [done, setDone] = useState21(false);
4282
+ const [error, setError] = useState21(null);
4283
+ useEffect17(() => {
3933
4284
  let cancelled = false;
3934
4285
  async function start() {
3935
4286
  const base = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}`;
@@ -3982,17 +4333,17 @@ function PayInvoice({
3982
4333
  onPaid?.();
3983
4334
  };
3984
4335
  if (done) {
3985
- return /* @__PURE__ */ jsx23("div", { className: cls("b316-pay", className), style, children: /* @__PURE__ */ jsx23("p", { className: "b316-pay__done", children: "Paid \u2014 thank you." }) });
4336
+ return /* @__PURE__ */ jsx25("div", { className: cls("b316-pay", className), style, children: /* @__PURE__ */ jsx25("p", { className: "b316-pay__done", children: "Paid \u2014 thank you." }) });
3986
4337
  }
3987
- return /* @__PURE__ */ jsxs22("form", { className: cls("b316-pay", className), style, onSubmit: submit, children: [
3988
- error ? /* @__PURE__ */ jsx23("p", { className: "b316-pay__error", role: "alert", children: error }) : null,
3989
- /* @__PURE__ */ jsx23("div", { ref: mountRef, className: "b316-pay__element" }),
3990
- /* @__PURE__ */ jsx23("button", { className: "b316-pay__submit", type: "submit", disabled: !ready || paying, children: paying ? "Paying\u2026" : "Pay" })
4338
+ return /* @__PURE__ */ jsxs24("form", { className: cls("b316-pay", className), style, onSubmit: submit, children: [
4339
+ error ? /* @__PURE__ */ jsx25("p", { className: "b316-pay__error", role: "alert", children: error }) : null,
4340
+ /* @__PURE__ */ jsx25("div", { ref: mountRef, className: "b316-pay__element" }),
4341
+ /* @__PURE__ */ jsx25("button", { className: "b316-pay__submit", type: "submit", disabled: !ready || paying, children: paying ? "Paying\u2026" : "Pay" })
3991
4342
  ] });
3992
4343
  }
3993
4344
 
3994
4345
  // src/usePaymentLink.ts
3995
- import { useEffect as useEffect17, useRef as useRef6, useState as useState21 } from "react";
4346
+ import { useEffect as useEffect18, useRef as useRef6, useState as useState22 } from "react";
3996
4347
  function usePaymentLink({
3997
4348
  token,
3998
4349
  environmentId,
@@ -4000,10 +4351,10 @@ function usePaymentLink({
4000
4351
  onPaid
4001
4352
  }) {
4002
4353
  const { client } = useBase316();
4003
- const [status2, setStatus] = useState21({ state: "loading" });
4354
+ const [status2, setStatus] = useState22({ state: "loading" });
4004
4355
  const onPaidRef = useRef6(onPaid);
4005
4356
  onPaidRef.current = onPaid;
4006
- useEffect17(() => {
4357
+ useEffect18(() => {
4007
4358
  let stopped = false;
4008
4359
  let timer;
4009
4360
  const statusUrl = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}/status`;
@@ -4052,23 +4403,23 @@ function usePaymentLink({
4052
4403
  }
4053
4404
 
4054
4405
  // src/PricingTable.tsx
4055
- import { useState as useState23 } from "react";
4406
+ import { useState as useState24 } from "react";
4056
4407
 
4057
4408
  // src/usePlans.ts
4058
- import { useCallback as useCallback8, useEffect as useEffect18, useState as useState22 } from "react";
4409
+ import { useCallback as useCallback8, useEffect as useEffect19, useState as useState23 } from "react";
4059
4410
  var CHECKOUT_STATUSES = /* @__PURE__ */ new Set([402, 409]);
4060
4411
  function usePlans(options = {}) {
4061
4412
  const { client, token } = useBase316();
4062
- const [plans, setPlans] = useState22(null);
4063
- const [error, setError] = useState22(false);
4064
- const [busyPlanVersionId, setBusy] = useState22(null);
4065
- const [lastError, setLastError] = useState22(null);
4066
- const [ownPlanVersionId, setOwnPlanVersionId] = useState22(null);
4067
- const [managedBy, setManagedBy] = useState22(null);
4068
- const [reloadCount, setReloadCount] = useState22(0);
4413
+ const [plans, setPlans] = useState23(null);
4414
+ const [error, setError] = useState23(false);
4415
+ const [busyPlanVersionId, setBusy] = useState23(null);
4416
+ const [lastError, setLastError] = useState23(null);
4417
+ const [ownPlanVersionId, setOwnPlanVersionId] = useState23(null);
4418
+ const [managedBy, setManagedBy] = useState23(null);
4419
+ const [reloadCount, setReloadCount] = useState23(0);
4069
4420
  const supplied = options.currentPlanVersionId;
4070
4421
  const discover = supplied === void 0;
4071
- useEffect18(() => {
4422
+ useEffect19(() => {
4072
4423
  let cancelled = false;
4073
4424
  client.billing.plans().then((result) => {
4074
4425
  if (!cancelled) {
@@ -4084,7 +4435,7 @@ function usePlans(options = {}) {
4084
4435
  cancelled = true;
4085
4436
  };
4086
4437
  }, [client, reloadCount]);
4087
- useEffect18(() => {
4438
+ useEffect19(() => {
4088
4439
  if (!token) {
4089
4440
  return;
4090
4441
  }
@@ -4173,7 +4524,7 @@ function usePlans(options = {}) {
4173
4524
  }
4174
4525
 
4175
4526
  // src/PricingTable.tsx
4176
- import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
4527
+ import { jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
4177
4528
  function formatAmount(amount, currency) {
4178
4529
  if (amount === null) return "Free";
4179
4530
  const value = Number(amount);
@@ -4222,7 +4573,7 @@ function PricingTable({
4222
4573
  managedBy,
4223
4574
  selectPlan
4224
4575
  } = usePlans({ currentPlanVersionId });
4225
- const [scheduled, setScheduled] = useState23(null);
4576
+ const [scheduled, setScheduled] = useState24(null);
4226
4577
  async function choose(plan) {
4227
4578
  if (onSelectPlan) {
4228
4579
  await onSelectPlan(plan.planVersionId, plan);
@@ -4239,50 +4590,50 @@ function PricingTable({
4239
4590
  }
4240
4591
  }
4241
4592
  if (error) {
4242
- return /* @__PURE__ */ jsx24("div", { className: cls("b316-card", className), style, children: "Plans are unavailable right now." });
4593
+ return /* @__PURE__ */ jsx26("div", { className: cls("b316-card", className), style, children: "Plans are unavailable right now." });
4243
4594
  }
4244
4595
  if (!plans) {
4245
- return /* @__PURE__ */ jsx24("div", { className: cls("b316-card", className), style, children: "Loading plans\u2026" });
4596
+ return /* @__PURE__ */ jsx26("div", { className: cls("b316-card", className), style, children: "Loading plans\u2026" });
4246
4597
  }
4247
4598
  if (plans.length === 0) {
4248
- return /* @__PURE__ */ jsx24("div", { className: cls("b316-card", className), style, children: "No plans are published yet." });
4599
+ return /* @__PURE__ */ jsx26("div", { className: cls("b316-card", className), style, children: "No plans are published yet." });
4249
4600
  }
4250
4601
  const anyTrial = plans.some((plan) => Boolean(plan.trialDays));
4251
4602
  const anyDescription = plans.some((plan) => Boolean(plan.description));
4252
4603
  const anyFeatured = plans.some((plan) => plan.key === featuredPlanKey);
4253
- return /* @__PURE__ */ jsxs23("div", { className: cls("b316-plans", className), style, children: [
4604
+ return /* @__PURE__ */ jsxs25("div", { className: cls("b316-plans", className), style, children: [
4254
4605
  managedBy ? (
4255
4606
  // A client company's plan comes from the firm that runs it. The table
4256
4607
  // still shows what is on offer, with the current plan marked, but
4257
4608
  // nothing here can be bought: it would grant this account nothing.
4258
- /* @__PURE__ */ jsxs23("div", { className: "b316-plans-managed b316-muted", children: [
4609
+ /* @__PURE__ */ jsxs25("div", { className: "b316-plans-managed b316-muted", children: [
4259
4610
  "Your plan is provided by ",
4260
4611
  managedBy.name ?? "the organization that manages your account",
4261
4612
  ". Ask them to change it."
4262
4613
  ] })
4263
- ) : lastError ? /* @__PURE__ */ jsx24("div", { className: "b316-plans-error", role: "alert", children: lastError }) : scheduled ? /* @__PURE__ */ jsx24("div", { className: "b316-plans-managed b316-muted", role: "status", children: scheduled }) : null,
4614
+ ) : lastError ? /* @__PURE__ */ jsx26("div", { className: "b316-plans-error", role: "alert", children: lastError }) : scheduled ? /* @__PURE__ */ jsx26("div", { className: "b316-plans-managed b316-muted", role: "status", children: scheduled }) : null,
4264
4615
  plans.map((plan) => {
4265
4616
  const base = plan.prices.find((price) => price.featureId === null) ?? plan.prices[0];
4266
4617
  const isCurrent = current === plan.planVersionId;
4267
4618
  const featured = featuredPlanKey === plan.key;
4268
- return /* @__PURE__ */ jsxs23(
4619
+ return /* @__PURE__ */ jsxs25(
4269
4620
  "div",
4270
4621
  {
4271
4622
  className: featured ? "b316-card b316-plan b316-plan-featured" : "b316-card b316-plan",
4272
4623
  children: [
4273
- /* @__PURE__ */ jsxs23("div", { className: "b316-plan-head", children: [
4274
- anyFeatured ? /* @__PURE__ */ jsx24("div", { className: featured ? "b316-plan-badge" : "b316-plan-badge-spacer", children: featured ? "Recommended" : "\xA0" }) : null,
4275
- /* @__PURE__ */ jsx24("div", { className: "b316-plan-name", children: plan.name }),
4276
- anyDescription ? /* @__PURE__ */ jsx24("div", { className: "b316-plan-desc", children: plan.description ?? "\xA0" }) : null
4624
+ /* @__PURE__ */ jsxs25("div", { className: "b316-plan-head", children: [
4625
+ anyFeatured ? /* @__PURE__ */ jsx26("div", { className: featured ? "b316-plan-badge" : "b316-plan-badge-spacer", children: featured ? "Recommended" : "\xA0" }) : null,
4626
+ /* @__PURE__ */ jsx26("div", { className: "b316-plan-name", children: plan.name }),
4627
+ anyDescription ? /* @__PURE__ */ jsx26("div", { className: "b316-plan-desc", children: plan.description ?? "\xA0" }) : null
4277
4628
  ] }),
4278
- /* @__PURE__ */ jsxs23("div", { className: "b316-plan-pricing", children: [
4279
- /* @__PURE__ */ jsx24("div", { className: "b316-plan-price", children: formatAmount(base?.amount ?? null, plan.currency) }),
4280
- /* @__PURE__ */ jsx24("div", { className: "b316-plan-cadence", children: cadence(plan, base?.amount ?? null) }),
4281
- anyTrial ? /* @__PURE__ */ jsx24("div", { className: "b316-plan-trial", children: describeTrial(plan, plans) ?? "\xA0" }) : null
4629
+ /* @__PURE__ */ jsxs25("div", { className: "b316-plan-pricing", children: [
4630
+ /* @__PURE__ */ jsx26("div", { className: "b316-plan-price", children: formatAmount(base?.amount ?? null, plan.currency) }),
4631
+ /* @__PURE__ */ jsx26("div", { className: "b316-plan-cadence", children: cadence(plan, base?.amount ?? null) }),
4632
+ anyTrial ? /* @__PURE__ */ jsx26("div", { className: "b316-plan-trial", children: describeTrial(plan, plans) ?? "\xA0" }) : null
4282
4633
  ] }),
4283
- /* @__PURE__ */ jsx24("ul", { className: "b316-plan-features", children: plan.entitlements.filter((entitlement) => entitlement.enabled).map((entitlement) => /* @__PURE__ */ jsxs23("li", { className: "b316-plan-feature", children: [
4284
- /* @__PURE__ */ jsx24("span", { children: entitlement.featureName }),
4285
- /* @__PURE__ */ jsx24("span", { className: "b316-plan-feature-value", children: entitlement.limit === null ? "Unlimited" : (
4634
+ /* @__PURE__ */ jsx26("ul", { className: "b316-plan-features", children: plan.entitlements.filter((entitlement) => entitlement.enabled).map((entitlement) => /* @__PURE__ */ jsxs25("li", { className: "b316-plan-feature", children: [
4635
+ /* @__PURE__ */ jsx26("span", { children: entitlement.featureName }),
4636
+ /* @__PURE__ */ jsx26("span", { className: "b316-plan-feature-value", children: entitlement.limit === null ? "Unlimited" : (
4286
4637
  // A usage price on the feature makes the limit an
4287
4638
  // allowance billed past, not a ceiling — the same
4288
4639
  // rule `check()` applies (any non-FLAT price).
@@ -4291,7 +4642,7 @@ function PricingTable({
4291
4642
  ) ? `${entitlement.limit} included` : entitlement.limit
4292
4643
  ) })
4293
4644
  ] }, entitlement.featureId)) }),
4294
- /* @__PURE__ */ jsx24("div", { className: "b316-plan-action", children: /* @__PURE__ */ jsx24(
4645
+ /* @__PURE__ */ jsx26("div", { className: "b316-plan-action", children: /* @__PURE__ */ jsx26(
4295
4646
  "button",
4296
4647
  {
4297
4648
  type: "button",
@@ -4313,14 +4664,14 @@ function PricingTable({
4313
4664
 
4314
4665
  // src/DataTable.tsx
4315
4666
  import { specFor as specFor3 } from "@base316/sdk";
4316
- import { useState as useState27 } from "react";
4667
+ import { useState as useState28 } from "react";
4317
4668
 
4318
4669
  // src/fields.tsx
4319
4670
  import {
4320
4671
  formatAddress,
4321
4672
  specFor
4322
4673
  } from "@base316/sdk";
4323
- import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
4674
+ import { jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
4324
4675
  function formatNumber(value, fraction = 0) {
4325
4676
  const number = Number(value);
4326
4677
  return Number.isFinite(number) ? new Intl.NumberFormat(void 0, {
@@ -4342,10 +4693,10 @@ function formatDuration(value) {
4342
4693
  }
4343
4694
  function FieldCell({ value, field, related }) {
4344
4695
  if (field.type === "RELATION") {
4345
- return related?.title ?? (related?.id ? /* @__PURE__ */ jsx25("code", { className: "b316-muted", children: related.id }) : "\u2014");
4696
+ return related?.title ?? (related?.id ? /* @__PURE__ */ jsx27("code", { className: "b316-muted", children: related.id }) : "\u2014");
4346
4697
  }
4347
4698
  if (value === null || value === void 0 || value === "") {
4348
- return /* @__PURE__ */ jsx25("span", { className: "b316-muted", children: "\u2014" });
4699
+ return /* @__PURE__ */ jsx27("span", { className: "b316-muted", children: "\u2014" });
4349
4700
  }
4350
4701
  switch (field.type) {
4351
4702
  case "BOOLEAN":
@@ -4358,9 +4709,9 @@ function FieldCell({ value, field, related }) {
4358
4709
  return formatDuration(value);
4359
4710
  case "RATING": {
4360
4711
  const stars = Math.round(Number(value));
4361
- return /* @__PURE__ */ jsxs24("span", { "aria-label": `${stars} out of 5`, children: [
4712
+ return /* @__PURE__ */ jsxs26("span", { "aria-label": `${stars} out of 5`, children: [
4362
4713
  "\u2605".repeat(stars),
4363
- /* @__PURE__ */ jsx25("span", { className: "b316-muted", children: "\u2605".repeat(Math.max(0, 5 - stars)) })
4714
+ /* @__PURE__ */ jsx27("span", { className: "b316-muted", children: "\u2605".repeat(Math.max(0, 5 - stars)) })
4364
4715
  ] });
4365
4716
  }
4366
4717
  case "DATE":
@@ -4368,15 +4719,15 @@ function FieldCell({ value, field, related }) {
4368
4719
  case "DATETIME":
4369
4720
  return new Date(String(value)).toLocaleString();
4370
4721
  case "SELECT":
4371
- return /* @__PURE__ */ jsx25("span", { className: "b316-chip", children: String(value) });
4722
+ return /* @__PURE__ */ jsx27("span", { className: "b316-chip", children: String(value) });
4372
4723
  case "MULTISELECT":
4373
- return /* @__PURE__ */ jsx25("span", { className: "b316-chips", children: (Array.isArray(value) ? value : [value]).map((item) => /* @__PURE__ */ jsx25("span", { className: "b316-chip", children: String(item) }, String(item))) });
4724
+ return /* @__PURE__ */ jsx27("span", { className: "b316-chips", children: (Array.isArray(value) ? value : [value]).map((item) => /* @__PURE__ */ jsx27("span", { className: "b316-chip", children: String(item) }, String(item))) });
4374
4725
  case "URL":
4375
- return /* @__PURE__ */ jsx25("a", { href: String(value), target: "_blank", rel: "noreferrer noopener", children: String(value) });
4726
+ return /* @__PURE__ */ jsx27("a", { href: String(value), target: "_blank", rel: "noreferrer noopener", children: String(value) });
4376
4727
  case "EMAIL":
4377
- return /* @__PURE__ */ jsx25("a", { href: `mailto:${String(value)}`, children: String(value) });
4728
+ return /* @__PURE__ */ jsx27("a", { href: `mailto:${String(value)}`, children: String(value) });
4378
4729
  case "PHONE":
4379
- return /* @__PURE__ */ jsx25("a", { href: `tel:${String(value)}`, children: String(value) });
4730
+ return /* @__PURE__ */ jsx27("a", { href: `tel:${String(value)}`, children: String(value) });
4380
4731
  case "ADDRESS":
4381
4732
  return formatAddress(value);
4382
4733
  case "ATTACHMENT": {
@@ -4388,7 +4739,7 @@ function FieldCell({ value, field, related }) {
4388
4739
  return text.length > 80 ? `${text.slice(0, 80)}\u2026` : text;
4389
4740
  }
4390
4741
  case "JSON":
4391
- return /* @__PURE__ */ jsx25("code", { className: "b316-muted", children: JSON.stringify(value).slice(0, 60) });
4742
+ return /* @__PURE__ */ jsx27("code", { className: "b316-muted", children: JSON.stringify(value).slice(0, 60) });
4392
4743
  default:
4393
4744
  return String(value);
4394
4745
  }
@@ -4409,7 +4760,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4409
4760
  function control() {
4410
4761
  switch (field.type) {
4411
4762
  case "LONGTEXT":
4412
- return /* @__PURE__ */ jsx25(
4763
+ return /* @__PURE__ */ jsx27(
4413
4764
  "textarea",
4414
4765
  {
4415
4766
  ...common,
@@ -4419,7 +4770,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4419
4770
  }
4420
4771
  );
4421
4772
  case "BOOLEAN":
4422
- return /* @__PURE__ */ jsx25(
4773
+ return /* @__PURE__ */ jsx27(
4423
4774
  "input",
4424
4775
  {
4425
4776
  ...common,
@@ -4430,22 +4781,22 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4430
4781
  }
4431
4782
  );
4432
4783
  case "SELECT":
4433
- return /* @__PURE__ */ jsxs24(
4784
+ return /* @__PURE__ */ jsxs26(
4434
4785
  "select",
4435
4786
  {
4436
4787
  ...common,
4437
4788
  value: value === null || value === void 0 ? "" : String(value),
4438
4789
  onChange: (event) => onChange(event.target.value === "" ? null : event.target.value),
4439
4790
  children: [
4440
- field.required ? null : /* @__PURE__ */ jsx25("option", { value: "", children: "\u2014" }),
4441
- (field.options ?? []).map((option) => /* @__PURE__ */ jsx25("option", { value: option, children: option }, option))
4791
+ field.required ? null : /* @__PURE__ */ jsx27("option", { value: "", children: "\u2014" }),
4792
+ (field.options ?? []).map((option) => /* @__PURE__ */ jsx27("option", { value: option, children: option }, option))
4442
4793
  ]
4443
4794
  }
4444
4795
  );
4445
4796
  case "MULTISELECT": {
4446
4797
  const selected = new Set(Array.isArray(value) ? value.map(String) : []);
4447
- return /* @__PURE__ */ jsx25("div", { className: "b316-choices", children: (field.options ?? []).map((option) => /* @__PURE__ */ jsxs24("label", { className: "b316-choice", children: [
4448
- /* @__PURE__ */ jsx25(
4798
+ return /* @__PURE__ */ jsx27("div", { className: "b316-choices", children: (field.options ?? []).map((option) => /* @__PURE__ */ jsxs26("label", { className: "b316-choice", children: [
4799
+ /* @__PURE__ */ jsx27(
4449
4800
  "input",
4450
4801
  {
4451
4802
  type: "checkbox",
@@ -4468,7 +4819,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4468
4819
  case "NUMBER":
4469
4820
  case "MONEY":
4470
4821
  case "PERCENT":
4471
- return /* @__PURE__ */ jsx25(
4822
+ return /* @__PURE__ */ jsx27(
4472
4823
  "input",
4473
4824
  {
4474
4825
  ...common,
@@ -4479,7 +4830,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4479
4830
  }
4480
4831
  );
4481
4832
  case "RATING":
4482
- return /* @__PURE__ */ jsx25(
4833
+ return /* @__PURE__ */ jsx27(
4483
4834
  "input",
4484
4835
  {
4485
4836
  ...common,
@@ -4493,8 +4844,8 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4493
4844
  );
4494
4845
  case "DURATION": {
4495
4846
  const minutes = value === null || value === void 0 ? "" : String(Number(value) / 60);
4496
- return /* @__PURE__ */ jsxs24("div", { className: "b316-suffixed", children: [
4497
- /* @__PURE__ */ jsx25(
4847
+ return /* @__PURE__ */ jsxs26("div", { className: "b316-suffixed", children: [
4848
+ /* @__PURE__ */ jsx27(
4498
4849
  "input",
4499
4850
  {
4500
4851
  ...common,
@@ -4504,11 +4855,11 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4504
4855
  onChange: (event) => onChange(event.target.value === "" ? null : Number(event.target.value) * 60)
4505
4856
  }
4506
4857
  ),
4507
- /* @__PURE__ */ jsx25("span", { className: "b316-muted", children: "minutes" })
4858
+ /* @__PURE__ */ jsx27("span", { className: "b316-muted", children: "minutes" })
4508
4859
  ] });
4509
4860
  }
4510
4861
  case "DATE":
4511
- return /* @__PURE__ */ jsx25(
4862
+ return /* @__PURE__ */ jsx27(
4512
4863
  "input",
4513
4864
  {
4514
4865
  ...common,
@@ -4518,7 +4869,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4518
4869
  }
4519
4870
  );
4520
4871
  case "DATETIME":
4521
- return /* @__PURE__ */ jsx25(
4872
+ return /* @__PURE__ */ jsx27(
4522
4873
  "input",
4523
4874
  {
4524
4875
  ...common,
@@ -4531,7 +4882,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4531
4882
  );
4532
4883
  case "ADDRESS": {
4533
4884
  const address = value ?? {};
4534
- const part = (key, label) => /* @__PURE__ */ jsx25(
4885
+ const part = (key, label) => /* @__PURE__ */ jsx27(
4535
4886
  "input",
4536
4887
  {
4537
4888
  className: "b316-input",
@@ -4543,7 +4894,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4543
4894
  },
4544
4895
  key
4545
4896
  );
4546
- return /* @__PURE__ */ jsxs24("div", { className: "b316-address", children: [
4897
+ return /* @__PURE__ */ jsxs26("div", { className: "b316-address", children: [
4547
4898
  part("line1", "Address line 1"),
4548
4899
  part("line2", "Address line 2"),
4549
4900
  part("city", "City"),
@@ -4553,7 +4904,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4553
4904
  ] });
4554
4905
  }
4555
4906
  case "EMAIL":
4556
- return /* @__PURE__ */ jsx25(
4907
+ return /* @__PURE__ */ jsx27(
4557
4908
  "input",
4558
4909
  {
4559
4910
  ...common,
@@ -4563,7 +4914,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4563
4914
  }
4564
4915
  );
4565
4916
  case "URL":
4566
- return /* @__PURE__ */ jsx25(
4917
+ return /* @__PURE__ */ jsx27(
4567
4918
  "input",
4568
4919
  {
4569
4920
  ...common,
@@ -4573,7 +4924,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4573
4924
  }
4574
4925
  );
4575
4926
  case "PHONE":
4576
- return /* @__PURE__ */ jsx25(
4927
+ return /* @__PURE__ */ jsx27(
4577
4928
  "input",
4578
4929
  {
4579
4930
  ...common,
@@ -4583,7 +4934,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4583
4934
  }
4584
4935
  );
4585
4936
  default:
4586
- return /* @__PURE__ */ jsx25(
4937
+ return /* @__PURE__ */ jsx27(
4587
4938
  "input",
4588
4939
  {
4589
4940
  ...common,
@@ -4594,24 +4945,24 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4594
4945
  );
4595
4946
  }
4596
4947
  }
4597
- return /* @__PURE__ */ jsxs24("div", { className: "b316-field", children: [
4598
- /* @__PURE__ */ jsxs24("label", { className: "b316-label", htmlFor: id, children: [
4948
+ return /* @__PURE__ */ jsxs26("div", { className: "b316-field", children: [
4949
+ /* @__PURE__ */ jsxs26("label", { className: "b316-label", htmlFor: id, children: [
4599
4950
  field.label,
4600
- field.required ? /* @__PURE__ */ jsx25("span", { "aria-hidden": "true", children: " *" }) : null
4951
+ field.required ? /* @__PURE__ */ jsx27("span", { "aria-hidden": "true", children: " *" }) : null
4601
4952
  ] }),
4602
4953
  control(),
4603
- field.description ? /* @__PURE__ */ jsx25("div", { className: "b316-hint", children: field.description }) : null,
4604
- error ? /* @__PURE__ */ jsx25("div", { className: "b316-error", id: described, role: "alert", children: error }) : null
4954
+ field.description ? /* @__PURE__ */ jsx27("div", { className: "b316-hint", children: field.description }) : null,
4955
+ error ? /* @__PURE__ */ jsx27("div", { className: "b316-error", id: described, role: "alert", children: error }) : null
4605
4956
  ] });
4606
4957
  }
4607
4958
 
4608
4959
  // src/RecordForm.tsx
4609
4960
  import { specFor as specFor2 } from "@base316/sdk";
4610
- import { useEffect as useEffect21, useState as useState26 } from "react";
4961
+ import { useEffect as useEffect22, useState as useState27 } from "react";
4611
4962
 
4612
4963
  // src/RelationPicker.tsx
4613
- import { useEffect as useEffect19, useRef as useRef7, useState as useState24 } from "react";
4614
- import { Fragment as Fragment8, jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
4964
+ import { useEffect as useEffect20, useRef as useRef7, useState as useState25 } from "react";
4965
+ import { Fragment as Fragment10, jsx as jsx28, jsxs as jsxs27 } from "react/jsx-runtime";
4615
4966
  function RelationPicker({
4616
4967
  field,
4617
4968
  value,
@@ -4621,13 +4972,13 @@ function RelationPicker({
4621
4972
  tenant
4622
4973
  }) {
4623
4974
  const { client, token } = useBase316();
4624
- const [query, setQuery] = useState24("");
4625
- const [results, setResults] = useState24([]);
4626
- const [chosenTitle, setChosenTitle] = useState24(null);
4627
- const [open, setOpen] = useState24(false);
4975
+ const [query, setQuery] = useState25("");
4976
+ const [results, setResults] = useState25([]);
4977
+ const [chosenTitle, setChosenTitle] = useState25(null);
4978
+ const [open, setOpen] = useState25(false);
4628
4979
  const id = `b316-field-${field.key}`;
4629
4980
  const box = useRef7(null);
4630
- useEffect19(() => {
4981
+ useEffect20(() => {
4631
4982
  if (!token || !value || !field.relationTo) {
4632
4983
  setChosenTitle(null);
4633
4984
  return;
@@ -4642,7 +4993,7 @@ function RelationPicker({
4642
4993
  cancelled = true;
4643
4994
  };
4644
4995
  }, [client, token, value, field.relationTo, tenant]);
4645
- useEffect19(() => {
4996
+ useEffect20(() => {
4646
4997
  if (!token || !field.relationTo || !open) {
4647
4998
  return;
4648
4999
  }
@@ -4668,7 +5019,7 @@ function RelationPicker({
4668
5019
  clearTimeout(timer);
4669
5020
  };
4670
5021
  }, [client, token, field.relationTo, query, open, tenant]);
4671
- useEffect19(() => {
5022
+ useEffect20(() => {
4672
5023
  if (!open || typeof document === "undefined") {
4673
5024
  return;
4674
5025
  }
@@ -4682,14 +5033,14 @@ function RelationPicker({
4682
5033
  document.removeEventListener("mousedown", onDocumentClick);
4683
5034
  };
4684
5035
  }, [open]);
4685
- return /* @__PURE__ */ jsxs25("div", { className: "b316-field", ref: box, children: [
4686
- /* @__PURE__ */ jsxs25("label", { className: "b316-label", htmlFor: id, children: [
5036
+ return /* @__PURE__ */ jsxs27("div", { className: "b316-field", ref: box, children: [
5037
+ /* @__PURE__ */ jsxs27("label", { className: "b316-label", htmlFor: id, children: [
4687
5038
  field.label,
4688
- field.required ? /* @__PURE__ */ jsx26("span", { "aria-hidden": "true", children: " *" }) : null
5039
+ field.required ? /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: " *" }) : null
4689
5040
  ] }),
4690
- value && !open ? /* @__PURE__ */ jsxs25("div", { className: "b316-relation-chosen", children: [
4691
- /* @__PURE__ */ jsx26("span", { children: chosenTitle ?? value }),
4692
- disabled ? null : /* @__PURE__ */ jsx26(
5041
+ value && !open ? /* @__PURE__ */ jsxs27("div", { className: "b316-relation-chosen", children: [
5042
+ /* @__PURE__ */ jsx28("span", { children: chosenTitle ?? value }),
5043
+ disabled ? null : /* @__PURE__ */ jsx28(
4693
5044
  "button",
4694
5045
  {
4695
5046
  type: "button",
@@ -4701,7 +5052,7 @@ function RelationPicker({
4701
5052
  children: "Change"
4702
5053
  }
4703
5054
  ),
4704
- disabled || field.required ? null : /* @__PURE__ */ jsx26(
5055
+ disabled || field.required ? null : /* @__PURE__ */ jsx28(
4705
5056
  "button",
4706
5057
  {
4707
5058
  type: "button",
@@ -4711,8 +5062,8 @@ function RelationPicker({
4711
5062
  children: "Clear"
4712
5063
  }
4713
5064
  )
4714
- ] }) : /* @__PURE__ */ jsxs25(Fragment8, { children: [
4715
- /* @__PURE__ */ jsx26(
5065
+ ] }) : /* @__PURE__ */ jsxs27(Fragment10, { children: [
5066
+ /* @__PURE__ */ jsx28(
4716
5067
  "input",
4717
5068
  {
4718
5069
  id,
@@ -4733,7 +5084,7 @@ function RelationPicker({
4733
5084
  }
4734
5085
  }
4735
5086
  ),
4736
- open ? /* @__PURE__ */ jsx26("ul", { className: "b316-relation-results", id: `${id}-results`, role: "listbox", children: results.length === 0 ? /* @__PURE__ */ jsx26("li", { className: "b316-muted b316-relation-empty", children: "No matches" }) : results.map((result) => /* @__PURE__ */ jsx26("li", { children: /* @__PURE__ */ jsx26(
5087
+ open ? /* @__PURE__ */ jsx28("ul", { className: "b316-relation-results", id: `${id}-results`, role: "listbox", children: results.length === 0 ? /* @__PURE__ */ jsx28("li", { className: "b316-muted b316-relation-empty", children: "No matches" }) : results.map((result) => /* @__PURE__ */ jsx28("li", { children: /* @__PURE__ */ jsx28(
4737
5088
  "button",
4738
5089
  {
4739
5090
  type: "button",
@@ -4749,13 +5100,13 @@ function RelationPicker({
4749
5100
  }
4750
5101
  ) }, result.id)) }) : null
4751
5102
  ] }),
4752
- field.description ? /* @__PURE__ */ jsx26("div", { className: "b316-hint", children: field.description }) : null,
4753
- error ? /* @__PURE__ */ jsx26("div", { className: "b316-error", role: "alert", children: error }) : null
5103
+ field.description ? /* @__PURE__ */ jsx28("div", { className: "b316-hint", children: field.description }) : null,
5104
+ error ? /* @__PURE__ */ jsx28("div", { className: "b316-error", role: "alert", children: error }) : null
4754
5105
  ] });
4755
5106
  }
4756
5107
 
4757
5108
  // src/useCollection.ts
4758
- import { useCallback as useCallback9, useEffect as useEffect20, useMemo as useMemo3, useState as useState25 } from "react";
5109
+ import { useCallback as useCallback9, useEffect as useEffect21, useMemo as useMemo3, useState as useState26 } from "react";
4759
5110
  function fieldErrorFrom(cause) {
4760
5111
  const param = cause?.param;
4761
5112
  const message = cause instanceof Error ? cause.message : "That value was not accepted.";
@@ -4763,24 +5114,24 @@ function fieldErrorFrom(cause) {
4763
5114
  }
4764
5115
  function useCollection(collection, options = {}) {
4765
5116
  const { client, token } = useBase316();
4766
- const [schema, setSchema] = useState25(null);
4767
- const [records, setRecords] = useState25([]);
4768
- const [error, setError] = useState25(null);
4769
- const [loading, setLoading] = useState25(true);
4770
- const [total, setTotal] = useState25(0);
4771
- const [cursor, setCursor] = useState25(null);
4772
- const [reloadCount, setReloadCount] = useState25(0);
4773
- const [search, setSearch] = useState25("");
4774
- const [filters, setFilters] = useState25([]);
4775
- const [sort, setSort] = useState25(
5117
+ const [schema, setSchema] = useState26(null);
5118
+ const [records, setRecords] = useState26([]);
5119
+ const [error, setError] = useState26(null);
5120
+ const [loading, setLoading] = useState26(true);
5121
+ const [total, setTotal] = useState26(0);
5122
+ const [cursor, setCursor] = useState26(null);
5123
+ const [reloadCount, setReloadCount] = useState26(0);
5124
+ const [search, setSearch] = useState26("");
5125
+ const [filters, setFilters] = useState26([]);
5126
+ const [sort, setSort] = useState26(
4776
5127
  options.sort ?? null
4777
5128
  );
4778
- const [fieldErrors, setFieldErrors] = useState25({});
4779
- const [saving, setSaving] = useState25(false);
5129
+ const [fieldErrors, setFieldErrors] = useState26({});
5130
+ const [saving, setSaving] = useState26(false);
4780
5131
  const { tenant, limit, recordId } = options;
4781
5132
  const fixedFilters = JSON.stringify(options.filters ?? []);
4782
5133
  const scope = useMemo3(() => tenant ? { tenant } : void 0, [tenant]);
4783
- useEffect20(() => {
5134
+ useEffect21(() => {
4784
5135
  if (!token) {
4785
5136
  return;
4786
5137
  }
@@ -4799,7 +5150,7 @@ function useCollection(collection, options = {}) {
4799
5150
  cancelled = true;
4800
5151
  };
4801
5152
  }, [client, token, collection, scope]);
4802
- useEffect20(() => {
5153
+ useEffect21(() => {
4803
5154
  if (!token || !schema) {
4804
5155
  return;
4805
5156
  }
@@ -4991,7 +5342,7 @@ function useCollection(collection, options = {}) {
4991
5342
  }
4992
5343
 
4993
5344
  // src/RecordForm.tsx
4994
- import { jsx as jsx27, jsxs as jsxs26 } from "react/jsx-runtime";
5345
+ import { jsx as jsx29, jsxs as jsxs28 } from "react/jsx-runtime";
4995
5346
  function RecordForm({
4996
5347
  collection,
4997
5348
  recordId,
@@ -5012,20 +5363,20 @@ function RecordForm({
5012
5363
  recordId
5013
5364
  }
5014
5365
  );
5015
- const [values, setValues] = useState26(defaults ?? {});
5016
- const [loaded, setLoaded] = useState26(!recordId);
5366
+ const [values, setValues] = useState27(defaults ?? {});
5367
+ const [loaded, setLoaded] = useState27(!recordId);
5017
5368
  const existing = recordId ? records.find((record) => record.id === recordId) : void 0;
5018
- useEffect21(() => {
5369
+ useEffect22(() => {
5019
5370
  if (existing && !loaded) {
5020
5371
  setValues(existing.fields);
5021
5372
  setLoaded(true);
5022
5373
  }
5023
5374
  }, [existing, loaded]);
5024
5375
  if (error) {
5025
- return /* @__PURE__ */ jsx27("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx27("div", { className: "b316-error", role: "alert", children: error }) });
5376
+ return /* @__PURE__ */ jsx29("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx29("div", { className: "b316-error", role: "alert", children: error }) });
5026
5377
  }
5027
5378
  if (!schema || !loaded) {
5028
- return /* @__PURE__ */ jsx27("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5379
+ return /* @__PURE__ */ jsx29("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5029
5380
  }
5030
5381
  const editable = schema.fields.filter((field) => !specFor2(field).computed);
5031
5382
  async function submit(event) {
@@ -5035,11 +5386,11 @@ function RecordForm({
5035
5386
  onSaved?.(saved.id);
5036
5387
  }
5037
5388
  }
5038
- return /* @__PURE__ */ jsxs26("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
5039
- /* @__PURE__ */ jsx27("h3", { className: "b316-form-title", children: recordId ? `Edit ${schema.name.toLowerCase()}` : `New ${schema.name.toLowerCase()}` }),
5040
- fieldErrors._ ? /* @__PURE__ */ jsx27("div", { className: "b316-error", role: "alert", children: fieldErrors._ }) : null,
5389
+ return /* @__PURE__ */ jsxs28("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
5390
+ /* @__PURE__ */ jsx29("h3", { className: "b316-form-title", children: recordId ? `Edit ${schema.name.toLowerCase()}` : `New ${schema.name.toLowerCase()}` }),
5391
+ fieldErrors._ ? /* @__PURE__ */ jsx29("div", { className: "b316-error", role: "alert", children: fieldErrors._ }) : null,
5041
5392
  editable.map(
5042
- (field) => field.type === "RELATION" ? /* @__PURE__ */ jsx27(
5393
+ (field) => field.type === "RELATION" ? /* @__PURE__ */ jsx29(
5043
5394
  RelationPicker,
5044
5395
  {
5045
5396
  field,
@@ -5050,7 +5401,7 @@ function RecordForm({
5050
5401
  onChange: (next) => setValues((current) => ({ ...current, [field.key]: next }))
5051
5402
  },
5052
5403
  field.key
5053
- ) : /* @__PURE__ */ jsx27(
5404
+ ) : /* @__PURE__ */ jsx29(
5054
5405
  FieldInput,
5055
5406
  {
5056
5407
  field,
@@ -5062,15 +5413,15 @@ function RecordForm({
5062
5413
  field.key
5063
5414
  )
5064
5415
  ),
5065
- /* @__PURE__ */ jsxs26("div", { className: "b316-form-actions", children: [
5066
- onCancel ? /* @__PURE__ */ jsx27("button", { type: "button", className: "b316-button-quiet", onClick: onCancel, disabled: saving, children: "Cancel" }) : null,
5067
- /* @__PURE__ */ jsx27("button", { type: "submit", className: "b316-button", disabled: saving, children: saving ? "Saving\u2026" : "Save" })
5416
+ /* @__PURE__ */ jsxs28("div", { className: "b316-form-actions", children: [
5417
+ onCancel ? /* @__PURE__ */ jsx29("button", { type: "button", className: "b316-button-quiet", onClick: onCancel, disabled: saving, children: "Cancel" }) : null,
5418
+ /* @__PURE__ */ jsx29("button", { type: "submit", className: "b316-button", disabled: saving, children: saving ? "Saving\u2026" : "Save" })
5068
5419
  ] })
5069
5420
  ] });
5070
5421
  }
5071
5422
 
5072
5423
  // src/DataTable.tsx
5073
- import { jsx as jsx28, jsxs as jsxs27 } from "react/jsx-runtime";
5424
+ import { jsx as jsx30, jsxs as jsxs29 } from "react/jsx-runtime";
5074
5425
  function DataTable({
5075
5426
  collection,
5076
5427
  columns,
@@ -5099,13 +5450,13 @@ function DataTable({
5099
5450
  loadMore,
5100
5451
  remove
5101
5452
  } = useCollection(collection, options);
5102
- const [editing, setEditing] = useState27(null);
5103
- const [removeFailed, setRemoveFailed] = useState27(null);
5453
+ const [editing, setEditing] = useState28(null);
5454
+ const [removeFailed, setRemoveFailed] = useState28(null);
5104
5455
  if (error) {
5105
- return /* @__PURE__ */ jsx28("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx28("div", { className: "b316-error", role: "alert", children: error }) });
5456
+ return /* @__PURE__ */ jsx30("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx30("div", { className: "b316-error", role: "alert", children: error }) });
5106
5457
  }
5107
5458
  if (!schema) {
5108
- return /* @__PURE__ */ jsx28("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5459
+ return /* @__PURE__ */ jsx30("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5109
5460
  }
5110
5461
  const shown = columns ? (
5111
5462
  // Ordered by what was asked for, not by the schema: a caller naming
@@ -5114,10 +5465,10 @@ function DataTable({
5114
5465
  ) : schema.fields;
5115
5466
  const searchable = schema.fields.some((field) => specFor3(field).capabilities.searchable);
5116
5467
  const writable = canWrite && !readOnly;
5117
- return /* @__PURE__ */ jsxs27("div", { className: cls("b316-table-wrap", className), style, children: [
5118
- removeFailed ? /* @__PURE__ */ jsx28("div", { className: "b316-error", role: "alert", children: removeFailed }) : null,
5119
- /* @__PURE__ */ jsxs27("div", { className: "b316-table-bar", children: [
5120
- searchable && !hideSearch ? /* @__PURE__ */ jsx28(
5468
+ return /* @__PURE__ */ jsxs29("div", { className: cls("b316-table-wrap", className), style, children: [
5469
+ removeFailed ? /* @__PURE__ */ jsx30("div", { className: "b316-error", role: "alert", children: removeFailed }) : null,
5470
+ /* @__PURE__ */ jsxs29("div", { className: "b316-table-bar", children: [
5471
+ searchable && !hideSearch ? /* @__PURE__ */ jsx30(
5121
5472
  "input",
5122
5473
  {
5123
5474
  type: "search",
@@ -5127,25 +5478,25 @@ function DataTable({
5127
5478
  value: search,
5128
5479
  onChange: (event) => setSearch(event.target.value)
5129
5480
  }
5130
- ) : /* @__PURE__ */ jsx28("span", {}),
5131
- /* @__PURE__ */ jsxs27("div", { className: "b316-table-actions", children: [
5132
- /* @__PURE__ */ jsxs27("span", { className: "b316-muted", children: [
5481
+ ) : /* @__PURE__ */ jsx30("span", {}),
5482
+ /* @__PURE__ */ jsxs29("div", { className: "b316-table-actions", children: [
5483
+ /* @__PURE__ */ jsxs29("span", { className: "b316-muted", children: [
5133
5484
  total,
5134
5485
  " ",
5135
5486
  total === 1 ? schema.name.toLowerCase() : schema.namePlural.toLowerCase()
5136
5487
  ] }),
5137
- writable ? /* @__PURE__ */ jsxs27("button", { type: "button", className: "b316-button", onClick: () => setEditing("new"), children: [
5488
+ writable ? /* @__PURE__ */ jsxs29("button", { type: "button", className: "b316-button", onClick: () => setEditing("new"), children: [
5138
5489
  "New ",
5139
5490
  schema.name.toLowerCase()
5140
5491
  ] }) : null
5141
5492
  ] })
5142
5493
  ] }),
5143
- /* @__PURE__ */ jsx28("div", { className: "b316-table-scroll", children: /* @__PURE__ */ jsxs27("table", { className: "b316-table", children: [
5144
- /* @__PURE__ */ jsx28("thead", { children: /* @__PURE__ */ jsxs27("tr", { children: [
5494
+ /* @__PURE__ */ jsx30("div", { className: "b316-table-scroll", children: /* @__PURE__ */ jsxs29("table", { className: "b316-table", children: [
5495
+ /* @__PURE__ */ jsx30("thead", { children: /* @__PURE__ */ jsxs29("tr", { children: [
5145
5496
  shown.map((field) => {
5146
5497
  const sortable = specFor3(field).capabilities.sortable;
5147
5498
  const active = sort?.field === field.key;
5148
- return /* @__PURE__ */ jsx28("th", { scope: "col", "aria-sort": ariaSort(active, sort?.direction), children: sortable ? /* @__PURE__ */ jsxs27(
5499
+ return /* @__PURE__ */ jsx30("th", { scope: "col", "aria-sort": ariaSort(active, sort?.direction), children: sortable ? /* @__PURE__ */ jsxs29(
5149
5500
  "button",
5150
5501
  {
5151
5502
  type: "button",
@@ -5153,20 +5504,20 @@ function DataTable({
5153
5504
  onClick: () => toggleSort(field.key),
5154
5505
  children: [
5155
5506
  field.label,
5156
- /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: active ? sort?.direction === "desc" ? " \u2193" : " \u2191" : " \u2195" })
5507
+ /* @__PURE__ */ jsx30("span", { "aria-hidden": "true", children: active ? sort?.direction === "desc" ? " \u2193" : " \u2191" : " \u2195" })
5157
5508
  ]
5158
5509
  }
5159
5510
  ) : field.label }, field.key);
5160
5511
  }),
5161
- writable ? /* @__PURE__ */ jsx28("th", { scope: "col", className: "b316-table-rowactions" }) : null
5512
+ writable ? /* @__PURE__ */ jsx30("th", { scope: "col", className: "b316-table-rowactions" }) : null
5162
5513
  ] }) }),
5163
- /* @__PURE__ */ jsx28("tbody", { children: records.map((record) => /* @__PURE__ */ jsxs27(
5514
+ /* @__PURE__ */ jsx30("tbody", { children: records.map((record) => /* @__PURE__ */ jsxs29(
5164
5515
  "tr",
5165
5516
  {
5166
5517
  className: onSelect ? "b316-row-clickable" : void 0,
5167
5518
  onClick: onSelect ? () => onSelect(record) : void 0,
5168
5519
  children: [
5169
- shown.map((field) => /* @__PURE__ */ jsx28("td", { children: renderCell?.(record, field) ?? /* @__PURE__ */ jsx28(
5520
+ shown.map((field) => /* @__PURE__ */ jsx30("td", { children: renderCell?.(record, field) ?? /* @__PURE__ */ jsx30(
5170
5521
  FieldCell,
5171
5522
  {
5172
5523
  value: record.fields[field.key] ?? null,
@@ -5174,8 +5525,8 @@ function DataTable({
5174
5525
  related: record.related[field.key]
5175
5526
  }
5176
5527
  ) }, field.key)),
5177
- writable ? /* @__PURE__ */ jsxs27("td", { className: "b316-table-rowactions", children: [
5178
- /* @__PURE__ */ jsx28(
5528
+ writable ? /* @__PURE__ */ jsxs29("td", { className: "b316-table-rowactions", children: [
5529
+ /* @__PURE__ */ jsx30(
5179
5530
  "button",
5180
5531
  {
5181
5532
  type: "button",
@@ -5187,7 +5538,7 @@ function DataTable({
5187
5538
  children: "Edit"
5188
5539
  }
5189
5540
  ),
5190
- /* @__PURE__ */ jsx28(
5541
+ /* @__PURE__ */ jsx30(
5191
5542
  ConfirmButton,
5192
5543
  {
5193
5544
  className: "b316-button-quiet b316-danger",
@@ -5211,10 +5562,10 @@ function DataTable({
5211
5562
  record.id
5212
5563
  )) })
5213
5564
  ] }) }),
5214
- records.length === 0 && !loading ? /* @__PURE__ */ jsx28("div", { className: "b316-empty", children: emptyState ?? `No ${schema.namePlural.toLowerCase()} yet.` }) : null,
5215
- loading ? /* @__PURE__ */ jsx28("div", { className: "b316-empty", children: "Loading\u2026" }) : null,
5216
- hasMore ? /* @__PURE__ */ jsx28("div", { className: "b316-table-more", children: /* @__PURE__ */ jsx28("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: "Load more" }) }) : null,
5217
- editing ? /* @__PURE__ */ jsx28(
5565
+ records.length === 0 && !loading ? /* @__PURE__ */ jsx30("div", { className: "b316-empty", children: emptyState ?? `No ${schema.namePlural.toLowerCase()} yet.` }) : null,
5566
+ loading ? /* @__PURE__ */ jsx30("div", { className: "b316-empty", children: "Loading\u2026" }) : null,
5567
+ hasMore ? /* @__PURE__ */ jsx30("div", { className: "b316-table-more", children: /* @__PURE__ */ jsx30("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: "Load more" }) }) : null,
5568
+ editing ? /* @__PURE__ */ jsx30(
5218
5569
  RecordForm,
5219
5570
  {
5220
5571
  collection,
@@ -5242,8 +5593,8 @@ import {
5242
5593
  specFor as specFor4,
5243
5594
  titleFieldOf
5244
5595
  } from "@base316/sdk";
5245
- import { useState as useState28 } from "react";
5246
- import { jsx as jsx29, jsxs as jsxs28 } from "react/jsx-runtime";
5596
+ import { useState as useState29 } from "react";
5597
+ import { jsx as jsx31, jsxs as jsxs30 } from "react/jsx-runtime";
5247
5598
  function Kanban({
5248
5599
  collection,
5249
5600
  groupBy,
@@ -5260,17 +5611,17 @@ function Kanban({
5260
5611
  limit: options.limit ?? 100,
5261
5612
  ...options
5262
5613
  });
5263
- const [dragging, setDragging] = useState28(null);
5264
- const [over, setOver] = useState28(null);
5614
+ const [dragging, setDragging] = useState29(null);
5615
+ const [over, setOver] = useState29(null);
5265
5616
  if (error) {
5266
- return /* @__PURE__ */ jsx29("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx29("div", { className: "b316-error", role: "alert", children: error }) });
5617
+ return /* @__PURE__ */ jsx31("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx31("div", { className: "b316-error", role: "alert", children: error }) });
5267
5618
  }
5268
5619
  if (!schema) {
5269
- return /* @__PURE__ */ jsx29("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5620
+ return /* @__PURE__ */ jsx31("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5270
5621
  }
5271
5622
  const field = groupBy ? schema.fields.find((candidate) => candidate.key === groupBy) ?? null : defaultGroupFieldOf(schema.fields);
5272
5623
  if (!field || !specFor4(field).capabilities.groupable) {
5273
- return /* @__PURE__ */ jsx29("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.` });
5624
+ return /* @__PURE__ */ jsx31("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.` });
5274
5625
  }
5275
5626
  const columns = columnsFor(field);
5276
5627
  const shown = cardFields ? cardFields.map((key) => schema.fields.find((candidate) => candidate.key === key)).filter((candidate) => Boolean(candidate)) : (
@@ -5287,12 +5638,12 @@ function Kanban({
5287
5638
  }
5288
5639
  await update(record.id, { [field.key]: value });
5289
5640
  }
5290
- return /* @__PURE__ */ jsxs28("div", { className: cls("b316-board-wrap", className), style, children: [
5291
- /* @__PURE__ */ jsx29("div", { className: "b316-board", role: "list", children: columns.map((column) => {
5641
+ return /* @__PURE__ */ jsxs30("div", { className: cls("b316-board-wrap", className), style, children: [
5642
+ /* @__PURE__ */ jsx31("div", { className: "b316-board", role: "list", children: columns.map((column) => {
5292
5643
  const inColumn = records.filter(
5293
5644
  (record) => String(record.fields[field.key] ?? "") === String(column.value ?? "")
5294
5645
  );
5295
- return /* @__PURE__ */ jsxs28(
5646
+ return /* @__PURE__ */ jsxs30(
5296
5647
  "section",
5297
5648
  {
5298
5649
  className: over === String(column.value) ? "b316-board-column b316-board-over" : "b316-board-column",
@@ -5316,12 +5667,12 @@ function Kanban({
5316
5667
  setDragging(null);
5317
5668
  },
5318
5669
  children: [
5319
- /* @__PURE__ */ jsxs28("header", { className: "b316-board-head", children: [
5320
- /* @__PURE__ */ jsx29("span", { className: "b316-board-title", children: column.label }),
5321
- /* @__PURE__ */ jsx29("span", { className: "b316-muted", children: inColumn.length })
5670
+ /* @__PURE__ */ jsxs30("header", { className: "b316-board-head", children: [
5671
+ /* @__PURE__ */ jsx31("span", { className: "b316-board-title", children: column.label }),
5672
+ /* @__PURE__ */ jsx31("span", { className: "b316-muted", children: inColumn.length })
5322
5673
  ] }),
5323
- /* @__PURE__ */ jsxs28("div", { className: "b316-board-cards", children: [
5324
- inColumn.map((record) => /* @__PURE__ */ jsxs28(
5674
+ /* @__PURE__ */ jsxs30("div", { className: "b316-board-cards", children: [
5675
+ inColumn.map((record) => /* @__PURE__ */ jsxs30(
5325
5676
  "article",
5326
5677
  {
5327
5678
  className: "b316-board-card",
@@ -5333,10 +5684,10 @@ function Kanban({
5333
5684
  },
5334
5685
  onClick: onSelect ? () => onSelect(record) : void 0,
5335
5686
  children: [
5336
- /* @__PURE__ */ jsx29("div", { className: "b316-board-card-title", children: record.title ?? "Untitled" }),
5337
- shown.map((candidate) => /* @__PURE__ */ jsxs28("div", { className: "b316-board-card-field", children: [
5338
- /* @__PURE__ */ jsx29("span", { className: "b316-muted", children: candidate.label }),
5339
- /* @__PURE__ */ jsx29(
5687
+ /* @__PURE__ */ jsx31("div", { className: "b316-board-card-title", children: record.title ?? "Untitled" }),
5688
+ shown.map((candidate) => /* @__PURE__ */ jsxs30("div", { className: "b316-board-card-field", children: [
5689
+ /* @__PURE__ */ jsx31("span", { className: "b316-muted", children: candidate.label }),
5690
+ /* @__PURE__ */ jsx31(
5340
5691
  FieldCell,
5341
5692
  {
5342
5693
  value: record.fields[candidate.key] ?? null,
@@ -5349,9 +5700,9 @@ function Kanban({
5349
5700
  // Dragging is not reachable by keyboard and is awkward on a
5350
5701
  // phone. This is the same action by other means, not a
5351
5702
  // lesser fallback.
5352
- /* @__PURE__ */ jsxs28("label", { className: "b316-board-move", children: [
5353
- /* @__PURE__ */ jsx29("span", { className: "b316-muted", children: "Move to" }),
5354
- /* @__PURE__ */ jsx29(
5703
+ /* @__PURE__ */ jsxs30("label", { className: "b316-board-move", children: [
5704
+ /* @__PURE__ */ jsx31("span", { className: "b316-muted", children: "Move to" }),
5705
+ /* @__PURE__ */ jsx31(
5355
5706
  "select",
5356
5707
  {
5357
5708
  className: "b316-input",
@@ -5363,7 +5714,7 @@ function Kanban({
5363
5714
  );
5364
5715
  void move(record, chosen?.value ?? null);
5365
5716
  },
5366
- children: columns.map((candidate) => /* @__PURE__ */ jsx29("option", { value: String(candidate.value), children: candidate.label }, String(candidate.value)))
5717
+ children: columns.map((candidate) => /* @__PURE__ */ jsx31("option", { value: String(candidate.value), children: candidate.label }, String(candidate.value)))
5367
5718
  }
5368
5719
  )
5369
5720
  ] })
@@ -5372,14 +5723,14 @@ function Kanban({
5372
5723
  },
5373
5724
  record.id
5374
5725
  )),
5375
- inColumn.length === 0 ? /* @__PURE__ */ jsx29("div", { className: "b316-board-empty", children: emptyState ?? "Nothing here" }) : null
5726
+ inColumn.length === 0 ? /* @__PURE__ */ jsx31("div", { className: "b316-board-empty", children: emptyState ?? "Nothing here" }) : null
5376
5727
  ] })
5377
5728
  ]
5378
5729
  },
5379
5730
  String(column.value)
5380
5731
  );
5381
5732
  }) }),
5382
- hasMore ? /* @__PURE__ */ jsx29("div", { className: "b316-table-more", children: /* @__PURE__ */ jsxs28("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: [
5733
+ hasMore ? /* @__PURE__ */ jsx31("div", { className: "b316-table-more", children: /* @__PURE__ */ jsxs30("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: [
5383
5734
  "Showing ",
5384
5735
  records.length,
5385
5736
  " of ",
@@ -5406,7 +5757,7 @@ import {
5406
5757
  specFor as specFor5
5407
5758
  } from "@base316/sdk";
5408
5759
  import { useMemo as useMemo4 } from "react";
5409
- import { jsx as jsx30, jsxs as jsxs29 } from "react/jsx-runtime";
5760
+ import { jsx as jsx32, jsxs as jsxs31 } from "react/jsx-runtime";
5410
5761
  function Chart({
5411
5762
  collection,
5412
5763
  x,
@@ -5445,23 +5796,23 @@ function Chart({
5445
5796
  [records, axis, measure, aggregate, bucket, y]
5446
5797
  );
5447
5798
  if (error) {
5448
- return /* @__PURE__ */ jsx30("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx30("div", { className: "b316-error", role: "alert", children: error }) });
5799
+ return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx32("div", { className: "b316-error", role: "alert", children: error }) });
5449
5800
  }
5450
5801
  if (!schema || loading) {
5451
- return /* @__PURE__ */ jsx30("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5802
+ return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5452
5803
  }
5453
5804
  if (!axis) {
5454
- return /* @__PURE__ */ jsx30("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.` });
5805
+ return /* @__PURE__ */ jsx32("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.` });
5455
5806
  }
5456
5807
  if (y && !measure) {
5457
- return /* @__PURE__ */ jsx30("div", { className: cls("b316-card", className), style, children: `"${y}" cannot be ${aggregate === "avg" ? "averaged" : `combined with ${aggregate}`}.` });
5808
+ return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: `"${y}" cannot be ${aggregate === "avg" ? "averaged" : `combined with ${aggregate}`}.` });
5458
5809
  }
5459
5810
  const peak = Math.max(...buckets.map((entry) => entry.value), 0);
5460
5811
  const heading = title ?? `${measure ? `${aggregate} of ${measure.label}` : schema.namePlural} by ${axis.label}`;
5461
- return /* @__PURE__ */ jsxs29("figure", { className: cls("b316-card b316-chart", className), style, children: [
5462
- /* @__PURE__ */ jsx30("figcaption", { className: "b316-chart-title", children: heading }),
5463
- buckets.length === 0 || peak === 0 ? /* @__PURE__ */ jsx30("div", { className: "b316-empty", children: "Nothing to chart yet." }) : /* @__PURE__ */ jsx30("div", { className: "b316-chart-plot", style: { height }, children: buckets.map((entry) => /* @__PURE__ */ jsxs29("div", { className: "b316-chart-col", children: [
5464
- /* @__PURE__ */ jsx30(
5812
+ return /* @__PURE__ */ jsxs31("figure", { className: cls("b316-card b316-chart", className), style, children: [
5813
+ /* @__PURE__ */ jsx32("figcaption", { className: "b316-chart-title", children: heading }),
5814
+ buckets.length === 0 || peak === 0 ? /* @__PURE__ */ jsx32("div", { className: "b316-empty", children: "Nothing to chart yet." }) : /* @__PURE__ */ jsx32("div", { className: "b316-chart-plot", style: { height }, children: buckets.map((entry) => /* @__PURE__ */ jsxs31("div", { className: "b316-chart-col", children: [
5815
+ /* @__PURE__ */ jsx32(
5465
5816
  "div",
5466
5817
  {
5467
5818
  className: "b316-chart-bar",
@@ -5469,18 +5820,18 @@ function Chart({
5469
5820
  title: `${entry.label}: ${format(entry.value)}`
5470
5821
  }
5471
5822
  ),
5472
- /* @__PURE__ */ jsx30("span", { className: "b316-chart-label", children: entry.label })
5823
+ /* @__PURE__ */ jsx32("span", { className: "b316-chart-label", children: entry.label })
5473
5824
  ] }, entry.key)) }),
5474
- /* @__PURE__ */ jsxs29("details", { className: "b316-chart-data", children: [
5475
- /* @__PURE__ */ jsx30("summary", { children: "Values" }),
5476
- /* @__PURE__ */ jsxs29("table", { className: "b316-table", children: [
5477
- /* @__PURE__ */ jsx30("thead", { children: /* @__PURE__ */ jsxs29("tr", { children: [
5478
- /* @__PURE__ */ jsx30("th", { scope: "col", children: axis.label }),
5479
- /* @__PURE__ */ jsx30("th", { scope: "col", children: measure ? measure.label : "Count" })
5825
+ /* @__PURE__ */ jsxs31("details", { className: "b316-chart-data", children: [
5826
+ /* @__PURE__ */ jsx32("summary", { children: "Values" }),
5827
+ /* @__PURE__ */ jsxs31("table", { className: "b316-table", children: [
5828
+ /* @__PURE__ */ jsx32("thead", { children: /* @__PURE__ */ jsxs31("tr", { children: [
5829
+ /* @__PURE__ */ jsx32("th", { scope: "col", children: axis.label }),
5830
+ /* @__PURE__ */ jsx32("th", { scope: "col", children: measure ? measure.label : "Count" })
5480
5831
  ] }) }),
5481
- /* @__PURE__ */ jsx30("tbody", { children: buckets.map((entry) => /* @__PURE__ */ jsxs29("tr", { children: [
5482
- /* @__PURE__ */ jsx30("td", { children: entry.label }),
5483
- /* @__PURE__ */ jsx30("td", { children: format(entry.value) })
5832
+ /* @__PURE__ */ jsx32("tbody", { children: buckets.map((entry) => /* @__PURE__ */ jsxs31("tr", { children: [
5833
+ /* @__PURE__ */ jsx32("td", { children: entry.label }),
5834
+ /* @__PURE__ */ jsx32("td", { children: format(entry.value) })
5484
5835
  ] }, entry.key)) })
5485
5836
  ] })
5486
5837
  ] })
@@ -5539,8 +5890,8 @@ function combine(values, aggregate) {
5539
5890
 
5540
5891
  // src/RecordDetail.tsx
5541
5892
  import { specFor as specFor6 } from "@base316/sdk";
5542
- import { useState as useState29 } from "react";
5543
- import { jsx as jsx31, jsxs as jsxs30 } from "react/jsx-runtime";
5893
+ import { useState as useState30 } from "react";
5894
+ import { jsx as jsx33, jsxs as jsxs32 } from "react/jsx-runtime";
5544
5895
  function RecordDetail({
5545
5896
  collection,
5546
5897
  recordId,
@@ -5556,23 +5907,23 @@ function RecordDetail({
5556
5907
  tenant,
5557
5908
  recordId
5558
5909
  });
5559
- const [editing, setEditing] = useState29(false);
5910
+ const [editing, setEditing] = useState30(false);
5560
5911
  const record = records.find((candidate) => candidate.id === recordId);
5561
5912
  if (error) {
5562
- return /* @__PURE__ */ jsx31("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx31("div", { className: "b316-error", role: "alert", children: error }) });
5913
+ return /* @__PURE__ */ jsx33("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx33("div", { className: "b316-error", role: "alert", children: error }) });
5563
5914
  }
5564
5915
  if (!schema || loading) {
5565
- return /* @__PURE__ */ jsx31("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5916
+ return /* @__PURE__ */ jsx33("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5566
5917
  }
5567
5918
  if (!record) {
5568
- return /* @__PURE__ */ jsxs30("div", { className: cls("b316-card", className), style, children: [
5919
+ return /* @__PURE__ */ jsxs32("div", { className: cls("b316-card", className), style, children: [
5569
5920
  "That ",
5570
5921
  schema.name.toLowerCase(),
5571
5922
  " is not available."
5572
5923
  ] });
5573
5924
  }
5574
5925
  if (editing) {
5575
- return /* @__PURE__ */ jsx31(
5926
+ return /* @__PURE__ */ jsx33(
5576
5927
  RecordForm,
5577
5928
  {
5578
5929
  collection,
@@ -5586,12 +5937,12 @@ function RecordDetail({
5586
5937
  );
5587
5938
  }
5588
5939
  const writable = canWrite && !readOnly;
5589
- return /* @__PURE__ */ jsxs30("div", { className: cls("b316-card b316-detail", className), style, children: [
5590
- /* @__PURE__ */ jsxs30("div", { className: "b316-detail-head", children: [
5591
- /* @__PURE__ */ jsx31("h3", { className: "b316-detail-title", children: record.title ?? schema.name }),
5592
- /* @__PURE__ */ jsxs30("div", { className: "b316-detail-actions", children: [
5593
- writable ? /* @__PURE__ */ jsx31("button", { type: "button", className: "b316-button-quiet", onClick: () => setEditing(true), children: "Edit" }) : null,
5594
- writable ? /* @__PURE__ */ jsx31(
5940
+ return /* @__PURE__ */ jsxs32("div", { className: cls("b316-card b316-detail", className), style, children: [
5941
+ /* @__PURE__ */ jsxs32("div", { className: "b316-detail-head", children: [
5942
+ /* @__PURE__ */ jsx33("h3", { className: "b316-detail-title", children: record.title ?? schema.name }),
5943
+ /* @__PURE__ */ jsxs32("div", { className: "b316-detail-actions", children: [
5944
+ writable ? /* @__PURE__ */ jsx33("button", { type: "button", className: "b316-button-quiet", onClick: () => setEditing(true), children: "Edit" }) : null,
5945
+ writable ? /* @__PURE__ */ jsx33(
5595
5946
  ConfirmButton,
5596
5947
  {
5597
5948
  className: "b316-button-quiet b316-danger",
@@ -5604,15 +5955,15 @@ function RecordDetail({
5604
5955
  children: "Delete"
5605
5956
  }
5606
5957
  ) : null,
5607
- onClose ? /* @__PURE__ */ jsx31("button", { type: "button", className: "b316-button-quiet", onClick: onClose, children: "Close" }) : null
5958
+ onClose ? /* @__PURE__ */ jsx33("button", { type: "button", className: "b316-button-quiet", onClick: onClose, children: "Close" }) : null
5608
5959
  ] })
5609
5960
  ] }),
5610
- /* @__PURE__ */ jsx31("dl", { className: "b316-detail-fields", children: schema.fields.map((field) => /* @__PURE__ */ jsxs30("div", { className: "b316-detail-row", children: [
5611
- /* @__PURE__ */ jsxs30("dt", { className: "b316-label", children: [
5961
+ /* @__PURE__ */ jsx33("dl", { className: "b316-detail-fields", children: schema.fields.map((field) => /* @__PURE__ */ jsxs32("div", { className: "b316-detail-row", children: [
5962
+ /* @__PURE__ */ jsxs32("dt", { className: "b316-label", children: [
5612
5963
  field.label,
5613
- specFor6(field).computed ? /* @__PURE__ */ jsx31("span", { className: "b316-muted", children: " (calculated)" }) : null
5964
+ specFor6(field).computed ? /* @__PURE__ */ jsx33("span", { className: "b316-muted", children: " (calculated)" }) : null
5614
5965
  ] }),
5615
- /* @__PURE__ */ jsx31("dd", { children: /* @__PURE__ */ jsx31(
5966
+ /* @__PURE__ */ jsx33("dd", { children: /* @__PURE__ */ jsx33(
5616
5967
  FieldCell,
5617
5968
  {
5618
5969
  value: record.fields[field.key] ?? null,
@@ -5626,8 +5977,8 @@ function RecordDetail({
5626
5977
  }
5627
5978
 
5628
5979
  // src/SubscriptionManager.tsx
5629
- import { useCallback as useCallback10, useEffect as useEffect22, useState as useState30 } from "react";
5630
- import { jsx as jsx32, jsxs as jsxs31 } from "react/jsx-runtime";
5980
+ import { useCallback as useCallback10, useEffect as useEffect23, useState as useState31 } from "react";
5981
+ import { jsx as jsx34, jsxs as jsxs33 } from "react/jsx-runtime";
5631
5982
  function statusLabel(status2) {
5632
5983
  const words = status2.toLowerCase().split("_");
5633
5984
  return words.map((w, i) => i === 0 ? w.charAt(0).toUpperCase() + w.slice(1) : w).join(" ");
@@ -5667,15 +6018,15 @@ function SubscriptionManager({
5667
6018
  style
5668
6019
  }) {
5669
6020
  const { client, token, loading: sessionLoading } = useBase316();
5670
- const [subscription, setSubscription] = useState30(null);
5671
- const [loading, setLoading] = useState30(true);
5672
- const [managedBy, setManagedBy] = useState30(null);
5673
- const [schedule, setSchedule] = useState30([]);
5674
- const [busy, setBusy] = useState30(false);
5675
- const [error, setError] = useState30(null);
5676
- const [step, setStep] = useState30({ kind: "idle" });
5677
- const [reason, setReason] = useState30(null);
5678
- const [comment, setComment] = useState30("");
6021
+ const [subscription, setSubscription] = useState31(null);
6022
+ const [loading, setLoading] = useState31(true);
6023
+ const [managedBy, setManagedBy] = useState31(null);
6024
+ const [schedule, setSchedule] = useState31([]);
6025
+ const [busy, setBusy] = useState31(false);
6026
+ const [error, setError] = useState31(null);
6027
+ const [step, setStep] = useState31({ kind: "idle" });
6028
+ const [reason, setReason] = useState31(null);
6029
+ const [comment, setComment] = useState31("");
5679
6030
  const load = useCallback10(async () => {
5680
6031
  if (!token) {
5681
6032
  setSubscription(null);
@@ -5694,7 +6045,7 @@ function SubscriptionManager({
5694
6045
  setLoading(false);
5695
6046
  }
5696
6047
  }, [client, token]);
5697
- useEffect22(() => {
6048
+ useEffect23(() => {
5698
6049
  void load();
5699
6050
  }, [load]);
5700
6051
  const act = async (change, failure) => {
@@ -5712,29 +6063,29 @@ function SubscriptionManager({
5712
6063
  }
5713
6064
  };
5714
6065
  if (sessionLoading || loading) {
5715
- return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
6066
+ return /* @__PURE__ */ jsx34("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5716
6067
  }
5717
6068
  if (!token) {
5718
- return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: "Sign in to manage your subscription." });
6069
+ return /* @__PURE__ */ jsx34("div", { className: cls("b316-card", className), style, children: "Sign in to manage your subscription." });
5719
6070
  }
5720
6071
  if (error) {
5721
- return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx32("div", { className: "b316-error", role: "alert", children: error }) });
6072
+ return /* @__PURE__ */ jsx34("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx34("div", { className: "b316-error", role: "alert", children: error }) });
5722
6073
  }
5723
6074
  if (!subscription) {
5724
- return /* @__PURE__ */ jsx32("div", { className: cls("b316-card", className), style, children: "You are not subscribed to a plan." });
6075
+ return /* @__PURE__ */ jsx34("div", { className: cls("b316-card", className), style, children: "You are not subscribed to a plan." });
5725
6076
  }
5726
6077
  const renews = new Date(subscription.currentPeriodEnd).toLocaleDateString();
5727
6078
  const next = schedule[0] ?? null;
5728
6079
  const nextOn = next?.effectiveAt ? new Date(next.effectiveAt).toLocaleDateString() : renews;
5729
- return /* @__PURE__ */ jsxs31("div", { className: cls("b316-card", className), style, children: [
5730
- error ? /* @__PURE__ */ jsx32("div", { className: "b316-error", role: "alert", children: error }) : null,
5731
- /* @__PURE__ */ jsx32("div", { className: "b316-plan-name", children: subscription.planVersion.plan.name }),
5732
- /* @__PURE__ */ jsxs31("div", { className: "b316-muted", children: [
6080
+ return /* @__PURE__ */ jsxs33("div", { className: cls("b316-card", className), style, children: [
6081
+ error ? /* @__PURE__ */ jsx34("div", { className: "b316-error", role: "alert", children: error }) : null,
6082
+ /* @__PURE__ */ jsx34("div", { className: "b316-plan-name", children: subscription.planVersion.plan.name }),
6083
+ /* @__PURE__ */ jsxs33("div", { className: "b316-muted", children: [
5733
6084
  statusLabel(subscription.status),
5734
6085
  " \xB7 ",
5735
6086
  subscription.cancelAtPeriodEnd ? `Ends ${renews}` : `Renews ${renews}`
5736
6087
  ] }),
5737
- next && !managedBy ? /* @__PURE__ */ jsxs31("div", { className: "b316-muted", role: "status", style: { marginTop: 10 }, children: [
6088
+ next && !managedBy ? /* @__PURE__ */ jsxs33("div", { className: "b316-muted", role: "status", style: { marginTop: 10 }, children: [
5738
6089
  "Moves to ",
5739
6090
  next.plan.name,
5740
6091
  " on ",
@@ -5742,7 +6093,7 @@ function SubscriptionManager({
5742
6093
  ". You keep ",
5743
6094
  subscription.planVersion.plan.name,
5744
6095
  " until then.",
5745
- /* @__PURE__ */ jsx32("div", { children: /* @__PURE__ */ jsx32(
6096
+ /* @__PURE__ */ jsx34("div", { children: /* @__PURE__ */ jsx34(
5746
6097
  "button",
5747
6098
  {
5748
6099
  type: "button",
@@ -5767,17 +6118,17 @@ function SubscriptionManager({
5767
6118
  }
5768
6119
  ) })
5769
6120
  ] }) : null,
5770
- managedBy ? /* @__PURE__ */ jsxs31("p", { className: "b316-muted", children: [
6121
+ managedBy ? /* @__PURE__ */ jsxs33("p", { className: "b316-muted", children: [
5771
6122
  "Provided by ",
5772
6123
  managedBy.name ?? "the organization that manages your account",
5773
6124
  ". Ask them to change or cancel it."
5774
- ] }) : subscription.cancelAtPeriodEnd ? /* @__PURE__ */ jsxs31("div", { children: [
5775
- /* @__PURE__ */ jsxs31("p", { className: "b316-muted", children: [
6125
+ ] }) : subscription.cancelAtPeriodEnd ? /* @__PURE__ */ jsxs33("div", { children: [
6126
+ /* @__PURE__ */ jsxs33("p", { className: "b316-muted", children: [
5776
6127
  "This subscription will not renew. You keep access until ",
5777
6128
  renews,
5778
6129
  "."
5779
6130
  ] }),
5780
- /* @__PURE__ */ jsx32(
6131
+ /* @__PURE__ */ jsx34(
5781
6132
  "button",
5782
6133
  {
5783
6134
  type: "button",
@@ -5787,14 +6138,14 @@ function SubscriptionManager({
5787
6138
  children: busy ? "Working\u2026" : "Resume subscription"
5788
6139
  }
5789
6140
  )
5790
- ] }) : step.kind === "offer" ? /* @__PURE__ */ jsxs31("section", { style: { marginTop: 14 }, "aria-label": "Retention offer", children: [
5791
- /* @__PURE__ */ jsx32("div", { className: "b316-plan-name", children: step.cancellation.offer.headline ?? "Before you go" }),
5792
- /* @__PURE__ */ jsx32("p", { className: "b316-muted", children: step.cancellation.offer.message ?? `Stay on ${subscription.planVersion.plan.name} and get ${describeRetentionOffer(
6141
+ ] }) : step.kind === "offer" ? /* @__PURE__ */ jsxs33("section", { style: { marginTop: 14 }, "aria-label": "Retention offer", children: [
6142
+ /* @__PURE__ */ jsx34("div", { className: "b316-plan-name", children: step.cancellation.offer.headline ?? "Before you go" }),
6143
+ /* @__PURE__ */ jsx34("p", { className: "b316-muted", children: step.cancellation.offer.message ?? `Stay on ${subscription.planVersion.plan.name} and get ${describeRetentionOffer(
5793
6144
  step.cancellation.offer,
5794
6145
  step.cancellation.currency
5795
6146
  )}.` }),
5796
- /* @__PURE__ */ jsxs31("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
5797
- /* @__PURE__ */ jsx32(
6147
+ /* @__PURE__ */ jsxs33("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
6148
+ /* @__PURE__ */ jsx34(
5798
6149
  "button",
5799
6150
  {
5800
6151
  type: "button",
@@ -5807,7 +6158,7 @@ function SubscriptionManager({
5807
6158
  children: busy ? "Working\u2026" : "Accept offer and stay"
5808
6159
  }
5809
6160
  ),
5810
- /* @__PURE__ */ jsx32(
6161
+ /* @__PURE__ */ jsx34(
5811
6162
  "button",
5812
6163
  {
5813
6164
  type: "button",
@@ -5821,12 +6172,12 @@ function SubscriptionManager({
5821
6172
  }
5822
6173
  )
5823
6174
  ] }),
5824
- /* @__PURE__ */ jsxs31("p", { className: "b316-muted", children: [
6175
+ /* @__PURE__ */ jsxs33("p", { className: "b316-muted", children: [
5825
6176
  "If you cancel, you keep access until ",
5826
6177
  renews,
5827
6178
  "."
5828
6179
  ] })
5829
- ] }) : step.kind === "survey" ? /* @__PURE__ */ jsxs31(
6180
+ ] }) : step.kind === "survey" ? /* @__PURE__ */ jsxs33(
5830
6181
  "form",
5831
6182
  {
5832
6183
  style: { marginTop: 14 },
@@ -5846,15 +6197,15 @@ function SubscriptionManager({
5846
6197
  }, "Could not cancel. Try again.");
5847
6198
  },
5848
6199
  children: [
5849
- /* @__PURE__ */ jsxs31("p", { className: "b316-muted", children: [
6200
+ /* @__PURE__ */ jsxs33("p", { className: "b316-muted", children: [
5850
6201
  "You keep access until ",
5851
6202
  renews,
5852
6203
  ". It will not renew after that."
5853
6204
  ] }),
5854
- /* @__PURE__ */ jsxs31("fieldset", { className: "b316-fieldset", children: [
5855
- /* @__PURE__ */ jsx32("legend", { className: "b316-label", children: "Why are you leaving? (optional)" }),
5856
- REASONS.map((option) => /* @__PURE__ */ jsxs31("label", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
5857
- /* @__PURE__ */ jsx32(
6205
+ /* @__PURE__ */ jsxs33("fieldset", { className: "b316-fieldset", children: [
6206
+ /* @__PURE__ */ jsx34("legend", { className: "b316-label", children: "Why are you leaving? (optional)" }),
6207
+ REASONS.map((option) => /* @__PURE__ */ jsxs33("label", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
6208
+ /* @__PURE__ */ jsx34(
5858
6209
  "input",
5859
6210
  {
5860
6211
  type: "radio",
@@ -5864,12 +6215,12 @@ function SubscriptionManager({
5864
6215
  onChange: () => setReason(option.value)
5865
6216
  }
5866
6217
  ),
5867
- /* @__PURE__ */ jsx32("span", { children: option.label })
6218
+ /* @__PURE__ */ jsx34("span", { children: option.label })
5868
6219
  ] }, option.value))
5869
6220
  ] }),
5870
- /* @__PURE__ */ jsxs31("label", { className: "b316-field", children: [
5871
- /* @__PURE__ */ jsx32("span", { className: "b316-label", children: "Anything else? (optional)" }),
5872
- /* @__PURE__ */ jsx32(
6221
+ /* @__PURE__ */ jsxs33("label", { className: "b316-field", children: [
6222
+ /* @__PURE__ */ jsx34("span", { className: "b316-label", children: "Anything else? (optional)" }),
6223
+ /* @__PURE__ */ jsx34(
5873
6224
  "textarea",
5874
6225
  {
5875
6226
  className: "b316-input",
@@ -5880,9 +6231,9 @@ function SubscriptionManager({
5880
6231
  }
5881
6232
  )
5882
6233
  ] }),
5883
- /* @__PURE__ */ jsxs31("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
5884
- /* @__PURE__ */ jsx32("button", { type: "submit", className: "b316-button b316-button-secondary", disabled: busy, children: busy ? "Working\u2026" : "Cancel subscription" }),
5885
- /* @__PURE__ */ jsxs31(
6234
+ /* @__PURE__ */ jsxs33("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
6235
+ /* @__PURE__ */ jsx34("button", { type: "submit", className: "b316-button b316-button-secondary", disabled: busy, children: busy ? "Working\u2026" : "Cancel subscription" }),
6236
+ /* @__PURE__ */ jsxs33(
5886
6237
  "button",
5887
6238
  {
5888
6239
  type: "button",
@@ -5898,7 +6249,7 @@ function SubscriptionManager({
5898
6249
  ] })
5899
6250
  ]
5900
6251
  }
5901
- ) : /* @__PURE__ */ jsx32("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ jsx32(
6252
+ ) : /* @__PURE__ */ jsx34("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ jsx34(
5902
6253
  "button",
5903
6254
  {
5904
6255
  type: "button",
@@ -5916,11 +6267,11 @@ function SubscriptionManager({
5916
6267
  }
5917
6268
 
5918
6269
  // src/BillingPortal.tsx
5919
- import { useCallback as useCallback12, useEffect as useEffect26, useState as useState34 } from "react";
6270
+ import { useCallback as useCallback12, useEffect as useEffect27, useState as useState35 } from "react";
5920
6271
 
5921
6272
  // src/CreditBalances.tsx
5922
- import { useEffect as useEffect23, useState as useState31 } from "react";
5923
- import { Fragment as Fragment9, jsx as jsx33, jsxs as jsxs32 } from "react/jsx-runtime";
6273
+ import { useEffect as useEffect24, useState as useState32 } from "react";
6274
+ import { Fragment as Fragment11, jsx as jsx35, jsxs as jsxs34 } from "react/jsx-runtime";
5924
6275
  function units(value) {
5925
6276
  return value === null ? "Unlimited" : Number(value).toLocaleString("en");
5926
6277
  }
@@ -5955,10 +6306,10 @@ function Feature({
5955
6306
  }) {
5956
6307
  const { client, token } = useBase316();
5957
6308
  const setting = feature.autoRecharge;
5958
- const [busy, setBusy] = useState31(false);
5959
- const [error, setError] = useState31(null);
5960
- const [saved, setSaved] = useState31(null);
5961
- const [pack, setPack] = useState31(feature.packs[0]?.id ?? "");
6309
+ const [busy, setBusy] = useState32(false);
6310
+ const [error, setError] = useState32(null);
6311
+ const [saved, setSaved] = useState32(null);
6312
+ const [pack, setPack] = useState32(feature.packs[0]?.id ?? "");
5962
6313
  const unit = feature.unit ? ` ${feature.unit}` : "";
5963
6314
  const warning = status(feature);
5964
6315
  const buy = async () => {
@@ -6012,33 +6363,33 @@ function Feature({
6012
6363
  setBusy(false);
6013
6364
  }
6014
6365
  };
6015
- return /* @__PURE__ */ jsxs32("div", { className: "b316-card b316-credit-balance", children: [
6016
- /* @__PURE__ */ jsx33("div", { className: "b316-label", children: feature.featureName }),
6017
- /* @__PURE__ */ jsxs32("div", { children: [
6018
- /* @__PURE__ */ jsx33("strong", { children: units(feature.remaining) }),
6366
+ return /* @__PURE__ */ jsxs34("div", { className: "b316-card b316-credit-balance", children: [
6367
+ /* @__PURE__ */ jsx35("div", { className: "b316-label", children: feature.featureName }),
6368
+ /* @__PURE__ */ jsxs34("div", { children: [
6369
+ /* @__PURE__ */ jsx35("strong", { children: units(feature.remaining) }),
6019
6370
  unit,
6020
6371
  " left"
6021
6372
  ] }),
6022
- /* @__PURE__ */ jsxs32("div", { className: "b316-muted", children: [
6373
+ /* @__PURE__ */ jsxs34("div", { className: "b316-muted", children: [
6023
6374
  feature.allowance === null ? "Unlimited allowance" : `${units(feature.allowanceRemaining)} of ${units(feature.allowance)} included this period`,
6024
6375
  " ",
6025
6376
  "\xB7 ",
6026
6377
  units(feature.purchasedRemaining),
6027
6378
  " purchased"
6028
6379
  ] }),
6029
- warning && !managed ? /* @__PURE__ */ jsx33("div", { className: "b316-error", role: "alert", children: warning }) : null,
6030
- error ? /* @__PURE__ */ jsx33("div", { className: "b316-error", role: "alert", children: error }) : null,
6031
- saved ? /* @__PURE__ */ jsx33("div", { className: "b316-notice", role: "status", children: saved }) : null,
6032
- managed || feature.packs.length === 0 ? null : /* @__PURE__ */ jsxs32(Fragment9, { children: [
6033
- /* @__PURE__ */ jsxs32("div", { className: "b316-row", style: { marginTop: 12 }, children: [
6034
- /* @__PURE__ */ jsx33(
6380
+ warning && !managed ? /* @__PURE__ */ jsx35("div", { className: "b316-error", role: "alert", children: warning }) : null,
6381
+ error ? /* @__PURE__ */ jsx35("div", { className: "b316-error", role: "alert", children: error }) : null,
6382
+ saved ? /* @__PURE__ */ jsx35("div", { className: "b316-notice", role: "status", children: saved }) : null,
6383
+ managed || feature.packs.length === 0 ? null : /* @__PURE__ */ jsxs34(Fragment11, { children: [
6384
+ /* @__PURE__ */ jsxs34("div", { className: "b316-row", style: { marginTop: 12 }, children: [
6385
+ /* @__PURE__ */ jsx35(
6035
6386
  "select",
6036
6387
  {
6037
6388
  className: "b316-input",
6038
6389
  "aria-label": "Pack to buy",
6039
6390
  value: pack,
6040
6391
  onChange: (event) => setPack(event.target.value),
6041
- children: feature.packs.map((option) => /* @__PURE__ */ jsxs32("option", { value: option.id, children: [
6392
+ children: feature.packs.map((option) => /* @__PURE__ */ jsxs34("option", { value: option.id, children: [
6042
6393
  option.name,
6043
6394
  " \u2014 ",
6044
6395
  units(option.units),
@@ -6047,7 +6398,7 @@ function Feature({
6047
6398
  ] }, option.id))
6048
6399
  }
6049
6400
  ),
6050
- /* @__PURE__ */ jsx33(
6401
+ /* @__PURE__ */ jsx35(
6051
6402
  "button",
6052
6403
  {
6053
6404
  type: "button",
@@ -6058,19 +6409,19 @@ function Feature({
6058
6409
  }
6059
6410
  )
6060
6411
  ] }),
6061
- /* @__PURE__ */ jsxs32("form", { onSubmit: save, style: { marginTop: 16 }, children: [
6062
- /* @__PURE__ */ jsxs32("label", { className: "b316-checkbox", children: [
6063
- /* @__PURE__ */ jsx33("input", { type: "checkbox", name: "enabled", defaultChecked: setting?.enabled ?? false }),
6412
+ /* @__PURE__ */ jsxs34("form", { onSubmit: save, style: { marginTop: 16 }, children: [
6413
+ /* @__PURE__ */ jsxs34("label", { className: "b316-checkbox", children: [
6414
+ /* @__PURE__ */ jsx35("input", { type: "checkbox", name: "enabled", defaultChecked: setting?.enabled ?? false }),
6064
6415
  " ",
6065
6416
  "Buy credits automatically when my balance runs low"
6066
6417
  ] }),
6067
- /* @__PURE__ */ jsxs32("label", { className: "b316-field", children: [
6068
- /* @__PURE__ */ jsxs32("span", { className: "b316-label", children: [
6418
+ /* @__PURE__ */ jsxs34("label", { className: "b316-field", children: [
6419
+ /* @__PURE__ */ jsxs34("span", { className: "b316-label", children: [
6069
6420
  "When fewer than this many",
6070
6421
  unit,
6071
6422
  " are left"
6072
6423
  ] }),
6073
- /* @__PURE__ */ jsx33(
6424
+ /* @__PURE__ */ jsx35(
6074
6425
  "input",
6075
6426
  {
6076
6427
  className: "b316-input",
@@ -6081,21 +6432,21 @@ function Feature({
6081
6432
  }
6082
6433
  )
6083
6434
  ] }),
6084
- /* @__PURE__ */ jsxs32("label", { className: "b316-field", children: [
6085
- /* @__PURE__ */ jsx33("span", { className: "b316-label", children: "Buy" }),
6086
- /* @__PURE__ */ jsx33(
6435
+ /* @__PURE__ */ jsxs34("label", { className: "b316-field", children: [
6436
+ /* @__PURE__ */ jsx35("span", { className: "b316-label", children: "Buy" }),
6437
+ /* @__PURE__ */ jsx35(
6087
6438
  "select",
6088
6439
  {
6089
6440
  className: "b316-input",
6090
6441
  name: "creditPackId",
6091
6442
  defaultValue: setting?.creditPackId ?? feature.packs[0]?.id,
6092
- children: feature.packs.map((option) => /* @__PURE__ */ jsx33("option", { value: option.id, children: option.name }, option.id))
6443
+ children: feature.packs.map((option) => /* @__PURE__ */ jsx35("option", { value: option.id, children: option.name }, option.id))
6093
6444
  }
6094
6445
  )
6095
6446
  ] }),
6096
- /* @__PURE__ */ jsxs32("label", { className: "b316-field", children: [
6097
- /* @__PURE__ */ jsx33("span", { className: "b316-label", children: "At most this many times a month" }),
6098
- /* @__PURE__ */ jsx33(
6447
+ /* @__PURE__ */ jsxs34("label", { className: "b316-field", children: [
6448
+ /* @__PURE__ */ jsx35("span", { className: "b316-label", children: "At most this many times a month" }),
6449
+ /* @__PURE__ */ jsx35(
6099
6450
  "input",
6100
6451
  {
6101
6452
  className: "b316-input",
@@ -6105,13 +6456,13 @@ function Feature({
6105
6456
  }
6106
6457
  )
6107
6458
  ] }),
6108
- /* @__PURE__ */ jsxs32("label", { className: "b316-field", children: [
6109
- /* @__PURE__ */ jsxs32("span", { className: "b316-label", children: [
6459
+ /* @__PURE__ */ jsxs34("label", { className: "b316-field", children: [
6460
+ /* @__PURE__ */ jsxs34("span", { className: "b316-label", children: [
6110
6461
  "Spending at most (",
6111
6462
  setting?.currency ?? feature.packs[0]?.currency ?? "USD",
6112
6463
  ") a month"
6113
6464
  ] }),
6114
- /* @__PURE__ */ jsx33(
6465
+ /* @__PURE__ */ jsx35(
6115
6466
  "input",
6116
6467
  {
6117
6468
  className: "b316-input",
@@ -6121,16 +6472,16 @@ function Feature({
6121
6472
  }
6122
6473
  )
6123
6474
  ] }),
6124
- /* @__PURE__ */ jsx33("button", { type: "submit", className: "b316-button", disabled: busy, children: "Save auto-recharge" })
6475
+ /* @__PURE__ */ jsx35("button", { type: "submit", className: "b316-button", disabled: busy, children: "Save auto-recharge" })
6125
6476
  ] })
6126
6477
  ] })
6127
6478
  ] });
6128
6479
  }
6129
6480
  function CreditBalances({ onChange, className, style }) {
6130
6481
  const { client, token, loading: sessionLoading } = useBase316();
6131
- const [state, setState] = useState31({ kind: "loading" });
6132
- const [version, setVersion] = useState31(0);
6133
- useEffect23(() => {
6482
+ const [state, setState] = useState32({ kind: "loading" });
6483
+ const [version, setVersion] = useState32(0);
6484
+ useEffect24(() => {
6134
6485
  if (!token) return;
6135
6486
  let cancelled = false;
6136
6487
  client.billing.credits(token).then((credits2) => {
@@ -6143,24 +6494,24 @@ function CreditBalances({ onChange, className, style }) {
6143
6494
  cancelled = true;
6144
6495
  };
6145
6496
  }, [client, token, version]);
6146
- const wrap = (content) => /* @__PURE__ */ jsx33("div", { className: cls("b316-credit-balances", className), style, children: content });
6497
+ const wrap = (content) => /* @__PURE__ */ jsx35("div", { className: cls("b316-credit-balances", className), style, children: content });
6147
6498
  if (sessionLoading || !token || state.kind === "loading") return null;
6148
6499
  if (state.kind === "error") {
6149
6500
  return wrap(
6150
- /* @__PURE__ */ jsx33("div", { className: "b316-card", children: /* @__PURE__ */ jsx33("div", { className: "b316-error", role: "alert", children: "Could not load your credits." }) })
6501
+ /* @__PURE__ */ jsx35("div", { className: "b316-card", children: /* @__PURE__ */ jsx35("div", { className: "b316-error", role: "alert", children: "Could not load your credits." }) })
6151
6502
  );
6152
6503
  }
6153
6504
  const { credits } = state;
6154
6505
  if (credits.features.length === 0) return null;
6155
6506
  return wrap(
6156
- /* @__PURE__ */ jsxs32(Fragment9, { children: [
6157
- credits.managedBy ? /* @__PURE__ */ jsxs32("p", { className: "b316-muted", children: [
6507
+ /* @__PURE__ */ jsxs34(Fragment11, { children: [
6508
+ credits.managedBy ? /* @__PURE__ */ jsxs34("p", { className: "b316-muted", children: [
6158
6509
  "Credits for this account come from",
6159
6510
  " ",
6160
6511
  credits.managedBy.name ?? "the organization that manages it",
6161
6512
  ", which manages them."
6162
6513
  ] }) : null,
6163
- credits.features.map((feature) => /* @__PURE__ */ jsx33(
6514
+ credits.features.map((feature) => /* @__PURE__ */ jsx35(
6164
6515
  Feature,
6165
6516
  {
6166
6517
  feature,
@@ -6177,19 +6528,19 @@ function CreditBalances({ onChange, className, style }) {
6177
6528
  }
6178
6529
 
6179
6530
  // src/PaymentMethod.tsx
6180
- import { useEffect as useEffect24, useState as useState32 } from "react";
6181
- import { Fragment as Fragment10, jsx as jsx34, jsxs as jsxs33 } from "react/jsx-runtime";
6531
+ import { useEffect as useEffect25, useState as useState33 } from "react";
6532
+ import { Fragment as Fragment12, jsx as jsx36, jsxs as jsxs35 } from "react/jsx-runtime";
6182
6533
  function brandName(brand) {
6183
6534
  if (!brand) return "Card";
6184
6535
  return brand.charAt(0).toUpperCase() + brand.slice(1);
6185
6536
  }
6186
6537
  function PaymentMethod({ returnUrl, className, style }) {
6187
6538
  const { client, token, loading: sessionLoading } = useBase316();
6188
- const [state, setState] = useState32({ kind: "loading" });
6189
- const [busy, setBusy] = useState32(false);
6190
- const [error, setError] = useState32(null);
6191
- const [version, setVersion] = useState32(0);
6192
- useEffect24(() => {
6539
+ const [state, setState] = useState33({ kind: "loading" });
6540
+ const [busy, setBusy] = useState33(false);
6541
+ const [error, setError] = useState33(null);
6542
+ const [version, setVersion] = useState33(0);
6543
+ useEffect25(() => {
6193
6544
  if (!token) return;
6194
6545
  let cancelled = false;
6195
6546
  client.billing.paymentMethods(token).then((result) => {
@@ -6205,7 +6556,7 @@ function PaymentMethod({ returnUrl, className, style }) {
6205
6556
  cancelled = true;
6206
6557
  };
6207
6558
  }, [client, token, version]);
6208
- const wrap = (content) => /* @__PURE__ */ jsx34("div", { className: cls("b316-card b316-payment-method", className), style, children: content });
6559
+ const wrap = (content) => /* @__PURE__ */ jsx36("div", { className: cls("b316-card b316-payment-method", className), style, children: content });
6209
6560
  if (sessionLoading) return wrap("Loading\u2026");
6210
6561
  if (!token) return wrap("Sign in to manage your payment method.");
6211
6562
  switch (state.kind) {
@@ -6213,11 +6564,11 @@ function PaymentMethod({ returnUrl, className, style }) {
6213
6564
  return wrap("Loading\u2026");
6214
6565
  case "error":
6215
6566
  return wrap(
6216
- /* @__PURE__ */ jsx34("div", { className: "b316-error", role: "alert", children: "Could not load your payment method." })
6567
+ /* @__PURE__ */ jsx36("div", { className: "b316-error", role: "alert", children: "Could not load your payment method." })
6217
6568
  );
6218
6569
  case "managed":
6219
6570
  return wrap(
6220
- /* @__PURE__ */ jsx34("p", { className: "b316-muted", children: "Your plan is paid for by the organization that manages it." })
6571
+ /* @__PURE__ */ jsx36("p", { className: "b316-muted", children: "Your plan is paid for by the organization that manages it." })
6221
6572
  );
6222
6573
  }
6223
6574
  const card = state.cards.find((saved) => saved.isDefault) ?? null;
@@ -6236,31 +6587,31 @@ function PaymentMethod({ returnUrl, className, style }) {
6236
6587
  }
6237
6588
  };
6238
6589
  return wrap(
6239
- /* @__PURE__ */ jsxs33(Fragment10, { children: [
6240
- /* @__PURE__ */ jsx34("div", { className: "b316-label", children: "Payment method" }),
6241
- card ? /* @__PURE__ */ jsxs33("div", { children: [
6242
- /* @__PURE__ */ jsxs33("div", { children: [
6590
+ /* @__PURE__ */ jsxs35(Fragment12, { children: [
6591
+ /* @__PURE__ */ jsx36("div", { className: "b316-label", children: "Payment method" }),
6592
+ card ? /* @__PURE__ */ jsxs35("div", { children: [
6593
+ /* @__PURE__ */ jsxs35("div", { children: [
6243
6594
  brandName(card.brand),
6244
6595
  " ending ",
6245
6596
  card.last4 ?? "????"
6246
6597
  ] }),
6247
- card.expMonth && card.expYear ? /* @__PURE__ */ jsxs33("div", { className: "b316-muted", children: [
6598
+ card.expMonth && card.expYear ? /* @__PURE__ */ jsxs35("div", { className: "b316-muted", children: [
6248
6599
  "Expires ",
6249
6600
  String(card.expMonth).padStart(2, "0"),
6250
6601
  "/",
6251
6602
  card.expYear
6252
6603
  ] }) : null
6253
- ] }) : /* @__PURE__ */ jsx34("p", { className: "b316-muted", children: "No card on file." }),
6254
- others.length > 0 ? /* @__PURE__ */ jsxs33("div", { style: { marginTop: 12 }, children: [
6255
- /* @__PURE__ */ jsx34("div", { className: "b316-label", children: "Other saved cards" }),
6256
- others.map((saved) => /* @__PURE__ */ jsxs33("div", { className: "b316-row", style: { marginTop: 6 }, children: [
6257
- /* @__PURE__ */ jsxs33("span", { children: [
6604
+ ] }) : /* @__PURE__ */ jsx36("p", { className: "b316-muted", children: "No card on file." }),
6605
+ others.length > 0 ? /* @__PURE__ */ jsxs35("div", { style: { marginTop: 12 }, children: [
6606
+ /* @__PURE__ */ jsx36("div", { className: "b316-label", children: "Other saved cards" }),
6607
+ others.map((saved) => /* @__PURE__ */ jsxs35("div", { className: "b316-row", style: { marginTop: 6 }, children: [
6608
+ /* @__PURE__ */ jsxs35("span", { children: [
6258
6609
  brandName(saved.brand),
6259
6610
  " ending ",
6260
6611
  saved.last4 ?? "????"
6261
6612
  ] }),
6262
- /* @__PURE__ */ jsxs33("span", { children: [
6263
- /* @__PURE__ */ jsx34(
6613
+ /* @__PURE__ */ jsxs35("span", { children: [
6614
+ /* @__PURE__ */ jsx36(
6264
6615
  "button",
6265
6616
  {
6266
6617
  type: "button",
@@ -6274,7 +6625,7 @@ function PaymentMethod({ returnUrl, className, style }) {
6274
6625
  }
6275
6626
  ),
6276
6627
  " ",
6277
- /* @__PURE__ */ jsx34(
6628
+ /* @__PURE__ */ jsx36(
6278
6629
  "button",
6279
6630
  {
6280
6631
  type: "button",
@@ -6290,8 +6641,8 @@ function PaymentMethod({ returnUrl, className, style }) {
6290
6641
  ] })
6291
6642
  ] }, saved.id))
6292
6643
  ] }) : null,
6293
- error ? /* @__PURE__ */ jsx34("div", { className: "b316-error", role: "alert", children: error }) : null,
6294
- /* @__PURE__ */ jsx34(
6644
+ error ? /* @__PURE__ */ jsx36("div", { className: "b316-error", role: "alert", children: error }) : null,
6645
+ /* @__PURE__ */ jsx36(
6295
6646
  "button",
6296
6647
  {
6297
6648
  type: "button",
@@ -6320,8 +6671,8 @@ function PaymentMethod({ returnUrl, className, style }) {
6320
6671
  }
6321
6672
 
6322
6673
  // src/PlanChangeReview.tsx
6323
- import { useCallback as useCallback11, useEffect as useEffect25, useState as useState33 } from "react";
6324
- import { Fragment as Fragment11, jsx as jsx35, jsxs as jsxs34 } from "react/jsx-runtime";
6674
+ import { useCallback as useCallback11, useEffect as useEffect26, useState as useState34 } from "react";
6675
+ import { Fragment as Fragment13, jsx as jsx37, jsxs as jsxs36 } from "react/jsx-runtime";
6325
6676
  function money5(amount, currency) {
6326
6677
  if (amount === null) return "\u2014";
6327
6678
  const value = Number(amount);
@@ -6354,12 +6705,12 @@ function PlanChangeReview({
6354
6705
  style
6355
6706
  }) {
6356
6707
  const { client, token } = useBase316();
6357
- const [timing, setTiming] = useState33(void 0);
6358
- const [preview, setPreview] = useState33(null);
6359
- const [error, setError] = useState33(null);
6360
- const [needsCard, setNeedsCard] = useState33(false);
6361
- const [busy, setBusy] = useState33(false);
6362
- useEffect25(() => {
6708
+ const [timing, setTiming] = useState34(void 0);
6709
+ const [preview, setPreview] = useState34(null);
6710
+ const [error, setError] = useState34(null);
6711
+ const [needsCard, setNeedsCard] = useState34(false);
6712
+ const [busy, setBusy] = useState34(false);
6713
+ useEffect26(() => {
6363
6714
  if (!token) return;
6364
6715
  let cancelled = false;
6365
6716
  client.billing.previewPlanChange(token, planVersionId, timing).then((result) => {
@@ -6411,12 +6762,12 @@ function PlanChangeReview({
6411
6762
  setError("Cards cannot be added here right now.");
6412
6763
  }
6413
6764
  }, [client, token, onNeedsCard]);
6414
- const card = (content) => /* @__PURE__ */ jsx35("div", { className: cls("b316-card b316-plan-review", className), style, children: content });
6765
+ const card = (content) => /* @__PURE__ */ jsx37("div", { className: cls("b316-card b316-plan-review", className), style, children: content });
6415
6766
  if (error && !preview) {
6416
6767
  return card(
6417
- /* @__PURE__ */ jsxs34(Fragment11, { children: [
6418
- /* @__PURE__ */ jsx35("div", { className: "b316-error", role: "alert", children: error }),
6419
- onCancel ? /* @__PURE__ */ jsx35("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: "Back" }) : null
6768
+ /* @__PURE__ */ jsxs36(Fragment13, { children: [
6769
+ /* @__PURE__ */ jsx37("div", { className: "b316-error", role: "alert", children: error }),
6770
+ onCancel ? /* @__PURE__ */ jsx37("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: "Back" }) : null
6420
6771
  ] })
6421
6772
  );
6422
6773
  }
@@ -6429,26 +6780,26 @@ function PlanChangeReview({
6429
6780
  const otherReason = preview.timings[other]?.reason ?? null;
6430
6781
  const changes = preview.entitlements.filter((change) => change.change !== "UNCHANGED");
6431
6782
  return card(
6432
- /* @__PURE__ */ jsxs34(Fragment11, { children: [
6433
- /* @__PURE__ */ jsxs34("div", { className: "b316-plan-name", children: [
6783
+ /* @__PURE__ */ jsxs36(Fragment13, { children: [
6784
+ /* @__PURE__ */ jsxs36("div", { className: "b316-plan-name", children: [
6434
6785
  "Change to ",
6435
6786
  to.planName
6436
6787
  ] }),
6437
- /* @__PURE__ */ jsxs34("div", { className: "b316-muted", children: [
6788
+ /* @__PURE__ */ jsxs36("div", { className: "b316-muted", children: [
6438
6789
  "From ",
6439
6790
  from.planName
6440
6791
  ] }),
6441
- error ? /* @__PURE__ */ jsx35("div", { className: "b316-error", role: "alert", children: error }) : null,
6442
- changes.length === 0 ? /* @__PURE__ */ jsx35("p", { className: "b316-muted", children: "Every feature stays the same." }) : /* @__PURE__ */ jsxs34("table", { className: "b316-review-table", children: [
6443
- /* @__PURE__ */ jsx35("thead", { children: /* @__PURE__ */ jsxs34("tr", { children: [
6444
- /* @__PURE__ */ jsx35("th", { children: "Feature" }),
6445
- /* @__PURE__ */ jsx35("th", { children: from.planName }),
6446
- /* @__PURE__ */ jsx35("th", { children: to.planName })
6792
+ error ? /* @__PURE__ */ jsx37("div", { className: "b316-error", role: "alert", children: error }) : null,
6793
+ changes.length === 0 ? /* @__PURE__ */ jsx37("p", { className: "b316-muted", children: "Every feature stays the same." }) : /* @__PURE__ */ jsxs36("table", { className: "b316-review-table", children: [
6794
+ /* @__PURE__ */ jsx37("thead", { children: /* @__PURE__ */ jsxs36("tr", { children: [
6795
+ /* @__PURE__ */ jsx37("th", { children: "Feature" }),
6796
+ /* @__PURE__ */ jsx37("th", { children: from.planName }),
6797
+ /* @__PURE__ */ jsx37("th", { children: to.planName })
6447
6798
  ] }) }),
6448
- /* @__PURE__ */ jsx35("tbody", { children: changes.map((change) => /* @__PURE__ */ jsxs34("tr", { children: [
6449
- /* @__PURE__ */ jsx35("td", { children: change.featureName }),
6450
- /* @__PURE__ */ jsx35("td", { children: limitText(change.before, change.type) }),
6451
- /* @__PURE__ */ jsx35(
6799
+ /* @__PURE__ */ jsx37("tbody", { children: changes.map((change) => /* @__PURE__ */ jsxs36("tr", { children: [
6800
+ /* @__PURE__ */ jsx37("td", { children: change.featureName }),
6801
+ /* @__PURE__ */ jsx37("td", { children: limitText(change.before, change.type) }),
6802
+ /* @__PURE__ */ jsx37(
6452
6803
  "td",
6453
6804
  {
6454
6805
  className: change.change === "GAINED" || change.change === "INCREASED" ? "b316-review-gain" : "b316-review-loss",
@@ -6457,40 +6808,40 @@ function PlanChangeReview({
6457
6808
  )
6458
6809
  ] }, change.featureId)) })
6459
6810
  ] }),
6460
- preview.timing === "NOW" ? now.trialing ? /* @__PURE__ */ jsxs34("p", { children: [
6811
+ preview.timing === "NOW" ? now.trialing ? /* @__PURE__ */ jsxs36("p", { children: [
6461
6812
  "The change happens now. Your trial carries on until ",
6462
6813
  day4(now.trialEndsAt),
6463
6814
  ", and nothing is charged before then."
6464
- ] }) : /* @__PURE__ */ jsxs34("div", { children: [
6465
- Number(now.credit) > 0 ? /* @__PURE__ */ jsxs34("div", { className: "b316-row", children: [
6466
- /* @__PURE__ */ jsxs34("span", { className: "b316-muted", children: [
6815
+ ] }) : /* @__PURE__ */ jsxs36("div", { children: [
6816
+ Number(now.credit) > 0 ? /* @__PURE__ */ jsxs36("div", { className: "b316-row", children: [
6817
+ /* @__PURE__ */ jsxs36("span", { className: "b316-muted", children: [
6467
6818
  "Credit for the unused part of ",
6468
6819
  from.planName
6469
6820
  ] }),
6470
- /* @__PURE__ */ jsxs34("span", { className: "b316-num", children: [
6821
+ /* @__PURE__ */ jsxs36("span", { className: "b316-num", children: [
6471
6822
  "\u2212",
6472
6823
  money5(now.credit, from.currency)
6473
6824
  ] })
6474
6825
  ] }) : null,
6475
- Number(now.closingUsage) > 0 ? /* @__PURE__ */ jsxs34("div", { className: "b316-row", children: [
6476
- /* @__PURE__ */ jsx35("span", { className: "b316-muted", children: "Usage so far this period" }),
6477
- /* @__PURE__ */ jsx35("span", { className: "b316-num", children: money5(now.closingUsage, from.currency) })
6826
+ Number(now.closingUsage) > 0 ? /* @__PURE__ */ jsxs36("div", { className: "b316-row", children: [
6827
+ /* @__PURE__ */ jsx37("span", { className: "b316-muted", children: "Usage so far this period" }),
6828
+ /* @__PURE__ */ jsx37("span", { className: "b316-num", children: money5(now.closingUsage, from.currency) })
6478
6829
  ] }) : null,
6479
- /* @__PURE__ */ jsxs34("div", { className: "b316-row", children: [
6480
- /* @__PURE__ */ jsxs34("span", { className: "b316-muted", children: [
6830
+ /* @__PURE__ */ jsxs36("div", { className: "b316-row", children: [
6831
+ /* @__PURE__ */ jsxs36("span", { className: "b316-muted", children: [
6481
6832
  to.planName,
6482
6833
  ", ",
6483
6834
  day4(now.newPeriod.start),
6484
6835
  " \u2013 ",
6485
6836
  day4(now.newPeriod.end)
6486
6837
  ] }),
6487
- /* @__PURE__ */ jsx35("span", { className: "b316-num", children: money5(now.newPeriodCharge, to.currency) })
6838
+ /* @__PURE__ */ jsx37("span", { className: "b316-num", children: money5(now.newPeriodCharge, to.currency) })
6488
6839
  ] }),
6489
- now.net !== null ? /* @__PURE__ */ jsxs34("div", { className: "b316-row b316-invoice-total", children: [
6490
- /* @__PURE__ */ jsx35("span", { children: "Due now" }),
6491
- /* @__PURE__ */ jsx35("span", { className: "b316-num", children: money5(now.net, to.currency) })
6840
+ now.net !== null ? /* @__PURE__ */ jsxs36("div", { className: "b316-row b316-invoice-total", children: [
6841
+ /* @__PURE__ */ jsx37("span", { children: "Due now" }),
6842
+ /* @__PURE__ */ jsx37("span", { className: "b316-num", children: money5(now.net, to.currency) })
6492
6843
  ] }) : null
6493
- ] }) : /* @__PURE__ */ jsxs34("p", { children: [
6844
+ ] }) : /* @__PURE__ */ jsxs36("p", { children: [
6494
6845
  "You keep ",
6495
6846
  from.planName,
6496
6847
  " until ",
@@ -6503,7 +6854,7 @@ function PlanChangeReview({
6503
6854
  preview.atPeriodEnd.nextInvoice.currency
6504
6855
  )}.` : ""
6505
6856
  ] }),
6506
- otherOpen ? /* @__PURE__ */ jsx35(
6857
+ otherOpen ? /* @__PURE__ */ jsx37(
6507
6858
  "button",
6508
6859
  {
6509
6860
  type: "button",
@@ -6514,12 +6865,12 @@ function PlanChangeReview({
6514
6865
  },
6515
6866
  children: other === "NOW" ? "Change now instead" : "Wait until the end of the period instead"
6516
6867
  }
6517
- ) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */ jsx35("p", { className: "b316-muted", children: TIMING_CLOSED[otherReason] }) : null,
6518
- needsCard ? /* @__PURE__ */ jsxs34("div", { className: "b316-notice", role: "status", children: [
6868
+ ) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */ jsx37("p", { className: "b316-muted", children: TIMING_CLOSED[otherReason] }) : null,
6869
+ needsCard ? /* @__PURE__ */ jsxs36("div", { className: "b316-notice", role: "status", children: [
6519
6870
  "A card is needed for a change that is charged now.",
6520
- /* @__PURE__ */ jsx35("div", { className: "b316-review-actions", children: /* @__PURE__ */ jsx35("button", { type: "button", className: "b316-button", onClick: () => void addCard(), children: "Add a card" }) })
6521
- ] }) : /* @__PURE__ */ jsxs34("div", { className: "b316-review-actions", children: [
6522
- /* @__PURE__ */ jsx35(
6871
+ /* @__PURE__ */ jsx37("div", { className: "b316-review-actions", children: /* @__PURE__ */ jsx37("button", { type: "button", className: "b316-button", onClick: () => void addCard(), children: "Add a card" }) })
6872
+ ] }) : /* @__PURE__ */ jsxs36("div", { className: "b316-review-actions", children: [
6873
+ /* @__PURE__ */ jsx37(
6523
6874
  "button",
6524
6875
  {
6525
6876
  type: "button",
@@ -6529,7 +6880,7 @@ function PlanChangeReview({
6529
6880
  children: busy ? "Working\u2026" : preview.timing === "NOW" ? `Change to ${to.planName} now` : `Schedule ${to.planName}`
6530
6881
  }
6531
6882
  ),
6532
- onCancel ? /* @__PURE__ */ jsxs34("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: [
6883
+ onCancel ? /* @__PURE__ */ jsxs36("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: [
6533
6884
  "Keep ",
6534
6885
  from.planName
6535
6886
  ] }) : null
@@ -6539,7 +6890,7 @@ function PlanChangeReview({
6539
6890
  }
6540
6891
 
6541
6892
  // src/BillingPortal.tsx
6542
- import { Fragment as Fragment12, jsx as jsx36, jsxs as jsxs35 } from "react/jsx-runtime";
6893
+ import { Fragment as Fragment14, jsx as jsx38, jsxs as jsxs37 } from "react/jsx-runtime";
6543
6894
  function BillingPortal({
6544
6895
  returnUrl,
6545
6896
  featuredPlanKey,
@@ -6549,12 +6900,12 @@ function BillingPortal({
6549
6900
  style
6550
6901
  }) {
6551
6902
  const { client, token, loading: sessionLoading } = useBase316();
6552
- const [overview, setOverview] = useState34(null);
6553
- const [failed, setFailed] = useState34(false);
6554
- const [version, setVersion] = useState34(0);
6555
- const [reviewing, setReviewing] = useState34(null);
6556
- const [notice, setNotice] = useState34(null);
6557
- useEffect26(() => {
6903
+ const [overview, setOverview] = useState35(null);
6904
+ const [failed, setFailed] = useState35(false);
6905
+ const [version, setVersion] = useState35(0);
6906
+ const [reviewing, setReviewing] = useState35(null);
6907
+ const [notice, setNotice] = useState35(null);
6908
+ useEffect27(() => {
6558
6909
  if (!token) return;
6559
6910
  let cancelled = false;
6560
6911
  client.billing.subscription(token).then((result) => {
@@ -6577,24 +6928,24 @@ function BillingPortal({
6577
6928
  setNotice(null);
6578
6929
  setVersion((value) => value + 1);
6579
6930
  }, []);
6580
- const shell = (content) => /* @__PURE__ */ jsx36("div", { className: cls("b316-billing-portal", className), style, children: content });
6581
- if (sessionLoading) return shell(/* @__PURE__ */ jsx36("div", { className: "b316-card", children: "Loading\u2026" }));
6582
- if (!token) return shell(/* @__PURE__ */ jsx36("div", { className: "b316-card", children: "Sign in to manage your billing." }));
6931
+ const shell = (content) => /* @__PURE__ */ jsx38("div", { className: cls("b316-billing-portal", className), style, children: content });
6932
+ if (sessionLoading) return shell(/* @__PURE__ */ jsx38("div", { className: "b316-card", children: "Loading\u2026" }));
6933
+ if (!token) return shell(/* @__PURE__ */ jsx38("div", { className: "b316-card", children: "Sign in to manage your billing." }));
6583
6934
  if (failed) {
6584
6935
  return shell(
6585
- /* @__PURE__ */ jsx36("div", { className: "b316-card", children: /* @__PURE__ */ jsx36("div", { className: "b316-error", role: "alert", children: "Could not load your billing." }) })
6936
+ /* @__PURE__ */ jsx38("div", { className: "b316-card", children: /* @__PURE__ */ jsx38("div", { className: "b316-error", role: "alert", children: "Could not load your billing." }) })
6586
6937
  );
6587
6938
  }
6588
- if (!overview) return shell(/* @__PURE__ */ jsx36("div", { className: "b316-card", children: "Loading\u2026" }));
6939
+ if (!overview) return shell(/* @__PURE__ */ jsx38("div", { className: "b316-card", children: "Loading\u2026" }));
6589
6940
  const { subscription, managedBy, quantityPriced } = overview;
6590
6941
  const canChange = Boolean(subscription) && !managedBy;
6591
6942
  return shell(
6592
- /* @__PURE__ */ jsxs35(Fragment12, { children: [
6593
- notice ? /* @__PURE__ */ jsx36("div", { className: "b316-card b316-notice", role: "status", children: notice }) : null,
6594
- /* @__PURE__ */ jsx36(SubscriptionManager, { onChange: refresh }, `plan-${version}`),
6595
- canChange ? /* @__PURE__ */ jsx36(UpcomingInvoice, {}, `next-${version}`) : null,
6596
- canChange && quantityPriced ? /* @__PURE__ */ jsx36(SeatManager, { unitLabel, onChange: refresh }, `seats-${version}`) : null,
6597
- reviewing ? /* @__PURE__ */ jsx36(
6943
+ /* @__PURE__ */ jsxs37(Fragment14, { children: [
6944
+ notice ? /* @__PURE__ */ jsx38("div", { className: "b316-card b316-notice", role: "status", children: notice }) : null,
6945
+ /* @__PURE__ */ jsx38(SubscriptionManager, { onChange: refresh }, `plan-${version}`),
6946
+ canChange ? /* @__PURE__ */ jsx38(UpcomingInvoice, {}, `next-${version}`) : null,
6947
+ canChange && quantityPriced ? /* @__PURE__ */ jsx38(SeatManager, { unitLabel, onChange: refresh }, `seats-${version}`) : null,
6948
+ reviewing ? /* @__PURE__ */ jsx38(
6598
6949
  PlanChangeReview,
6599
6950
  {
6600
6951
  planVersionId: reviewing,
@@ -6607,9 +6958,9 @@ function BillingPortal({
6607
6958
  );
6608
6959
  }
6609
6960
  }
6610
- ) : /* @__PURE__ */ jsxs35("section", { children: [
6611
- /* @__PURE__ */ jsx36("h2", { className: "b316-billing-portal-section-title", children: subscription ? "Change plan" : "Choose a plan" }),
6612
- /* @__PURE__ */ jsx36(
6961
+ ) : /* @__PURE__ */ jsxs37("section", { children: [
6962
+ /* @__PURE__ */ jsx38("h2", { className: "b316-billing-portal-section-title", children: subscription ? "Change plan" : "Choose a plan" }),
6963
+ /* @__PURE__ */ jsx38(
6613
6964
  PricingTable,
6614
6965
  {
6615
6966
  featuredPlanKey,
@@ -6621,17 +6972,17 @@ function BillingPortal({
6621
6972
  `plans-${version}`
6622
6973
  )
6623
6974
  ] }),
6624
- /* @__PURE__ */ jsx36(CreditBalances, {}, `credits-${version}`),
6625
- managedBy ? null : /* @__PURE__ */ jsx36(PaymentMethod, { returnUrl }, `card-${version}`),
6626
- /* @__PURE__ */ jsx36(Invoices, {}, `invoices-${version}`),
6627
- billingDetails === void 0 ? /* @__PURE__ */ jsx36(BillingDetailsForm, {}, `details-${version}`) : billingDetails
6975
+ /* @__PURE__ */ jsx38(CreditBalances, {}, `credits-${version}`),
6976
+ managedBy ? null : /* @__PURE__ */ jsx38(PaymentMethod, { returnUrl }, `card-${version}`),
6977
+ /* @__PURE__ */ jsx38(Invoices, {}, `invoices-${version}`),
6978
+ billingDetails === void 0 ? /* @__PURE__ */ jsx38(BillingDetailsForm, {}, `details-${version}`) : billingDetails
6628
6979
  ] })
6629
6980
  );
6630
6981
  }
6631
6982
 
6632
6983
  // src/ApiKeyManager.tsx
6633
- import { useCallback as useCallback13, useEffect as useEffect27, useState as useState35 } from "react";
6634
- import { jsx as jsx37, jsxs as jsxs36 } from "react/jsx-runtime";
6984
+ import { useCallback as useCallback13, useEffect as useEffect28, useState as useState36 } from "react";
6985
+ import { jsx as jsx39, jsxs as jsxs38 } from "react/jsx-runtime";
6635
6986
  function duration(seconds) {
6636
6987
  if (seconds % 3600 === 0) {
6637
6988
  return `${seconds / 3600}h`;
@@ -6648,16 +6999,16 @@ function ApiKeyManager({
6648
6999
  audience
6649
7000
  }) {
6650
7001
  const { client, token, loading: sessionLoading } = useBase316();
6651
- const [resources, setResources] = useState35([]);
6652
- const [credentials, setCredentials] = useState35([]);
6653
- const [loading, setLoading] = useState35(true);
6654
- const [busy, setBusy] = useState35(false);
6655
- const [error, setError] = useState35(null);
6656
- const [creating, setCreating] = useState35(false);
6657
- const [name, setName] = useState35("");
6658
- const [chosen, setChosen] = useState35([]);
6659
- const [resourceId, setResourceId] = useState35(null);
6660
- const [issued, setIssued] = useState35(null);
7002
+ const [resources, setResources] = useState36([]);
7003
+ const [credentials, setCredentials] = useState36([]);
7004
+ const [loading, setLoading] = useState36(true);
7005
+ const [busy, setBusy] = useState36(false);
7006
+ const [error, setError] = useState36(null);
7007
+ const [creating, setCreating] = useState36(false);
7008
+ const [name, setName] = useState36("");
7009
+ const [chosen, setChosen] = useState36([]);
7010
+ const [resourceId, setResourceId] = useState36(null);
7011
+ const [issued, setIssued] = useState36(null);
6661
7012
  const load = useCallback13(async () => {
6662
7013
  if (!token) {
6663
7014
  setLoading(false);
@@ -6679,20 +7030,20 @@ function ApiKeyManager({
6679
7030
  setLoading(false);
6680
7031
  }
6681
7032
  }, [client, token, audience]);
6682
- useEffect27(() => {
7033
+ useEffect28(() => {
6683
7034
  void load();
6684
7035
  }, [load]);
6685
7036
  if (sessionLoading || loading) {
6686
- return /* @__PURE__ */ jsx37("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
7037
+ return /* @__PURE__ */ jsx39("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
6687
7038
  }
6688
7039
  if (!token) {
6689
- return /* @__PURE__ */ jsx37("div", { className: cls("b316-card", className), style, children: "Sign in to manage your API keys." });
7040
+ return /* @__PURE__ */ jsx39("div", { className: cls("b316-card", className), style, children: "Sign in to manage your API keys." });
6690
7041
  }
6691
7042
  if (error) {
6692
- return /* @__PURE__ */ jsx37("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx37("div", { className: "b316-error", role: "alert", children: error }) });
7043
+ return /* @__PURE__ */ jsx39("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ jsx39("div", { className: "b316-error", role: "alert", children: error }) });
6693
7044
  }
6694
7045
  if (resources.length === 0) {
6695
- return /* @__PURE__ */ jsx37("div", { className: cls("b316-card", className), style, children: "There are no APIs available to your account." });
7046
+ return /* @__PURE__ */ jsx39("div", { className: cls("b316-card", className), style, children: "There are no APIs available to your account." });
6696
7047
  }
6697
7048
  const resource = resources.find((item) => item.id === resourceId) ?? resources[0];
6698
7049
  const reset = () => {
@@ -6701,37 +7052,37 @@ function ApiKeyManager({
6701
7052
  setChosen([]);
6702
7053
  setIssued(null);
6703
7054
  };
6704
- return /* @__PURE__ */ jsxs36("div", { className: cls("b316-card", className), style, children: [
6705
- error ? /* @__PURE__ */ jsx37("div", { className: "b316-error", role: "alert", children: error }) : null,
6706
- resources.length > 1 ? /* @__PURE__ */ jsx37(
7055
+ return /* @__PURE__ */ jsxs38("div", { className: cls("b316-card", className), style, children: [
7056
+ error ? /* @__PURE__ */ jsx39("div", { className: "b316-error", role: "alert", children: error }) : null,
7057
+ resources.length > 1 ? /* @__PURE__ */ jsx39(
6707
7058
  "select",
6708
7059
  {
6709
7060
  className: "b316-input",
6710
7061
  value: resource.id,
6711
7062
  onChange: (event) => setResourceId(event.target.value),
6712
7063
  style: { marginBottom: 14 },
6713
- children: resources.map((item) => /* @__PURE__ */ jsx37("option", { value: item.id, children: item.name }, item.id))
7064
+ children: resources.map((item) => /* @__PURE__ */ jsx39("option", { value: item.id, children: item.name }, item.id))
6714
7065
  }
6715
- ) : /* @__PURE__ */ jsx37("div", { className: "b316-plan-name", children: resource.name }),
6716
- resource.rateLimit ? /* @__PURE__ */ jsxs36("div", { className: "b316-muted", children: [
7066
+ ) : /* @__PURE__ */ jsx39("div", { className: "b316-plan-name", children: resource.name }),
7067
+ resource.rateLimit ? /* @__PURE__ */ jsxs38("div", { className: "b316-muted", children: [
6717
7068
  resource.rateLimit.requestsPerWindow,
6718
7069
  " requests per",
6719
7070
  " ",
6720
7071
  duration(resource.rateLimit.windowSeconds),
6721
7072
  resource.rateLimit.burst > resource.rateLimit.requestsPerWindow ? `, bursting to ${resource.rateLimit.burst}` : null
6722
- ] }) : /* @__PURE__ */ jsx37("div", { className: "b316-muted", children: "No rate limit." }),
6723
- credentials.length === 0 ? /* @__PURE__ */ jsx37("p", { className: "b316-muted", style: { marginTop: 14 }, children: "You have no API keys yet." }) : /* @__PURE__ */ jsx37("ul", { className: "b316-list", style: { marginTop: 14 }, children: credentials.map((credential) => /* @__PURE__ */ jsxs36("li", { className: "b316-list-item", children: [
6724
- /* @__PURE__ */ jsxs36("div", { children: [
6725
- /* @__PURE__ */ jsx37("div", { className: "b316-plan-name", children: credential.name }),
6726
- /* @__PURE__ */ jsxs36("div", { className: "b316-muted", children: [
6727
- /* @__PURE__ */ jsx37("code", { children: credential.clientId }),
7073
+ ] }) : /* @__PURE__ */ jsx39("div", { className: "b316-muted", children: "No rate limit." }),
7074
+ credentials.length === 0 ? /* @__PURE__ */ jsx39("p", { className: "b316-muted", style: { marginTop: 14 }, children: "You have no API keys yet." }) : /* @__PURE__ */ jsx39("ul", { className: "b316-list", style: { marginTop: 14 }, children: credentials.map((credential) => /* @__PURE__ */ jsxs38("li", { className: "b316-list-item", children: [
7075
+ /* @__PURE__ */ jsxs38("div", { children: [
7076
+ /* @__PURE__ */ jsx39("div", { className: "b316-plan-name", children: credential.name }),
7077
+ /* @__PURE__ */ jsxs38("div", { className: "b316-muted", children: [
7078
+ /* @__PURE__ */ jsx39("code", { children: credential.clientId }),
6728
7079
  credential.secretLastFour ? ` \xB7 \u2026${credential.secretLastFour}` : null,
6729
7080
  credential.disabled ? " \xB7 Disabled" : null
6730
7081
  ] }),
6731
- /* @__PURE__ */ jsx37("div", { className: "b316-muted", children: credential.scopes.join(", ") })
7082
+ /* @__PURE__ */ jsx39("div", { className: "b316-muted", children: credential.scopes.join(", ") })
6732
7083
  ] }),
6733
- /* @__PURE__ */ jsxs36("div", { style: { display: "flex", gap: 8 }, children: [
6734
- /* @__PURE__ */ jsx37(
7084
+ /* @__PURE__ */ jsxs38("div", { style: { display: "flex", gap: 8 }, children: [
7085
+ /* @__PURE__ */ jsx39(
6735
7086
  "button",
6736
7087
  {
6737
7088
  type: "button",
@@ -6760,7 +7111,7 @@ function ApiKeyManager({
6760
7111
  children: "Rotate"
6761
7112
  }
6762
7113
  ),
6763
- /* @__PURE__ */ jsx37(
7114
+ /* @__PURE__ */ jsx39(
6764
7115
  ConfirmButton,
6765
7116
  {
6766
7117
  className: "b316-button b316-button-secondary",
@@ -6784,11 +7135,11 @@ function ApiKeyManager({
6784
7135
  )
6785
7136
  ] })
6786
7137
  ] }, credential.clientId)) }),
6787
- issued ? /* @__PURE__ */ jsxs36("div", { className: "b316-notice", style: { marginTop: 14 }, children: [
6788
- /* @__PURE__ */ jsx37("strong", { children: "Copy this now." }),
7138
+ issued ? /* @__PURE__ */ jsxs38("div", { className: "b316-notice", style: { marginTop: 14 }, children: [
7139
+ /* @__PURE__ */ jsx39("strong", { children: "Copy this now." }),
6789
7140
  " It is shown once and cannot be retrieved again.",
6790
- /* @__PURE__ */ jsx37("div", { style: { marginTop: 8 }, children: /* @__PURE__ */ jsx37("code", { style: { wordBreak: "break-all" }, children: issued.secret }) }),
6791
- /* @__PURE__ */ jsx37(
7141
+ /* @__PURE__ */ jsx39("div", { style: { marginTop: 8 }, children: /* @__PURE__ */ jsx39("code", { style: { wordBreak: "break-all" }, children: issued.secret }) }),
7142
+ /* @__PURE__ */ jsx39(
6792
7143
  "button",
6793
7144
  {
6794
7145
  type: "button",
@@ -6801,7 +7152,7 @@ function ApiKeyManager({
6801
7152
  children: "Copy"
6802
7153
  }
6803
7154
  ),
6804
- /* @__PURE__ */ jsx37(
7155
+ /* @__PURE__ */ jsx39(
6805
7156
  "button",
6806
7157
  {
6807
7158
  type: "button",
@@ -6812,8 +7163,8 @@ function ApiKeyManager({
6812
7163
  }
6813
7164
  )
6814
7165
  ] }) : null,
6815
- creating && !issued ? /* @__PURE__ */ jsxs36("div", { style: { marginTop: 14 }, children: [
6816
- /* @__PURE__ */ jsx37(
7166
+ creating && !issued ? /* @__PURE__ */ jsxs38("div", { style: { marginTop: 14 }, children: [
7167
+ /* @__PURE__ */ jsx39(
6817
7168
  "input",
6818
7169
  {
6819
7170
  className: "b316-input",
@@ -6822,9 +7173,9 @@ function ApiKeyManager({
6822
7173
  onChange: (event) => setName(event.target.value)
6823
7174
  }
6824
7175
  ),
6825
- /* @__PURE__ */ jsxs36("div", { style: { marginTop: 10 }, children: [
6826
- resource.availableScopes.map((scope) => /* @__PURE__ */ jsxs36("label", { className: "b316-checkbox", children: [
6827
- /* @__PURE__ */ jsx37(
7176
+ /* @__PURE__ */ jsxs38("div", { style: { marginTop: 10 }, children: [
7177
+ resource.availableScopes.map((scope) => /* @__PURE__ */ jsxs38("label", { className: "b316-checkbox", children: [
7178
+ /* @__PURE__ */ jsx39(
6828
7179
  "input",
6829
7180
  {
6830
7181
  type: "checkbox",
@@ -6834,19 +7185,19 @@ function ApiKeyManager({
6834
7185
  )
6835
7186
  }
6836
7187
  ),
6837
- /* @__PURE__ */ jsx37("code", { children: scope.key }),
6838
- scope.description ? /* @__PURE__ */ jsxs36("span", { className: "b316-muted", children: [
7188
+ /* @__PURE__ */ jsx39("code", { children: scope.key }),
7189
+ scope.description ? /* @__PURE__ */ jsxs38("span", { className: "b316-muted", children: [
6839
7190
  " \u2014 ",
6840
7191
  scope.description
6841
7192
  ] }) : null
6842
7193
  ] }, scope.key)),
6843
- resource.lockedScopes.map((scope) => /* @__PURE__ */ jsxs36("label", { className: "b316-checkbox b316-muted", children: [
6844
- /* @__PURE__ */ jsx37("input", { type: "checkbox", disabled: true }),
6845
- /* @__PURE__ */ jsx37("code", { children: scope.key }),
6846
- /* @__PURE__ */ jsx37("span", { children: " \u2014 not included in your plan" })
7194
+ resource.lockedScopes.map((scope) => /* @__PURE__ */ jsxs38("label", { className: "b316-checkbox b316-muted", children: [
7195
+ /* @__PURE__ */ jsx39("input", { type: "checkbox", disabled: true }),
7196
+ /* @__PURE__ */ jsx39("code", { children: scope.key }),
7197
+ /* @__PURE__ */ jsx39("span", { children: " \u2014 not included in your plan" })
6847
7198
  ] }, scope.key))
6848
7199
  ] }),
6849
- /* @__PURE__ */ jsx37(
7200
+ /* @__PURE__ */ jsx39(
6850
7201
  "button",
6851
7202
  {
6852
7203
  type: "button",
@@ -6880,7 +7231,7 @@ function ApiKeyManager({
6880
7231
  children: "Create key"
6881
7232
  }
6882
7233
  ),
6883
- /* @__PURE__ */ jsx37(
7234
+ /* @__PURE__ */ jsx39(
6884
7235
  "button",
6885
7236
  {
6886
7237
  type: "button",
@@ -6891,7 +7242,7 @@ function ApiKeyManager({
6891
7242
  }
6892
7243
  )
6893
7244
  ] }) : null,
6894
- !creating && !issued ? /* @__PURE__ */ jsx37(
7245
+ !creating && !issued ? /* @__PURE__ */ jsx39(
6895
7246
  "button",
6896
7247
  {
6897
7248
  type: "button",
@@ -6966,26 +7317,45 @@ var MANIFEST = [
6966
7317
  {
6967
7318
  name: "SignIn",
6968
7319
  kind: "component",
6969
- summary: "Password, passkey, magic-link and text-message sign-in in one form.",
7320
+ 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`).",
6970
7321
  useWhen: "The application renders its own sign-in rather than redirecting to the hosted page.",
6971
7322
  requires: [],
6972
7323
  props: [
6973
7324
  { name: "onSignedIn", summary: "Called once a session exists.", required: false },
7325
+ {
7326
+ name: "password",
7327
+ summary: "`false` hides the password form. Every method prop can only turn a method off.",
7328
+ required: false
7329
+ },
6974
7330
  {
6975
7331
  name: "passkeys",
6976
- summary: "Offer passkeys where supported. On by default.",
7332
+ summary: "`false` hides passkeys; otherwise offered where the environment and browser allow.",
6977
7333
  required: false
6978
7334
  },
7335
+ { name: "magicLink", summary: "`false` hides the emailed sign-in link.", required: false },
6979
7336
  {
6980
7337
  name: "magicLinkRedirectUrl",
6981
- summary: "Where an emailed link lands, which must be registered on the environment. Without it, magic link is not offered at all.",
7338
+ 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.",
7339
+ required: false
7340
+ },
7341
+ { name: "phone", summary: "`false` hides text-message codes.", required: false },
7342
+ {
7343
+ name: "social",
7344
+ summary: "`false` hides the social buttons; a list of slugs keeps only those providers.",
6982
7345
  required: false
6983
7346
  },
7347
+ { name: "sso", summary: '`false` hides "Sign in with SSO".', required: false },
6984
7348
  {
6985
- name: "phone",
6986
- 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.",
7349
+ name: "socialRedirectUrl",
7350
+ 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.",
6987
7351
  required: false
6988
7352
  },
7353
+ {
7354
+ name: "socialState",
7355
+ summary: "A short value carried through a social or SSO sign-in, returned by `readOAuthState`.",
7356
+ required: false
7357
+ },
7358
+ { name: "labels", summary: "Wording for the form, for translation.", required: false },
6989
7359
  {
6990
7360
  name: "secondFactorLabels",
6991
7361
  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.",
@@ -6995,6 +7365,38 @@ var MANIFEST = [
6995
7365
  ],
6996
7366
  seeAlso: ["SignUp", "ForgotPassword", "SecondFactorStep"]
6997
7367
  },
7368
+ {
7369
+ name: "SocialSignIn",
7370
+ kind: "component",
7371
+ summary: `The environment's social sign-in buttons alone ("Continue with Google"), for a sign-in or sign-up form you draw yourself.`,
7372
+ useWhen: "Your own form needs the social providers switched on in the dashboard. SignIn and SignUp already include them.",
7373
+ requires: [],
7374
+ props: [
7375
+ {
7376
+ name: "socialRedirectUrl",
7377
+ 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.",
7378
+ required: false
7379
+ },
7380
+ {
7381
+ name: "socialState",
7382
+ summary: "A short value carried through, returned by `readOAuthState`.",
7383
+ required: false
7384
+ },
7385
+ {
7386
+ name: "social",
7387
+ summary: "`false` hides every button; a list of slugs keeps only those providers.",
7388
+ required: false
7389
+ },
7390
+ {
7391
+ name: "intent",
7392
+ summary: "`sign-up` hides the buttons when the environment is closed to new accounts.",
7393
+ required: false
7394
+ },
7395
+ { name: "divider", summary: 'Draw an "or" rule under the buttons.', required: false },
7396
+ { name: "labels", summary: "`continueWith` and `or`, for translation.", required: false }
7397
+ ],
7398
+ seeAlso: ["SignIn", "SignUp"]
7399
+ },
6998
7400
  {
6999
7401
  name: "SignUp",
7000
7402
  kind: "component",
@@ -7023,6 +7425,21 @@ var MANIFEST = [
7023
7425
  summary: "Wording for the second-factor step, for translation.",
7024
7426
  required: false
7025
7427
  },
7428
+ {
7429
+ name: "social",
7430
+ summary: "`false` hides the social buttons; a list of slugs keeps only those providers.",
7431
+ required: false
7432
+ },
7433
+ {
7434
+ name: "socialRedirectUrl",
7435
+ summary: "Where a social sign-up returns with `?code=&state=`, as on SignIn. Without it no social button is shown.",
7436
+ required: false
7437
+ },
7438
+ {
7439
+ name: "socialState",
7440
+ summary: "A short value carried through a social sign-up, returned by `readOAuthState`.",
7441
+ required: false
7442
+ },
7026
7443
  ...appearance
7027
7444
  ],
7028
7445
  seeAlso: ["SignIn", "VerifyEmail", "SecondFactorStep"]
@@ -7794,6 +8211,7 @@ export {
7794
8211
  SecondFactorStep,
7795
8212
  SignIn,
7796
8213
  SignUp,
8214
+ SocialSignIn,
7797
8215
  SubscriptionManager,
7798
8216
  TeamMembers,
7799
8217
  TwoFactorManager,