@elvix.is/sdk 0.5.2 → 0.5.4
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/react.d.ts +44 -31
- package/dist/react.js +376 -172
- package/package.json +2 -2
package/dist/react.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { ElvixActionResult } from './index.js';
|
|
4
4
|
export { ElvixUser, ElvixVerifyResult } from './index.js';
|
|
@@ -18,7 +18,7 @@ declare function ElvixCard({ title, footer, className, children, }: {
|
|
|
18
18
|
footer?: ReactNode;
|
|
19
19
|
className?: string;
|
|
20
20
|
children: ReactNode;
|
|
21
|
-
}):
|
|
21
|
+
}): react_jsx_runtime.JSX.Element;
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Editable sign-in copy.
|
|
@@ -84,6 +84,12 @@ type ElvixBrand = {
|
|
|
84
84
|
};
|
|
85
85
|
};
|
|
86
86
|
type ElvixSignInMethod = "google" | "email_otp" | "passkey" | "username";
|
|
87
|
+
/**
|
|
88
|
+
* The public render envelope `GET /api/v1/bootstrap/<clientId>` returns. Flat
|
|
89
|
+
* to match the wire shape exactly (the provider builds the {light,dark} brand
|
|
90
|
+
* chord from the colour fields). Any field here is already public — it's what
|
|
91
|
+
* the sign-in surface shows.
|
|
92
|
+
*/
|
|
87
93
|
type ElvixBootstrapEnvelope = {
|
|
88
94
|
applicationId: string;
|
|
89
95
|
clientId: string;
|
|
@@ -93,21 +99,28 @@ type ElvixBootstrapEnvelope = {
|
|
|
93
99
|
logoUrlDark: string | null;
|
|
94
100
|
iconUrl: string | null;
|
|
95
101
|
iconUrlDark: string | null;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
websiteUrl: string | null;
|
|
103
|
+
privacyPolicyUrl: string;
|
|
104
|
+
termsOfServiceUrl: string;
|
|
105
|
+
supportUrl: string | null;
|
|
106
|
+
brandColor: string;
|
|
107
|
+
brandColorDark: string | null;
|
|
108
|
+
onBrandColor: string;
|
|
109
|
+
onBrandColorDark: string | null;
|
|
110
|
+
brandPreset: string;
|
|
111
|
+
methodGoogle: boolean;
|
|
112
|
+
methodEmailOtp: boolean;
|
|
113
|
+
methodPasskey: boolean;
|
|
114
|
+
methodUsername: boolean;
|
|
115
|
+
layout: string;
|
|
116
|
+
socialLayout: string;
|
|
117
|
+
presentation: string;
|
|
118
|
+
theme: "light" | "dark" | "system";
|
|
119
|
+
showHeader: boolean;
|
|
120
|
+
transparentBg: boolean;
|
|
109
121
|
signInVerb: "signin" | "login";
|
|
110
122
|
signinGate: "public" | "private_beta" | "closed";
|
|
123
|
+
archivedAt: string | null;
|
|
111
124
|
/**
|
|
112
125
|
* Console-configured sign-in copy overrides. Any subset of the strings the
|
|
113
126
|
* sign-in surface renders; missing keys fall back to the built-in English
|
|
@@ -154,7 +167,7 @@ declare function ElvixProvider({ clientId, theme, brand, baseUrl, children, clas
|
|
|
154
167
|
baseUrl?: string;
|
|
155
168
|
children: ReactNode;
|
|
156
169
|
className?: string;
|
|
157
|
-
}):
|
|
170
|
+
}): react_jsx_runtime.JSX.Element;
|
|
158
171
|
|
|
159
172
|
/**
|
|
160
173
|
* `<ElvixSignIn>` — drop-in sign-in surface.
|
|
@@ -184,7 +197,7 @@ declare function ElvixSignIn({ onResult, redirectAfterSignIn, copy: copyProp, cl
|
|
|
184
197
|
*/
|
|
185
198
|
copy?: Partial<ElvixCopy>;
|
|
186
199
|
className?: string;
|
|
187
|
-
}):
|
|
200
|
+
}): react_jsx_runtime.JSX.Element;
|
|
188
201
|
|
|
189
202
|
type ElvixSignInButtonSize = "sm" | "md" | "lg";
|
|
190
203
|
type ElvixSignInButtonTheme = "light" | "dark" | "auto";
|
|
@@ -212,7 +225,7 @@ type ElvixSignInButtonProps = {
|
|
|
212
225
|
/** Terminal outcome of mode="embed": success (with token) or error. */
|
|
213
226
|
onResult?: (result: ElvixSignInResult) => void;
|
|
214
227
|
};
|
|
215
|
-
declare function ElvixSignInButton({ clientId, baseUrl, returnUrl, type, variant, shape, size, theme, preset, label, className, href, mode, onClick, onResult, }: ElvixSignInButtonProps):
|
|
228
|
+
declare function ElvixSignInButton({ clientId, baseUrl, returnUrl, type, variant, shape, size, theme, preset, label, className, href, mode, onClick, onResult, }: ElvixSignInButtonProps): react_jsx_runtime.JSX.Element;
|
|
216
229
|
|
|
217
230
|
type ElvixSecuredBadgeVariant = "white" | "dark" | "outline";
|
|
218
231
|
type ElvixSecuredBadgeSize = "sm" | "md" | "lg";
|
|
@@ -228,7 +241,7 @@ type ElvixSecuredBadgeProps = {
|
|
|
228
241
|
href?: string;
|
|
229
242
|
className?: string;
|
|
230
243
|
};
|
|
231
|
-
declare function ElvixSecuredBadge({ variant, size, theme, accentColor, href, className, }: ElvixSecuredBadgeProps):
|
|
244
|
+
declare function ElvixSecuredBadge({ variant, size, theme, accentColor, href, className, }: ElvixSecuredBadgeProps): react_jsx_runtime.JSX.Element;
|
|
232
245
|
|
|
233
246
|
/**
|
|
234
247
|
* Session token store for cross-origin SDK use.
|
|
@@ -281,7 +294,7 @@ declare function ElvixUsername({ onResult, }: {
|
|
|
281
294
|
onResult?: (r: ElvixActionResult<{
|
|
282
295
|
username: string;
|
|
283
296
|
}>) => void;
|
|
284
|
-
}):
|
|
297
|
+
}): react_jsx_runtime.JSX.Element;
|
|
285
298
|
|
|
286
299
|
/**
|
|
287
300
|
* `<ElvixAvatar>` — upload / replace the end-user's avatar for this
|
|
@@ -291,7 +304,7 @@ declare function ElvixAvatar({ onResult, }: {
|
|
|
291
304
|
onResult?: (r: ElvixActionResult<{
|
|
292
305
|
avatarUrl: string;
|
|
293
306
|
}>) => void;
|
|
294
|
-
}):
|
|
307
|
+
}): react_jsx_runtime.JSX.Element;
|
|
295
308
|
|
|
296
309
|
/**
|
|
297
310
|
* `<ElvixBanner>` — upload / replace the end-user's profile banner
|
|
@@ -301,7 +314,7 @@ declare function ElvixBanner({ onResult, }: {
|
|
|
301
314
|
onResult?: (r: ElvixActionResult<{
|
|
302
315
|
bannerUrl: string;
|
|
303
316
|
}>) => void;
|
|
304
|
-
}):
|
|
317
|
+
}): react_jsx_runtime.JSX.Element;
|
|
305
318
|
|
|
306
319
|
/**
|
|
307
320
|
* `<ElvixIdentityForm>` — edit the end-user's display name + bio for
|
|
@@ -314,7 +327,7 @@ declare function ElvixIdentityForm({ initialName, initialBio, onResult, }: {
|
|
|
314
327
|
name: string;
|
|
315
328
|
bio: string;
|
|
316
329
|
}>) => void;
|
|
317
|
-
}):
|
|
330
|
+
}): react_jsx_runtime.JSX.Element;
|
|
318
331
|
|
|
319
332
|
/**
|
|
320
333
|
* `<ElvixRegion>` — set the end-user's region (ISO 3166-1 alpha-2
|
|
@@ -328,7 +341,7 @@ declare function ElvixRegion({ initialCountry, initialTimezone, onResult, }: {
|
|
|
328
341
|
country: string;
|
|
329
342
|
timezone: string;
|
|
330
343
|
}>) => void;
|
|
331
|
-
}):
|
|
344
|
+
}): react_jsx_runtime.JSX.Element;
|
|
332
345
|
|
|
333
346
|
/**
|
|
334
347
|
* `<ElvixLanguages>` — set the end-user's preferred languages (BCP-47
|
|
@@ -339,13 +352,13 @@ declare function ElvixLanguages({ initial, onResult, }: {
|
|
|
339
352
|
onResult?: (r: ElvixActionResult<{
|
|
340
353
|
languages: string[];
|
|
341
354
|
}>) => void;
|
|
342
|
-
}):
|
|
355
|
+
}): react_jsx_runtime.JSX.Element;
|
|
343
356
|
|
|
344
357
|
declare function ElvixSessions({ onResult, }: {
|
|
345
358
|
onResult?: (r: ElvixActionResult<{
|
|
346
359
|
revoked: number;
|
|
347
360
|
}>) => void;
|
|
348
|
-
}):
|
|
361
|
+
}): react_jsx_runtime.JSX.Element;
|
|
349
362
|
|
|
350
363
|
/**
|
|
351
364
|
* `<ElvixExport>` — GDPR Art. 15 data-export request. Triggers an
|
|
@@ -356,15 +369,15 @@ declare function ElvixExport({ onResult, }: {
|
|
|
356
369
|
onResult?: (r: ElvixActionResult<{
|
|
357
370
|
requestId: string;
|
|
358
371
|
}>) => void;
|
|
359
|
-
}):
|
|
372
|
+
}): react_jsx_runtime.JSX.Element;
|
|
360
373
|
|
|
361
374
|
declare function ElvixDeactivate({ onResult, }: {
|
|
362
375
|
onResult?: (r: ElvixActionResult) => void;
|
|
363
|
-
}):
|
|
376
|
+
}): react_jsx_runtime.JSX.Element;
|
|
364
377
|
|
|
365
378
|
declare function ElvixLeave({ onResult, }: {
|
|
366
379
|
onResult?: (r: ElvixActionResult) => void;
|
|
367
|
-
}):
|
|
380
|
+
}): react_jsx_runtime.JSX.Element;
|
|
368
381
|
|
|
369
382
|
/**
|
|
370
383
|
* `<ElvixAddressBook>` — list / add / remove the end-user's addresses
|
|
@@ -373,7 +386,7 @@ declare function ElvixLeave({ onResult, }: {
|
|
|
373
386
|
*/
|
|
374
387
|
declare function ElvixAddressBook({ onResult, }: {
|
|
375
388
|
onResult?: (r: ElvixActionResult) => void;
|
|
376
|
-
}):
|
|
389
|
+
}): react_jsx_runtime.JSX.Element;
|
|
377
390
|
|
|
378
391
|
/**
|
|
379
392
|
* `<ElvixLegalEntities>` — list / add / remove the end-user's legal
|
|
@@ -382,6 +395,6 @@ declare function ElvixAddressBook({ onResult, }: {
|
|
|
382
395
|
*/
|
|
383
396
|
declare function ElvixLegalEntities({ onResult, }: {
|
|
384
397
|
onResult?: (r: ElvixActionResult) => void;
|
|
385
|
-
}):
|
|
398
|
+
}): react_jsx_runtime.JSX.Element;
|
|
386
399
|
|
|
387
400
|
export { DEFAULT_COPY, ElvixActionResult, ElvixAddressBook, ElvixAvatar, ElvixBanner, type ElvixBootstrapEnvelope, type ElvixBrand, ElvixCard, type ElvixCopy, ElvixDeactivate, ElvixExport, ElvixIdentityForm, ElvixLanguages, ElvixLeave, ElvixLegalEntities, ElvixLifecycleWatcher, ElvixProvider, ElvixRegion, ElvixSecuredBadge, ElvixSessions, ElvixSignIn, ElvixSignInButton, type ElvixSignInMethod, type ElvixSignInResult, type ElvixSignInResultErr, type ElvixSignInResultOk, type ElvixTheme, ElvixUsername, type UseUserListResult, getElvixToken, setElvixToken, useElvixApp, useElvixContext, useUserMemberships, useUserRoles, useUserScopes };
|
package/dist/react.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
// src/react/elvix-card.tsx
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
4
|
function ElvixCard({
|
|
3
5
|
title,
|
|
4
6
|
footer,
|
|
5
7
|
className = "",
|
|
6
8
|
children
|
|
7
9
|
}) {
|
|
8
|
-
return /* @__PURE__ */
|
|
10
|
+
return /* @__PURE__ */ jsxs(
|
|
9
11
|
"div",
|
|
10
12
|
{
|
|
11
13
|
className: `elvix-card ${className}`.trim(),
|
|
@@ -18,34 +20,36 @@ function ElvixCard({
|
|
|
18
20
|
flexDirection: "column",
|
|
19
21
|
maxWidth: "440px",
|
|
20
22
|
width: "100%"
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
title && /* @__PURE__ */ React.createElement(
|
|
24
|
-
"div",
|
|
25
|
-
{
|
|
26
|
-
style: {
|
|
27
|
-
padding: "20px 24px 0",
|
|
28
|
-
fontSize: "16px",
|
|
29
|
-
fontWeight: 600,
|
|
30
|
-
color: "var(--elvix-primary-strong, #5d4dff)"
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
title
|
|
34
|
-
),
|
|
35
|
-
/* @__PURE__ */ React.createElement("div", { style: { padding: "16px 24px", flex: 1 } }, children),
|
|
36
|
-
footer && /* @__PURE__ */ React.createElement(
|
|
37
|
-
"div",
|
|
38
|
-
{
|
|
39
|
-
style: {
|
|
40
|
-
padding: "12px 24px",
|
|
41
|
-
borderTop: "1px solid var(--elvix-primary-12, rgba(93,77,255,0.12))",
|
|
42
|
-
background: "rgba(0,0,0,0.02)",
|
|
43
|
-
fontSize: "12px",
|
|
44
|
-
color: "rgba(0,0,0,0.55)"
|
|
45
|
-
}
|
|
46
23
|
},
|
|
47
|
-
|
|
48
|
-
|
|
24
|
+
children: [
|
|
25
|
+
title && /* @__PURE__ */ jsx(
|
|
26
|
+
"div",
|
|
27
|
+
{
|
|
28
|
+
style: {
|
|
29
|
+
padding: "20px 24px 0",
|
|
30
|
+
fontSize: "16px",
|
|
31
|
+
fontWeight: 600,
|
|
32
|
+
color: "var(--elvix-primary-strong, #5d4dff)"
|
|
33
|
+
},
|
|
34
|
+
children: title
|
|
35
|
+
}
|
|
36
|
+
),
|
|
37
|
+
/* @__PURE__ */ jsx("div", { style: { padding: "16px 24px", flex: 1 }, children }),
|
|
38
|
+
footer && /* @__PURE__ */ jsx(
|
|
39
|
+
"div",
|
|
40
|
+
{
|
|
41
|
+
style: {
|
|
42
|
+
padding: "12px 24px",
|
|
43
|
+
borderTop: "1px solid var(--elvix-primary-12, rgba(93,77,255,0.12))",
|
|
44
|
+
background: "rgba(0,0,0,0.02)",
|
|
45
|
+
fontSize: "12px",
|
|
46
|
+
color: "rgba(0,0,0,0.55)"
|
|
47
|
+
},
|
|
48
|
+
children: footer
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
]
|
|
52
|
+
}
|
|
49
53
|
);
|
|
50
54
|
}
|
|
51
55
|
|
|
@@ -57,6 +61,7 @@ import {
|
|
|
57
61
|
useMemo,
|
|
58
62
|
useState
|
|
59
63
|
} from "react";
|
|
64
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
60
65
|
var ELVIX_DEFAULT_BRAND = {
|
|
61
66
|
light: { primary: "#5d4dff", on: "#ffffff" },
|
|
62
67
|
dark: { primary: "#8e7dff", on: "#0a0a0b" }
|
|
@@ -140,19 +145,25 @@ function ElvixProvider({
|
|
|
140
145
|
appError,
|
|
141
146
|
resolvedTheme: effectiveTheme
|
|
142
147
|
};
|
|
143
|
-
return /* @__PURE__ */
|
|
148
|
+
return /* @__PURE__ */ jsx2(ElvixContext.Provider, { value, children: /* @__PURE__ */ jsx2(
|
|
144
149
|
"div",
|
|
145
150
|
{
|
|
146
151
|
"data-elvix-theme": effectiveTheme,
|
|
147
152
|
style: cssVars,
|
|
148
|
-
className: (effectiveTheme === "dark" ? "dark " : "") + "elvix-sdk-root " + className
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
));
|
|
153
|
+
className: (effectiveTheme === "dark" ? "dark " : "") + "elvix-sdk-root " + className,
|
|
154
|
+
children
|
|
155
|
+
}
|
|
156
|
+
) });
|
|
152
157
|
}
|
|
153
158
|
function appBrand(app) {
|
|
154
|
-
if (!app?.
|
|
155
|
-
return
|
|
159
|
+
if (!app?.brandColor) return null;
|
|
160
|
+
return {
|
|
161
|
+
light: { primary: app.brandColor, on: app.onBrandColor },
|
|
162
|
+
dark: {
|
|
163
|
+
primary: app.brandColorDark ?? app.brandColor,
|
|
164
|
+
on: app.onBrandColorDark ?? app.onBrandColor
|
|
165
|
+
}
|
|
166
|
+
};
|
|
156
167
|
}
|
|
157
168
|
function withAlpha(hex, a) {
|
|
158
169
|
const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim());
|
|
@@ -240,6 +251,7 @@ function isSameOrigin(baseUrl) {
|
|
|
240
251
|
}
|
|
241
252
|
|
|
242
253
|
// src/react/elvix-sign-in.tsx
|
|
254
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
243
255
|
function ElvixSignIn({
|
|
244
256
|
onResult,
|
|
245
257
|
redirectAfterSignIn,
|
|
@@ -330,66 +342,87 @@ function ElvixSignIn({
|
|
|
330
342
|
}
|
|
331
343
|
const card = `elvix-card ${className}`.trim();
|
|
332
344
|
if (step === "done") {
|
|
333
|
-
return /* @__PURE__ */
|
|
345
|
+
return /* @__PURE__ */ jsx3("div", { className: card, "data-elvix-pane": "done", children: /* @__PURE__ */ jsx3("p", { children: copy.signedInText }) });
|
|
334
346
|
}
|
|
335
|
-
return /* @__PURE__ */
|
|
336
|
-
"
|
|
337
|
-
{
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
347
|
+
return /* @__PURE__ */ jsxs2("div", { className: card, "data-elvix-pane": step, children: [
|
|
348
|
+
/* @__PURE__ */ jsx3("h2", { className: "elvix-h", children: title }),
|
|
349
|
+
copy.subtitle && /* @__PURE__ */ jsx3("p", { className: "elvix-muted elvix-subtitle", children: copy.subtitle }),
|
|
350
|
+
step === "identify" && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
351
|
+
app?.methodGoogle && /* @__PURE__ */ jsx3(
|
|
352
|
+
"button",
|
|
353
|
+
{
|
|
354
|
+
type: "button",
|
|
355
|
+
onClick: startGoogle,
|
|
356
|
+
disabled: busy,
|
|
357
|
+
className: "elvix-btn elvix-btn-google",
|
|
358
|
+
"data-elvix-method": "google",
|
|
359
|
+
children: copy.googleButton
|
|
360
|
+
}
|
|
361
|
+
),
|
|
362
|
+
app?.methodEmailOtp && /* @__PURE__ */ jsxs2("form", { onSubmit: startOtp, "data-elvix-method": "email_otp", className: "elvix-otp-form", children: [
|
|
363
|
+
/* @__PURE__ */ jsx3(
|
|
364
|
+
"input",
|
|
365
|
+
{
|
|
366
|
+
type: "email",
|
|
367
|
+
value: email,
|
|
368
|
+
onChange: (ev) => setEmail(ev.target.value),
|
|
369
|
+
placeholder: copy.emailPlaceholder,
|
|
370
|
+
required: true,
|
|
371
|
+
disabled: busy,
|
|
372
|
+
className: "elvix-input"
|
|
373
|
+
}
|
|
374
|
+
),
|
|
375
|
+
/* @__PURE__ */ jsx3("button", { type: "submit", disabled: busy, className: "elvix-btn elvix-btn-primary", children: busy ? copy.sendingLabel : copy.sendCodeButton })
|
|
376
|
+
] })
|
|
377
|
+
] }),
|
|
378
|
+
step === "code" && /* @__PURE__ */ jsxs2("form", { onSubmit: verifyOtp, className: "elvix-otp-form", children: [
|
|
379
|
+
/* @__PURE__ */ jsx3("p", { className: "elvix-muted", children: fillCopy(copy.codeSentSubtitle ?? "", { email }) }),
|
|
380
|
+
/* @__PURE__ */ jsx3(
|
|
381
|
+
"input",
|
|
382
|
+
{
|
|
383
|
+
type: "text",
|
|
384
|
+
inputMode: "numeric",
|
|
385
|
+
pattern: "[0-9]*",
|
|
386
|
+
maxLength: 6,
|
|
387
|
+
value: code,
|
|
388
|
+
onChange: (ev) => setCode(ev.target.value.replace(/\D/g, "")),
|
|
389
|
+
placeholder: copy.codePlaceholder,
|
|
390
|
+
required: true,
|
|
391
|
+
disabled: busy,
|
|
392
|
+
className: "elvix-input"
|
|
393
|
+
}
|
|
394
|
+
),
|
|
395
|
+
/* @__PURE__ */ jsx3("button", { type: "submit", disabled: busy, className: "elvix-btn elvix-btn-primary", children: busy ? copy.verifyingLabel : submitLabel })
|
|
396
|
+
] }),
|
|
397
|
+
error && /* @__PURE__ */ jsx3("p", { role: "alert", className: "elvix-error", children: error })
|
|
398
|
+
] });
|
|
371
399
|
}
|
|
372
400
|
|
|
373
401
|
// src/react/elvix-sign-in-button.tsx
|
|
374
402
|
import { useState as useState3 } from "react";
|
|
375
403
|
|
|
376
404
|
// src/react/elvix-shield.tsx
|
|
405
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
377
406
|
function ElvixShield({
|
|
378
407
|
size,
|
|
379
408
|
fill,
|
|
380
409
|
accent
|
|
381
410
|
}) {
|
|
382
|
-
return /* @__PURE__ */
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
411
|
+
return /* @__PURE__ */ jsxs3("svg", { width: size, height: size, viewBox: "2 2 20 20", "aria-hidden": true, style: { display: "block" }, children: [
|
|
412
|
+
/* @__PURE__ */ jsx4(
|
|
413
|
+
"path",
|
|
414
|
+
{
|
|
415
|
+
fill,
|
|
416
|
+
fillRule: "evenodd",
|
|
417
|
+
d: "M 6 2.5 C 4.34 2.5 3 3.84 3 5.5 L 3 12.5 C 3 17.5 7 20.7 12 22 C 17 20.7 21 17.5 21 12.5 L 21 5.5 C 21 3.84 19.66 2.5 18 2.5 L 6 2.5 Z M 12 8.4 C 9.79 8.4 8 10.19 8 12.4 C 8 14.61 9.79 16.4 12 16.4 C 13.21 16.4 14.3 15.86 15.04 15 L 13.6 13.77 C 13.21 14.23 12.64 14.5 12 14.5 C 11.04 14.5 10.21 13.86 9.91 13 L 15.95 13 C 15.98 12.8 16 12.6 16 12.4 C 16 10.19 14.21 8.4 12 8.4 Z M 9.91 11.8 L 14.09 11.8 C 13.79 10.94 12.96 10.3 12 10.3 C 11.04 10.3 10.21 10.94 9.91 11.8 Z"
|
|
418
|
+
}
|
|
419
|
+
),
|
|
420
|
+
/* @__PURE__ */ jsx4("circle", { cx: "19.5", cy: "4.5", r: "2.4", fill: accent })
|
|
421
|
+
] });
|
|
390
422
|
}
|
|
391
423
|
|
|
392
424
|
// src/react/elvix-sign-in-button.tsx
|
|
425
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
393
426
|
var ELVIX_URL = "https://elvix.is";
|
|
394
427
|
var PRESET_LABEL = {
|
|
395
428
|
"sign-in-with-elvix": "Sign in with elvix",
|
|
@@ -467,29 +500,35 @@ function ElvixSignInButton({
|
|
|
467
500
|
transition: "background 0.15s, border-color 0.15s",
|
|
468
501
|
...isIcon ? { height: SIZE_ICON[size], width: SIZE_ICON[size] } : { height: std.height, paddingLeft: std.padX, paddingRight: std.padX, gap: std.gap }
|
|
469
502
|
};
|
|
470
|
-
const content = /* @__PURE__ */
|
|
503
|
+
const content = /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
504
|
+
/* @__PURE__ */ jsx5(ElvixShield, { size: ICON_SIZE[size], fill: shieldColor(variant, theme), accent: "#8e7dff" }),
|
|
505
|
+
isIcon ? null : /* @__PURE__ */ jsx5("span", { children: resolvedLabel })
|
|
506
|
+
] });
|
|
471
507
|
if (mode === "callback") {
|
|
472
|
-
return /* @__PURE__ */
|
|
508
|
+
return /* @__PURE__ */ jsx5("button", { type: "button", onClick, className, style, "aria-label": isIcon ? resolvedLabel : void 0, children: content });
|
|
473
509
|
}
|
|
474
510
|
if (mode === "embed") {
|
|
475
|
-
return /* @__PURE__ */
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
), embedOpen && /* @__PURE__ */ React.createElement(
|
|
486
|
-
ElvixSignIn,
|
|
487
|
-
{
|
|
488
|
-
onResult: (r) => {
|
|
489
|
-
onResult?.(r);
|
|
511
|
+
return /* @__PURE__ */ jsxs4("div", { "data-elvix-signin-button-embed": "", children: [
|
|
512
|
+
!embedOpen && /* @__PURE__ */ jsx5(
|
|
513
|
+
"button",
|
|
514
|
+
{
|
|
515
|
+
type: "button",
|
|
516
|
+
onClick: () => setEmbedOpen(true),
|
|
517
|
+
className,
|
|
518
|
+
style,
|
|
519
|
+
"aria-label": isIcon ? resolvedLabel : void 0,
|
|
520
|
+
children: content
|
|
490
521
|
}
|
|
491
|
-
|
|
492
|
-
|
|
522
|
+
),
|
|
523
|
+
embedOpen && /* @__PURE__ */ jsx5(
|
|
524
|
+
ElvixSignIn,
|
|
525
|
+
{
|
|
526
|
+
onResult: (r) => {
|
|
527
|
+
onResult?.(r);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
)
|
|
531
|
+
] });
|
|
493
532
|
}
|
|
494
533
|
const destination = (() => {
|
|
495
534
|
if (href) return href;
|
|
@@ -498,10 +537,11 @@ function ElvixSignInButton({
|
|
|
498
537
|
const sep = base.includes("?") ? "&" : "?";
|
|
499
538
|
return `${base}${sep}return=${encodeURIComponent(returnUrl)}`;
|
|
500
539
|
})();
|
|
501
|
-
return /* @__PURE__ */
|
|
540
|
+
return /* @__PURE__ */ jsx5("a", { href: destination, className, style, "aria-label": isIcon ? resolvedLabel : void 0, children: content });
|
|
502
541
|
}
|
|
503
542
|
|
|
504
543
|
// src/react/elvix-secured-badge.tsx
|
|
544
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
505
545
|
var ELVIX_URL2 = "https://elvix.is";
|
|
506
546
|
var SIZE = {
|
|
507
547
|
sm: { height: 28, padX: 10, font: 11.5, icon: 14, gap: 6 },
|
|
@@ -549,7 +589,7 @@ function ElvixSecuredBadge({
|
|
|
549
589
|
userSelect: "none",
|
|
550
590
|
lineHeight: 1
|
|
551
591
|
};
|
|
552
|
-
return /* @__PURE__ */
|
|
592
|
+
return /* @__PURE__ */ jsxs5(
|
|
553
593
|
"a",
|
|
554
594
|
{
|
|
555
595
|
href,
|
|
@@ -557,10 +597,15 @@ function ElvixSecuredBadge({
|
|
|
557
597
|
rel: "noopener noreferrer",
|
|
558
598
|
className,
|
|
559
599
|
style,
|
|
560
|
-
"data-elvix-secured-badge": ""
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
600
|
+
"data-elvix-secured-badge": "",
|
|
601
|
+
children: [
|
|
602
|
+
/* @__PURE__ */ jsx6(ElvixShield, { size: s.icon, fill: t.shield, accent: accentColor }),
|
|
603
|
+
/* @__PURE__ */ jsxs5("span", { style: { display: "inline-flex", alignItems: "baseline", gap: 4 }, children: [
|
|
604
|
+
/* @__PURE__ */ jsx6("span", { style: { color: t.lead }, children: "Secured by" }),
|
|
605
|
+
/* @__PURE__ */ jsx6("span", { style: { color: t.brand, fontWeight: 600 }, children: "elvix" })
|
|
606
|
+
] })
|
|
607
|
+
]
|
|
608
|
+
}
|
|
564
609
|
);
|
|
565
610
|
}
|
|
566
611
|
|
|
@@ -696,6 +741,7 @@ async function appDelete(opts, path) {
|
|
|
696
741
|
}
|
|
697
742
|
|
|
698
743
|
// src/react/elvix-username.tsx
|
|
744
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
699
745
|
function ElvixUsername({
|
|
700
746
|
onResult
|
|
701
747
|
}) {
|
|
@@ -723,25 +769,37 @@ function ElvixUsername({
|
|
|
723
769
|
onResult?.(result);
|
|
724
770
|
}
|
|
725
771
|
if (done) {
|
|
726
|
-
return /* @__PURE__ */
|
|
772
|
+
return /* @__PURE__ */ jsx7(ElvixCard, { title: "Username saved", children: /* @__PURE__ */ jsxs6("p", { children: [
|
|
773
|
+
"You are now ",
|
|
774
|
+
/* @__PURE__ */ jsxs6("strong", { children: [
|
|
775
|
+
"@",
|
|
776
|
+
done
|
|
777
|
+
] }),
|
|
778
|
+
"."
|
|
779
|
+
] }) });
|
|
727
780
|
}
|
|
728
|
-
return /* @__PURE__ */
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
781
|
+
return /* @__PURE__ */ jsx7(ElvixCard, { title: "Choose a username", children: /* @__PURE__ */ jsxs6("form", { onSubmit: submit, className: "elvix-form", children: [
|
|
782
|
+
/* @__PURE__ */ jsx7(
|
|
783
|
+
"input",
|
|
784
|
+
{
|
|
785
|
+
type: "text",
|
|
786
|
+
value,
|
|
787
|
+
onChange: (e) => setValue(e.target.value.toLowerCase()),
|
|
788
|
+
placeholder: "alice",
|
|
789
|
+
pattern: "[a-z][a-z0-9._]{2,28}[a-z0-9]",
|
|
790
|
+
required: true,
|
|
791
|
+
disabled: busy,
|
|
792
|
+
className: "elvix-input"
|
|
793
|
+
}
|
|
794
|
+
),
|
|
795
|
+
/* @__PURE__ */ jsx7("button", { type: "submit", disabled: busy || value.length < 4, className: "elvix-btn elvix-btn-primary", children: busy ? "Saving\u2026" : "Claim" }),
|
|
796
|
+
error && /* @__PURE__ */ jsx7("p", { role: "alert", className: "elvix-error", children: error })
|
|
797
|
+
] }) });
|
|
741
798
|
}
|
|
742
799
|
|
|
743
800
|
// src/react/elvix-avatar.tsx
|
|
744
801
|
import { useState as useState6 } from "react";
|
|
802
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
745
803
|
function ElvixAvatar({
|
|
746
804
|
onResult
|
|
747
805
|
}) {
|
|
@@ -771,18 +829,24 @@ function ElvixAvatar({
|
|
|
771
829
|
if (!result.ok) setError(result.error);
|
|
772
830
|
onResult?.(result);
|
|
773
831
|
}
|
|
774
|
-
return /* @__PURE__ */
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
832
|
+
return /* @__PURE__ */ jsxs7(ElvixCard, { title: "Avatar", children: [
|
|
833
|
+
preview && /* @__PURE__ */ jsx8(
|
|
834
|
+
"img",
|
|
835
|
+
{
|
|
836
|
+
src: preview,
|
|
837
|
+
alt: "avatar preview",
|
|
838
|
+
style: { width: 96, height: 96, borderRadius: "50%", objectFit: "cover", marginBottom: 12 }
|
|
839
|
+
}
|
|
840
|
+
),
|
|
841
|
+
/* @__PURE__ */ jsx8("input", { type: "file", accept: "image/png,image/jpeg,image/webp", onChange: onFile, disabled: busy }),
|
|
842
|
+
busy && /* @__PURE__ */ jsx8("p", { children: "Uploading\u2026" }),
|
|
843
|
+
error && /* @__PURE__ */ jsx8("p", { role: "alert", className: "elvix-error", children: error })
|
|
844
|
+
] });
|
|
782
845
|
}
|
|
783
846
|
|
|
784
847
|
// src/react/elvix-banner.tsx
|
|
785
848
|
import { useState as useState7 } from "react";
|
|
849
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
786
850
|
function ElvixBanner({
|
|
787
851
|
onResult
|
|
788
852
|
}) {
|
|
@@ -812,18 +876,24 @@ function ElvixBanner({
|
|
|
812
876
|
if (!result.ok) setError(result.error);
|
|
813
877
|
onResult?.(result);
|
|
814
878
|
}
|
|
815
|
-
return /* @__PURE__ */
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
879
|
+
return /* @__PURE__ */ jsxs8(ElvixCard, { title: "Banner", children: [
|
|
880
|
+
preview && /* @__PURE__ */ jsx9(
|
|
881
|
+
"img",
|
|
882
|
+
{
|
|
883
|
+
src: preview,
|
|
884
|
+
alt: "banner preview",
|
|
885
|
+
style: { width: "100%", aspectRatio: "16/9", objectFit: "cover", borderRadius: 10, marginBottom: 12 }
|
|
886
|
+
}
|
|
887
|
+
),
|
|
888
|
+
/* @__PURE__ */ jsx9("input", { type: "file", accept: "image/png,image/jpeg,image/webp", onChange: onFile, disabled: busy }),
|
|
889
|
+
busy && /* @__PURE__ */ jsx9("p", { children: "Uploading\u2026" }),
|
|
890
|
+
error && /* @__PURE__ */ jsx9("p", { role: "alert", className: "elvix-error", children: error })
|
|
891
|
+
] });
|
|
823
892
|
}
|
|
824
893
|
|
|
825
894
|
// src/react/elvix-identity-form.tsx
|
|
826
895
|
import { useState as useState8 } from "react";
|
|
896
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
827
897
|
function ElvixIdentityForm({
|
|
828
898
|
initialName = "",
|
|
829
899
|
initialBio = "",
|
|
@@ -850,11 +920,24 @@ function ElvixIdentityForm({
|
|
|
850
920
|
else setSaved(true);
|
|
851
921
|
onResult?.(result);
|
|
852
922
|
}
|
|
853
|
-
return /* @__PURE__ */
|
|
923
|
+
return /* @__PURE__ */ jsx10(ElvixCard, { title: "Identity", children: /* @__PURE__ */ jsxs9("form", { onSubmit: submit, className: "elvix-form", children: [
|
|
924
|
+
/* @__PURE__ */ jsxs9("label", { children: [
|
|
925
|
+
"Name",
|
|
926
|
+
/* @__PURE__ */ jsx10("input", { value: name, onChange: (e) => setName(e.target.value), maxLength: 80, disabled: busy, className: "elvix-input" })
|
|
927
|
+
] }),
|
|
928
|
+
/* @__PURE__ */ jsxs9("label", { children: [
|
|
929
|
+
"Bio",
|
|
930
|
+
/* @__PURE__ */ jsx10("textarea", { value: bio, onChange: (e) => setBio(e.target.value), maxLength: 500, rows: 3, disabled: busy, className: "elvix-input" })
|
|
931
|
+
] }),
|
|
932
|
+
/* @__PURE__ */ jsx10("button", { type: "submit", disabled: busy, className: "elvix-btn elvix-btn-primary", children: busy ? "Saving\u2026" : "Save" }),
|
|
933
|
+
saved && /* @__PURE__ */ jsx10("p", { className: "elvix-muted", children: "Saved." }),
|
|
934
|
+
error && /* @__PURE__ */ jsx10("p", { role: "alert", className: "elvix-error", children: error })
|
|
935
|
+
] }) });
|
|
854
936
|
}
|
|
855
937
|
|
|
856
938
|
// src/react/elvix-region.tsx
|
|
857
939
|
import { useState as useState9 } from "react";
|
|
940
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
858
941
|
function ElvixRegion({
|
|
859
942
|
initialCountry = "",
|
|
860
943
|
initialTimezone = "",
|
|
@@ -881,11 +964,24 @@ function ElvixRegion({
|
|
|
881
964
|
else setSaved(true);
|
|
882
965
|
onResult?.(result);
|
|
883
966
|
}
|
|
884
|
-
return /* @__PURE__ */
|
|
967
|
+
return /* @__PURE__ */ jsx11(ElvixCard, { title: "Region", children: /* @__PURE__ */ jsxs10("form", { onSubmit: submit, className: "elvix-form", children: [
|
|
968
|
+
/* @__PURE__ */ jsxs10("label", { children: [
|
|
969
|
+
"Country (ISO-2)",
|
|
970
|
+
/* @__PURE__ */ jsx11("input", { value: country, onChange: (e) => setCountry(e.target.value.toUpperCase()), maxLength: 2, pattern: "[A-Z]{2}", disabled: busy, className: "elvix-input" })
|
|
971
|
+
] }),
|
|
972
|
+
/* @__PURE__ */ jsxs10("label", { children: [
|
|
973
|
+
"Timezone",
|
|
974
|
+
/* @__PURE__ */ jsx11("input", { value: timezone, onChange: (e) => setTimezone(e.target.value), placeholder: "Europe/Berlin", disabled: busy, className: "elvix-input" })
|
|
975
|
+
] }),
|
|
976
|
+
/* @__PURE__ */ jsx11("button", { type: "submit", disabled: busy, className: "elvix-btn elvix-btn-primary", children: busy ? "Saving\u2026" : "Save" }),
|
|
977
|
+
saved && /* @__PURE__ */ jsx11("p", { className: "elvix-muted", children: "Saved." }),
|
|
978
|
+
error && /* @__PURE__ */ jsx11("p", { role: "alert", className: "elvix-error", children: error })
|
|
979
|
+
] }) });
|
|
885
980
|
}
|
|
886
981
|
|
|
887
982
|
// src/react/elvix-languages.tsx
|
|
888
983
|
import { useState as useState10 } from "react";
|
|
984
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
889
985
|
function ElvixLanguages({
|
|
890
986
|
initial = [],
|
|
891
987
|
onResult
|
|
@@ -911,11 +1007,20 @@ function ElvixLanguages({
|
|
|
911
1007
|
else setSaved(true);
|
|
912
1008
|
onResult?.(result);
|
|
913
1009
|
}
|
|
914
|
-
return /* @__PURE__ */
|
|
1010
|
+
return /* @__PURE__ */ jsx12(ElvixCard, { title: "Languages", children: /* @__PURE__ */ jsxs11("form", { onSubmit: submit, className: "elvix-form", children: [
|
|
1011
|
+
/* @__PURE__ */ jsxs11("label", { children: [
|
|
1012
|
+
"Preferred languages (comma-separated BCP-47 tags)",
|
|
1013
|
+
/* @__PURE__ */ jsx12("input", { value: raw, onChange: (e) => setRaw(e.target.value), placeholder: "en-GB, de-DE", disabled: busy, className: "elvix-input" })
|
|
1014
|
+
] }),
|
|
1015
|
+
/* @__PURE__ */ jsx12("button", { type: "submit", disabled: busy, className: "elvix-btn elvix-btn-primary", children: busy ? "Saving\u2026" : "Save" }),
|
|
1016
|
+
saved && /* @__PURE__ */ jsx12("p", { className: "elvix-muted", children: "Saved." }),
|
|
1017
|
+
error && /* @__PURE__ */ jsx12("p", { role: "alert", className: "elvix-error", children: error })
|
|
1018
|
+
] }) });
|
|
915
1019
|
}
|
|
916
1020
|
|
|
917
1021
|
// src/react/elvix-sessions.tsx
|
|
918
1022
|
import { useEffect as useEffect4, useState as useState11 } from "react";
|
|
1023
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
919
1024
|
function ElvixSessions({
|
|
920
1025
|
onResult
|
|
921
1026
|
}) {
|
|
@@ -943,11 +1048,29 @@ function ElvixSessions({
|
|
|
943
1048
|
if (result.ok) setRows((prev) => prev?.filter((s) => s.id !== id) ?? null);
|
|
944
1049
|
onResult?.(result);
|
|
945
1050
|
}
|
|
946
|
-
return /* @__PURE__ */
|
|
1051
|
+
return /* @__PURE__ */ jsxs12(ElvixCard, { title: "Active sessions", children: [
|
|
1052
|
+
error && /* @__PURE__ */ jsx13("p", { role: "alert", className: "elvix-error", children: error }),
|
|
1053
|
+
!rows && !error && /* @__PURE__ */ jsx13("p", { children: "Loading\u2026" }),
|
|
1054
|
+
rows && /* @__PURE__ */ jsx13("ul", { style: { listStyle: "none", padding: 0, margin: 0 }, children: rows.map((s) => /* @__PURE__ */ jsx13("li", { style: { padding: "10px 0", borderBottom: "1px solid rgba(0,0,0,0.06)" }, children: /* @__PURE__ */ jsxs12("div", { style: { display: "flex", justifyContent: "space-between", gap: 12 }, children: [
|
|
1055
|
+
/* @__PURE__ */ jsxs12("div", { children: [
|
|
1056
|
+
/* @__PURE__ */ jsxs12("div", { style: { fontSize: 13, fontWeight: 500 }, children: [
|
|
1057
|
+
s.device,
|
|
1058
|
+
s.current && /* @__PURE__ */ jsx13("span", { style: { marginLeft: 8, color: "var(--elvix-primary-strong)", fontSize: 11 }, children: "\xB7 this device" })
|
|
1059
|
+
] }),
|
|
1060
|
+
/* @__PURE__ */ jsxs12("div", { style: { fontSize: 11, color: "rgba(0,0,0,0.55)" }, children: [
|
|
1061
|
+
s.country ?? "\u2014",
|
|
1062
|
+
" \xB7 since ",
|
|
1063
|
+
new Date(s.createdAt).toLocaleDateString()
|
|
1064
|
+
] })
|
|
1065
|
+
] }),
|
|
1066
|
+
!s.current && /* @__PURE__ */ jsx13("button", { type: "button", disabled: busy, onClick: () => revoke(s.id), className: "elvix-btn elvix-btn-ghost", children: "Revoke" })
|
|
1067
|
+
] }) }, s.id)) })
|
|
1068
|
+
] });
|
|
947
1069
|
}
|
|
948
1070
|
|
|
949
1071
|
// src/react/elvix-export.tsx
|
|
950
1072
|
import { useState as useState12 } from "react";
|
|
1073
|
+
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
951
1074
|
function ElvixExport({
|
|
952
1075
|
onResult
|
|
953
1076
|
}) {
|
|
@@ -969,11 +1092,16 @@ function ElvixExport({
|
|
|
969
1092
|
else setDone(true);
|
|
970
1093
|
onResult?.(result);
|
|
971
1094
|
}
|
|
972
|
-
return /* @__PURE__ */
|
|
1095
|
+
return /* @__PURE__ */ jsxs13(ElvixCard, { title: "Export my data", children: [
|
|
1096
|
+
/* @__PURE__ */ jsx14("p", { style: { fontSize: 13, color: "rgba(0,0,0,0.6)" }, children: "Request a zip of every record we hold for you in this app. Delivery by email; single-use download link valid for 24h." }),
|
|
1097
|
+
done ? /* @__PURE__ */ jsx14("p", { className: "elvix-muted", children: "Request queued. Check your email." }) : /* @__PURE__ */ jsx14("button", { type: "button", onClick: start, disabled: busy, className: "elvix-btn elvix-btn-primary", children: busy ? "Queuing\u2026" : "Request export" }),
|
|
1098
|
+
error && /* @__PURE__ */ jsx14("p", { role: "alert", className: "elvix-error", children: error })
|
|
1099
|
+
] });
|
|
973
1100
|
}
|
|
974
1101
|
|
|
975
1102
|
// src/react/elvix-deactivate.tsx
|
|
976
1103
|
import { useState as useState13 } from "react";
|
|
1104
|
+
import { Fragment as Fragment3, jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
977
1105
|
function ElvixDeactivate({
|
|
978
1106
|
onResult
|
|
979
1107
|
}) {
|
|
@@ -1020,26 +1148,38 @@ function ElvixDeactivate({
|
|
|
1020
1148
|
onResult?.(result);
|
|
1021
1149
|
}
|
|
1022
1150
|
if (pane === "done") {
|
|
1023
|
-
return /* @__PURE__ */
|
|
1151
|
+
return /* @__PURE__ */ jsx15(ElvixCard, { title: "Deactivated", children: /* @__PURE__ */ jsx15("p", { children: "Your access has been paused. Sign in again to restore it." }) });
|
|
1024
1152
|
}
|
|
1025
|
-
return /* @__PURE__ */
|
|
1026
|
-
"
|
|
1027
|
-
|
|
1028
|
-
type: "
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1153
|
+
return /* @__PURE__ */ jsxs14(ElvixCard, { title: "Deactivate account", children: [
|
|
1154
|
+
pane === "warn" && /* @__PURE__ */ jsxs14(Fragment3, { children: [
|
|
1155
|
+
/* @__PURE__ */ jsx15("p", { style: { fontSize: 13, color: "rgba(0,0,0,0.6)" }, children: "Pause your membership. You can restore it any time by signing in again. No data is deleted." }),
|
|
1156
|
+
/* @__PURE__ */ jsx15("button", { type: "button", onClick: startChallenge, disabled: busy, className: "elvix-btn elvix-btn-danger", children: busy ? "Sending\u2026" : "Send code" })
|
|
1157
|
+
] }),
|
|
1158
|
+
pane === "otp" && /* @__PURE__ */ jsxs14("form", { onSubmit: confirm, className: "elvix-form", children: [
|
|
1159
|
+
/* @__PURE__ */ jsx15("p", { className: "elvix-muted", children: "We sent a 6-digit code to your email." }),
|
|
1160
|
+
/* @__PURE__ */ jsx15(
|
|
1161
|
+
"input",
|
|
1162
|
+
{
|
|
1163
|
+
type: "text",
|
|
1164
|
+
inputMode: "numeric",
|
|
1165
|
+
pattern: "[0-9]*",
|
|
1166
|
+
maxLength: 6,
|
|
1167
|
+
value: code,
|
|
1168
|
+
onChange: (e) => setCode(e.target.value.replace(/\D/g, "")),
|
|
1169
|
+
required: true,
|
|
1170
|
+
disabled: busy,
|
|
1171
|
+
className: "elvix-input"
|
|
1172
|
+
}
|
|
1173
|
+
),
|
|
1174
|
+
/* @__PURE__ */ jsx15("button", { type: "submit", disabled: busy || code.length !== 6, className: "elvix-btn elvix-btn-danger", children: busy ? "Deactivating\u2026" : "Confirm" })
|
|
1175
|
+
] }),
|
|
1176
|
+
error && /* @__PURE__ */ jsx15("p", { role: "alert", className: "elvix-error", children: error })
|
|
1177
|
+
] });
|
|
1039
1178
|
}
|
|
1040
1179
|
|
|
1041
1180
|
// src/react/elvix-leave.tsx
|
|
1042
1181
|
import { useState as useState14 } from "react";
|
|
1182
|
+
import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1043
1183
|
function ElvixLeave({
|
|
1044
1184
|
onResult
|
|
1045
1185
|
}) {
|
|
@@ -1086,26 +1226,38 @@ function ElvixLeave({
|
|
|
1086
1226
|
onResult?.(result);
|
|
1087
1227
|
}
|
|
1088
1228
|
if (pane === "done") {
|
|
1089
|
-
return /* @__PURE__ */
|
|
1229
|
+
return /* @__PURE__ */ jsx16(ElvixCard, { title: "You've left", children: /* @__PURE__ */ jsx16("p", { children: "You've left this app. Your data is archived; sign in again to rejoin." }) });
|
|
1090
1230
|
}
|
|
1091
|
-
return /* @__PURE__ */
|
|
1092
|
-
"
|
|
1093
|
-
|
|
1094
|
-
type: "
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1231
|
+
return /* @__PURE__ */ jsxs15(ElvixCard, { title: "Leave this app", children: [
|
|
1232
|
+
pane === "warn" && /* @__PURE__ */ jsxs15(Fragment4, { children: [
|
|
1233
|
+
/* @__PURE__ */ jsx16("p", { style: { fontSize: 13, color: "rgba(0,0,0,0.6)" }, children: "Remove yourself from this app. Audit trail is preserved; you can sign back in any time to rejoin." }),
|
|
1234
|
+
/* @__PURE__ */ jsx16("button", { type: "button", onClick: startChallenge, disabled: busy, className: "elvix-btn elvix-btn-danger", children: busy ? "Sending\u2026" : "Send code" })
|
|
1235
|
+
] }),
|
|
1236
|
+
pane === "otp" && /* @__PURE__ */ jsxs15("form", { onSubmit: confirm, className: "elvix-form", children: [
|
|
1237
|
+
/* @__PURE__ */ jsx16("p", { className: "elvix-muted", children: "We sent a 6-digit code to your email." }),
|
|
1238
|
+
/* @__PURE__ */ jsx16(
|
|
1239
|
+
"input",
|
|
1240
|
+
{
|
|
1241
|
+
type: "text",
|
|
1242
|
+
inputMode: "numeric",
|
|
1243
|
+
pattern: "[0-9]*",
|
|
1244
|
+
maxLength: 6,
|
|
1245
|
+
value: code,
|
|
1246
|
+
onChange: (e) => setCode(e.target.value.replace(/\D/g, "")),
|
|
1247
|
+
required: true,
|
|
1248
|
+
disabled: busy,
|
|
1249
|
+
className: "elvix-input"
|
|
1250
|
+
}
|
|
1251
|
+
),
|
|
1252
|
+
/* @__PURE__ */ jsx16("button", { type: "submit", disabled: busy || code.length !== 6, className: "elvix-btn elvix-btn-danger", children: busy ? "Leaving\u2026" : "Confirm leave" })
|
|
1253
|
+
] }),
|
|
1254
|
+
error && /* @__PURE__ */ jsx16("p", { role: "alert", className: "elvix-error", children: error })
|
|
1255
|
+
] });
|
|
1105
1256
|
}
|
|
1106
1257
|
|
|
1107
1258
|
// src/react/elvix-address-book.tsx
|
|
1108
1259
|
import { useEffect as useEffect5, useState as useState15 } from "react";
|
|
1260
|
+
import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1109
1261
|
function ElvixAddressBook({
|
|
1110
1262
|
onResult
|
|
1111
1263
|
}) {
|
|
@@ -1163,11 +1315,41 @@ function ElvixAddressBook({
|
|
|
1163
1315
|
if (result.ok) setRows((prev) => prev?.filter((a) => a.id !== id) ?? null);
|
|
1164
1316
|
onResult?.(result);
|
|
1165
1317
|
}
|
|
1166
|
-
return /* @__PURE__ */
|
|
1318
|
+
return /* @__PURE__ */ jsxs16(ElvixCard, { title: "Addresses", children: [
|
|
1319
|
+
error && /* @__PURE__ */ jsx17("p", { role: "alert", className: "elvix-error", children: error }),
|
|
1320
|
+
!rows && !error && /* @__PURE__ */ jsx17("p", { children: "Loading\u2026" }),
|
|
1321
|
+
rows && rows.length === 0 && /* @__PURE__ */ jsx17("p", { className: "elvix-muted", children: "No addresses yet." }),
|
|
1322
|
+
rows?.map((a) => /* @__PURE__ */ jsxs16("div", { style: { padding: "8px 0", borderBottom: "1px solid rgba(0,0,0,0.06)", display: "flex", justifyContent: "space-between", gap: 12 }, children: [
|
|
1323
|
+
/* @__PURE__ */ jsxs16("div", { style: { fontSize: 13 }, children: [
|
|
1324
|
+
/* @__PURE__ */ jsx17("div", { style: { fontWeight: 500 }, children: a.label }),
|
|
1325
|
+
/* @__PURE__ */ jsxs16("div", { style: { color: "rgba(0,0,0,0.55)" }, children: [
|
|
1326
|
+
a.line1,
|
|
1327
|
+
a.line2 ? `, ${a.line2}` : "",
|
|
1328
|
+
", ",
|
|
1329
|
+
a.postalCode,
|
|
1330
|
+
" ",
|
|
1331
|
+
a.city,
|
|
1332
|
+
", ",
|
|
1333
|
+
a.country
|
|
1334
|
+
] })
|
|
1335
|
+
] }),
|
|
1336
|
+
/* @__PURE__ */ jsx17("button", { type: "button", disabled: busy, onClick: () => remove(a.id), className: "elvix-btn elvix-btn-ghost", children: "Remove" })
|
|
1337
|
+
] }, a.id)),
|
|
1338
|
+
!adding && /* @__PURE__ */ jsx17("button", { type: "button", onClick: () => setAdding(true), className: "elvix-btn elvix-btn-primary", style: { marginTop: 12 }, children: "Add address" }),
|
|
1339
|
+
adding && /* @__PURE__ */ jsxs16("form", { onSubmit: add, className: "elvix-form", style: { marginTop: 12 }, children: [
|
|
1340
|
+
/* @__PURE__ */ jsx17("input", { value: form.label, onChange: (e) => setForm({ ...form, label: e.target.value }), placeholder: "Label", className: "elvix-input" }),
|
|
1341
|
+
/* @__PURE__ */ jsx17("input", { value: form.line1, onChange: (e) => setForm({ ...form, line1: e.target.value }), placeholder: "Street", required: true, className: "elvix-input" }),
|
|
1342
|
+
/* @__PURE__ */ jsx17("input", { value: form.postalCode, onChange: (e) => setForm({ ...form, postalCode: e.target.value }), placeholder: "Postal code", required: true, className: "elvix-input" }),
|
|
1343
|
+
/* @__PURE__ */ jsx17("input", { value: form.city, onChange: (e) => setForm({ ...form, city: e.target.value }), placeholder: "City", required: true, className: "elvix-input" }),
|
|
1344
|
+
/* @__PURE__ */ jsx17("input", { value: form.country, onChange: (e) => setForm({ ...form, country: e.target.value.toUpperCase() }), placeholder: "Country (ISO-2)", maxLength: 2, required: true, className: "elvix-input" }),
|
|
1345
|
+
/* @__PURE__ */ jsx17("button", { type: "submit", disabled: busy, className: "elvix-btn elvix-btn-primary", children: busy ? "Saving\u2026" : "Save" })
|
|
1346
|
+
] })
|
|
1347
|
+
] });
|
|
1167
1348
|
}
|
|
1168
1349
|
|
|
1169
1350
|
// src/react/elvix-legal-entities.tsx
|
|
1170
1351
|
import { useEffect as useEffect6, useState as useState16 } from "react";
|
|
1352
|
+
import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1171
1353
|
function ElvixLegalEntities({
|
|
1172
1354
|
onResult
|
|
1173
1355
|
}) {
|
|
@@ -1223,7 +1405,29 @@ function ElvixLegalEntities({
|
|
|
1223
1405
|
if (result.ok) setRows((prev) => prev?.filter((a) => a.id !== id) ?? null);
|
|
1224
1406
|
onResult?.(result);
|
|
1225
1407
|
}
|
|
1226
|
-
return /* @__PURE__ */
|
|
1408
|
+
return /* @__PURE__ */ jsxs17(ElvixCard, { title: "Legal entities", children: [
|
|
1409
|
+
error && /* @__PURE__ */ jsx18("p", { role: "alert", className: "elvix-error", children: error }),
|
|
1410
|
+
!rows && !error && /* @__PURE__ */ jsx18("p", { children: "Loading\u2026" }),
|
|
1411
|
+
rows && rows.length === 0 && /* @__PURE__ */ jsx18("p", { className: "elvix-muted", children: "No legal entities yet." }),
|
|
1412
|
+
rows?.map((e) => /* @__PURE__ */ jsxs17("div", { style: { padding: "8px 0", borderBottom: "1px solid rgba(0,0,0,0.06)", display: "flex", justifyContent: "space-between", gap: 12 }, children: [
|
|
1413
|
+
/* @__PURE__ */ jsxs17("div", { style: { fontSize: 13 }, children: [
|
|
1414
|
+
/* @__PURE__ */ jsx18("div", { style: { fontWeight: 500 }, children: e.legalName }),
|
|
1415
|
+
/* @__PURE__ */ jsxs17("div", { style: { color: "rgba(0,0,0,0.55)" }, children: [
|
|
1416
|
+
e.taxId,
|
|
1417
|
+
" \xB7 ",
|
|
1418
|
+
e.country
|
|
1419
|
+
] })
|
|
1420
|
+
] }),
|
|
1421
|
+
/* @__PURE__ */ jsx18("button", { type: "button", disabled: busy, onClick: () => remove(e.id), className: "elvix-btn elvix-btn-ghost", children: "Remove" })
|
|
1422
|
+
] }, e.id)),
|
|
1423
|
+
!adding && /* @__PURE__ */ jsx18("button", { type: "button", onClick: () => setAdding(true), className: "elvix-btn elvix-btn-primary", style: { marginTop: 12 }, children: "Add entity" }),
|
|
1424
|
+
adding && /* @__PURE__ */ jsxs17("form", { onSubmit: add, className: "elvix-form", style: { marginTop: 12 }, children: [
|
|
1425
|
+
/* @__PURE__ */ jsx18("input", { value: form.legalName, onChange: (e) => setForm({ ...form, legalName: e.target.value }), placeholder: "Legal name", required: true, className: "elvix-input" }),
|
|
1426
|
+
/* @__PURE__ */ jsx18("input", { value: form.taxId, onChange: (e) => setForm({ ...form, taxId: e.target.value }), placeholder: "Tax / VAT ID", required: true, className: "elvix-input" }),
|
|
1427
|
+
/* @__PURE__ */ jsx18("input", { value: form.country, onChange: (e) => setForm({ ...form, country: e.target.value.toUpperCase() }), placeholder: "Country (ISO-2)", maxLength: 2, required: true, className: "elvix-input" }),
|
|
1428
|
+
/* @__PURE__ */ jsx18("button", { type: "submit", disabled: busy, className: "elvix-btn elvix-btn-primary", children: busy ? "Saving\u2026" : "Save" })
|
|
1429
|
+
] })
|
|
1430
|
+
] });
|
|
1227
1431
|
}
|
|
1228
1432
|
export {
|
|
1229
1433
|
DEFAULT_COPY,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elvix.is/sdk",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Official elvix SDK. Drop-in React components, server helpers, and an MCP server so AI coding agents integrate elvix on the first try.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://elvix.is",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"LICENSE"
|
|
53
53
|
],
|
|
54
54
|
"scripts": {
|
|
55
|
-
"build": "tsup src/index.ts src/react.ts src/server.ts src/types.ts src/mcp/index.ts src/mcp/bin.ts src/cli/index.ts src/cli/doctor.ts --format esm --dts --clean --external react --external next",
|
|
55
|
+
"build": "tsup src/index.ts src/react.ts src/server.ts src/types.ts src/mcp/index.ts src/mcp/bin.ts src/cli/index.ts src/cli/doctor.ts --format esm --dts --clean --external react --external react/jsx-runtime --external next && node scripts/postbuild.mjs",
|
|
56
56
|
"typecheck": "tsc --noEmit",
|
|
57
57
|
"test": "vitest run"
|
|
58
58
|
},
|