@hex-core/components 1.8.1 → 1.9.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/_tsup-dts-rollup.d.ts +280 -0
- package/dist/auth-forgot-password.d.ts +2 -0
- package/dist/auth-forgot-password.js +400 -0
- package/dist/auth-forgot-password.js.map +1 -0
- package/dist/auth-reset-password.d.ts +2 -0
- package/dist/auth-reset-password.js +323 -0
- package/dist/auth-reset-password.js.map +1 -0
- package/dist/auth-sign-in-split.d.ts +3 -0
- package/dist/auth-sign-in-split.js +443 -0
- package/dist/auth-sign-in-split.js.map +1 -0
- package/dist/auth-sign-up-card.d.ts +3 -0
- package/dist/auth-sign-up-card.js +590 -0
- package/dist/auth-sign-up-card.js.map +1 -0
- package/dist/auth-verify-email.d.ts +2 -0
- package/dist/auth-verify-email.js +339 -0
- package/dist/auth-verify-email.js.map +1 -0
- package/dist/auth-verify-otp.d.ts +2 -0
- package/dist/auth-verify-otp.js +349 -0
- package/dist/auth-verify-otp.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +1029 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React4 from 'react';
|
|
3
|
+
import { cva } from 'class-variance-authority';
|
|
4
|
+
import { clsx } from 'clsx';
|
|
5
|
+
import { twMerge } from 'tailwind-merge';
|
|
6
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
|
+
import { OTPInput, OTPInputContext } from 'input-otp';
|
|
8
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
9
|
+
|
|
10
|
+
function cn(...inputs) {
|
|
11
|
+
return twMerge(clsx(inputs));
|
|
12
|
+
}
|
|
13
|
+
var alertVariants = cva(
|
|
14
|
+
[
|
|
15
|
+
"relative w-full rounded-lg border px-[var(--space-4,1rem)] py-[var(--space-3,0.75rem)] text-sm",
|
|
16
|
+
"transition-all duration-[var(--duration-normal,200ms)] ease-out",
|
|
17
|
+
"[&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:h-4 [&>svg]:w-4 [&>svg]:text-foreground",
|
|
18
|
+
"[&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px]"
|
|
19
|
+
].join(" "),
|
|
20
|
+
{
|
|
21
|
+
variants: {
|
|
22
|
+
variant: {
|
|
23
|
+
default: "border-foreground/[0.08] bg-background text-foreground",
|
|
24
|
+
destructive: "border-destructive/50 text-destructive [&>svg]:text-destructive bg-destructive/5"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
defaultVariants: { variant: "default" }
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
var Alert = React4.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
31
|
+
"div",
|
|
32
|
+
{
|
|
33
|
+
ref,
|
|
34
|
+
role: "alert",
|
|
35
|
+
className: cn(alertVariants({ variant }), className),
|
|
36
|
+
...props
|
|
37
|
+
}
|
|
38
|
+
));
|
|
39
|
+
Alert.displayName = "Alert";
|
|
40
|
+
var AlertTitle = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
41
|
+
"h5",
|
|
42
|
+
{
|
|
43
|
+
ref,
|
|
44
|
+
className: cn("mb-[var(--space-1,0.25rem)] font-medium leading-none tracking-tight", className),
|
|
45
|
+
...props
|
|
46
|
+
}
|
|
47
|
+
));
|
|
48
|
+
AlertTitle.displayName = "AlertTitle";
|
|
49
|
+
var AlertDescription = React4.forwardRef(
|
|
50
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("text-sm [&_p]:leading-relaxed", className), ...props })
|
|
51
|
+
);
|
|
52
|
+
AlertDescription.displayName = "AlertDescription";
|
|
53
|
+
var InputOTP = React4.forwardRef(
|
|
54
|
+
({ className, containerClassName, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
55
|
+
OTPInput,
|
|
56
|
+
{
|
|
57
|
+
ref,
|
|
58
|
+
containerClassName: cn(
|
|
59
|
+
"flex items-center gap-[var(--gap-sm,0.5rem)] has-[:disabled]:opacity-50",
|
|
60
|
+
containerClassName
|
|
61
|
+
),
|
|
62
|
+
className: cn("disabled:cursor-not-allowed", className),
|
|
63
|
+
...props
|
|
64
|
+
}
|
|
65
|
+
)
|
|
66
|
+
);
|
|
67
|
+
InputOTP.displayName = "InputOTP";
|
|
68
|
+
var InputOTPGroup = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-center", className), ...props }));
|
|
69
|
+
InputOTPGroup.displayName = "InputOTPGroup";
|
|
70
|
+
var InputOTPSlot = React4.forwardRef(
|
|
71
|
+
({ index, className, ...props }, ref) => {
|
|
72
|
+
const inputOTPContext = React4.useContext(OTPInputContext);
|
|
73
|
+
const slot = inputOTPContext.slots[index];
|
|
74
|
+
const char = slot?.char ?? null;
|
|
75
|
+
const hasFakeCaret = slot?.hasFakeCaret ?? false;
|
|
76
|
+
const isActive = slot?.isActive ?? false;
|
|
77
|
+
return /* @__PURE__ */ jsxs(
|
|
78
|
+
"div",
|
|
79
|
+
{
|
|
80
|
+
ref,
|
|
81
|
+
className: cn(
|
|
82
|
+
"relative flex h-[var(--control-height-md,2.5rem)] w-[var(--control-height-md,2.5rem)] items-center justify-center border-y border-r border-input text-sm transition-all duration-[var(--duration-normal,200ms)] ease-out",
|
|
83
|
+
"inset-ring-1 inset-ring-foreground/[0.06]",
|
|
84
|
+
"first:rounded-l-md first:border-l last:rounded-r-md",
|
|
85
|
+
isActive && "z-10 ring-2 ring-ring ring-offset-2 ring-offset-background",
|
|
86
|
+
className
|
|
87
|
+
),
|
|
88
|
+
...props,
|
|
89
|
+
children: [
|
|
90
|
+
char,
|
|
91
|
+
hasFakeCaret && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "h-4 w-px animate-pulse bg-foreground duration-1000" }) })
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
InputOTPSlot.displayName = "InputOTPSlot";
|
|
98
|
+
var InputOTPSeparator = React4.forwardRef(({ ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, role: "separator", ...props, children: /* @__PURE__ */ jsx(
|
|
99
|
+
"svg",
|
|
100
|
+
{
|
|
101
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
102
|
+
viewBox: "0 0 24 24",
|
|
103
|
+
fill: "currentColor",
|
|
104
|
+
className: "h-2 w-2 text-muted-foreground",
|
|
105
|
+
"aria-hidden": "true",
|
|
106
|
+
children: /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "6" })
|
|
107
|
+
}
|
|
108
|
+
) }));
|
|
109
|
+
InputOTPSeparator.displayName = "InputOTPSeparator";
|
|
110
|
+
var buttonVariants = cva(
|
|
111
|
+
[
|
|
112
|
+
"inline-flex items-center justify-center gap-[var(--gap-sm,0.5rem)] whitespace-nowrap rounded-md text-sm font-medium",
|
|
113
|
+
"transition-all duration-[var(--duration-normal,200ms)] ease-out",
|
|
114
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
115
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
116
|
+
"active:scale-[0.98]",
|
|
117
|
+
"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0"
|
|
118
|
+
].join(" "),
|
|
119
|
+
{
|
|
120
|
+
variants: {
|
|
121
|
+
variant: {
|
|
122
|
+
default: [
|
|
123
|
+
"bg-primary text-primary-foreground",
|
|
124
|
+
"shadow-sm shadow-primary/20",
|
|
125
|
+
"hover:bg-primary/90 hover:shadow-md hover:shadow-primary/25"
|
|
126
|
+
].join(" "),
|
|
127
|
+
destructive: [
|
|
128
|
+
"bg-destructive text-destructive-foreground",
|
|
129
|
+
"shadow-sm shadow-destructive/20",
|
|
130
|
+
"hover:bg-destructive/90 hover:shadow-md hover:shadow-destructive/25"
|
|
131
|
+
].join(" "),
|
|
132
|
+
outline: [
|
|
133
|
+
"border border-input bg-background",
|
|
134
|
+
"shadow-sm inset-ring-1 inset-ring-foreground/[0.06]",
|
|
135
|
+
"hover:bg-accent hover:text-accent-foreground hover:shadow-md hover:inset-ring-foreground/12"
|
|
136
|
+
].join(" "),
|
|
137
|
+
secondary: [
|
|
138
|
+
"bg-secondary text-secondary-foreground",
|
|
139
|
+
"shadow-sm inset-ring-1 inset-ring-foreground/[0.08]",
|
|
140
|
+
"hover:bg-secondary/80 hover:shadow-md hover:inset-ring-foreground/15"
|
|
141
|
+
].join(" "),
|
|
142
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
143
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
144
|
+
},
|
|
145
|
+
size: {
|
|
146
|
+
default: "h-[var(--control-height-md,2.5rem)] px-[var(--space-4,1rem)] py-[var(--space-2,0.5rem)]",
|
|
147
|
+
sm: "h-[var(--control-height-sm,2.25rem)] rounded-md px-[var(--space-3,0.75rem)]",
|
|
148
|
+
lg: "h-[var(--control-height-lg,2.75rem)] rounded-md px-[var(--space-8,2rem)] text-base",
|
|
149
|
+
icon: "h-[var(--control-height-md,2.5rem)] w-[var(--control-height-md,2.5rem)]"
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
defaultVariants: {
|
|
153
|
+
variant: "default",
|
|
154
|
+
size: "default"
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
);
|
|
158
|
+
var Button = React4.forwardRef(
|
|
159
|
+
({ className, variant, size, asChild = false, loading = false, children, disabled, ...props }, ref) => {
|
|
160
|
+
const Comp = asChild ? Slot : "button";
|
|
161
|
+
return /* @__PURE__ */ jsx(
|
|
162
|
+
Comp,
|
|
163
|
+
{
|
|
164
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
165
|
+
ref,
|
|
166
|
+
disabled: disabled || loading,
|
|
167
|
+
"aria-busy": loading || void 0,
|
|
168
|
+
...props,
|
|
169
|
+
children: loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
170
|
+
/* @__PURE__ */ jsxs(
|
|
171
|
+
"svg",
|
|
172
|
+
{
|
|
173
|
+
className: "animate-spin h-4 w-4",
|
|
174
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
175
|
+
fill: "none",
|
|
176
|
+
viewBox: "0 0 24 24",
|
|
177
|
+
"aria-hidden": "true",
|
|
178
|
+
children: [
|
|
179
|
+
/* @__PURE__ */ jsx(
|
|
180
|
+
"circle",
|
|
181
|
+
{
|
|
182
|
+
className: "opacity-25",
|
|
183
|
+
cx: "12",
|
|
184
|
+
cy: "12",
|
|
185
|
+
r: "10",
|
|
186
|
+
stroke: "currentColor",
|
|
187
|
+
strokeWidth: "4"
|
|
188
|
+
}
|
|
189
|
+
),
|
|
190
|
+
/* @__PURE__ */ jsx(
|
|
191
|
+
"path",
|
|
192
|
+
{
|
|
193
|
+
className: "opacity-75",
|
|
194
|
+
fill: "currentColor",
|
|
195
|
+
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
196
|
+
}
|
|
197
|
+
)
|
|
198
|
+
]
|
|
199
|
+
}
|
|
200
|
+
),
|
|
201
|
+
children
|
|
202
|
+
] }) : children
|
|
203
|
+
}
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
);
|
|
207
|
+
Button.displayName = "Button";
|
|
208
|
+
var HEADINGS = {
|
|
209
|
+
"sign-in": {
|
|
210
|
+
title: "Enter your sign-in code",
|
|
211
|
+
description: "We sent a 6-digit code to your email or phone. Enter it below to sign in."
|
|
212
|
+
},
|
|
213
|
+
"verify-email": {
|
|
214
|
+
title: "Verify your email",
|
|
215
|
+
description: "Enter the 6-digit code we sent to confirm your email address."
|
|
216
|
+
},
|
|
217
|
+
mfa: {
|
|
218
|
+
title: "Two-factor authentication",
|
|
219
|
+
description: "Enter the 6-digit code from your authenticator app."
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
function AuthVerifyOtp({
|
|
223
|
+
adapter,
|
|
224
|
+
intent,
|
|
225
|
+
length = 6,
|
|
226
|
+
resendCooldownSeconds = 30,
|
|
227
|
+
className,
|
|
228
|
+
onSuccess
|
|
229
|
+
}) {
|
|
230
|
+
const [code, setCode] = React4.useState("");
|
|
231
|
+
const [submitting, setSubmitting] = React4.useState(false);
|
|
232
|
+
const [resending, setResending] = React4.useState(false);
|
|
233
|
+
const [cooldownLeft, setCooldownLeft] = React4.useState(0);
|
|
234
|
+
const [error, setError] = React4.useState(null);
|
|
235
|
+
const lastSubmittedRef = React4.useRef("");
|
|
236
|
+
React4.useEffect(() => {
|
|
237
|
+
if (cooldownLeft <= 0) return;
|
|
238
|
+
const timer = setTimeout(() => setCooldownLeft((s) => s - 1), 1e3);
|
|
239
|
+
return () => clearTimeout(timer);
|
|
240
|
+
}, [cooldownLeft]);
|
|
241
|
+
const handleSubmit = React4.useCallback(
|
|
242
|
+
async (codeToSubmit) => {
|
|
243
|
+
if (!adapter.verifyOtp) {
|
|
244
|
+
console.warn(
|
|
245
|
+
"[AuthVerifyOtp] adapter.verifyOtp is not implemented \u2014 wire it up before exposing the form."
|
|
246
|
+
);
|
|
247
|
+
setError({
|
|
248
|
+
code: "unimplemented",
|
|
249
|
+
message: "Verification is currently unavailable. Please try again later."
|
|
250
|
+
});
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
setError(null);
|
|
254
|
+
setSubmitting(true);
|
|
255
|
+
try {
|
|
256
|
+
const result = await adapter.verifyOtp({ code: codeToSubmit, intent });
|
|
257
|
+
if (!result.ok) {
|
|
258
|
+
setError(
|
|
259
|
+
result.error ?? { code: "unknown", message: "Couldn't verify code." }
|
|
260
|
+
);
|
|
261
|
+
setCode("");
|
|
262
|
+
lastSubmittedRef.current = "";
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
onSuccess?.(result.redirect);
|
|
266
|
+
} finally {
|
|
267
|
+
setSubmitting(false);
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
[adapter, intent, onSuccess]
|
|
271
|
+
);
|
|
272
|
+
React4.useEffect(() => {
|
|
273
|
+
if (code.length !== length) return;
|
|
274
|
+
if (submitting) return;
|
|
275
|
+
if (lastSubmittedRef.current === code) return;
|
|
276
|
+
lastSubmittedRef.current = code;
|
|
277
|
+
void handleSubmit(code);
|
|
278
|
+
}, [code, length, submitting, handleSubmit]);
|
|
279
|
+
async function handleResend() {
|
|
280
|
+
if (!adapter.resendOtp) {
|
|
281
|
+
console.warn(
|
|
282
|
+
"[AuthVerifyOtp] adapter.resendOtp is not implemented \u2014 hide the resend button or wire the method."
|
|
283
|
+
);
|
|
284
|
+
setError({
|
|
285
|
+
code: "unimplemented",
|
|
286
|
+
message: "Resending is currently unavailable. Please try again later."
|
|
287
|
+
});
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
setError(null);
|
|
291
|
+
setResending(true);
|
|
292
|
+
try {
|
|
293
|
+
const result = await adapter.resendOtp({ intent });
|
|
294
|
+
if (!result.ok) {
|
|
295
|
+
setError(result.error ?? { code: "unknown", message: "Couldn't resend code." });
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
setCooldownLeft(resendCooldownSeconds);
|
|
299
|
+
setCode("");
|
|
300
|
+
} finally {
|
|
301
|
+
setResending(false);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
const heading = HEADINGS[intent];
|
|
305
|
+
const slots = React4.useMemo(
|
|
306
|
+
() => Array.from({ length }, (_, i) => i),
|
|
307
|
+
[length]
|
|
308
|
+
);
|
|
309
|
+
const cooldownLabel = cooldownLeft > 0 ? `Resend in ${cooldownLeft}s` : "Resend code";
|
|
310
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex min-h-svh items-center justify-center p-6 sm:p-10", className), children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-sm space-y-6", children: [
|
|
311
|
+
/* @__PURE__ */ jsxs("header", { className: "space-y-2 text-center", children: [
|
|
312
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold tracking-tight", children: heading.title }),
|
|
313
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: heading.description })
|
|
314
|
+
] }),
|
|
315
|
+
error ? /* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
|
|
316
|
+
/* @__PURE__ */ jsx(AlertTitle, { children: "Couldn\u2019t verify code" }),
|
|
317
|
+
/* @__PURE__ */ jsx(AlertDescription, { children: error.message })
|
|
318
|
+
] }) : null,
|
|
319
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4", children: [
|
|
320
|
+
/* @__PURE__ */ jsx(
|
|
321
|
+
InputOTP,
|
|
322
|
+
{
|
|
323
|
+
maxLength: length,
|
|
324
|
+
value: code,
|
|
325
|
+
onChange: setCode,
|
|
326
|
+
disabled: submitting,
|
|
327
|
+
"aria-label": "One-time code",
|
|
328
|
+
children: /* @__PURE__ */ jsx(InputOTPGroup, { children: slots.map((i) => /* @__PURE__ */ jsx(InputOTPSlot, { index: i }, i)) })
|
|
329
|
+
}
|
|
330
|
+
),
|
|
331
|
+
adapter.resendOtp ? /* @__PURE__ */ jsx(
|
|
332
|
+
Button,
|
|
333
|
+
{
|
|
334
|
+
type: "button",
|
|
335
|
+
variant: "ghost",
|
|
336
|
+
size: "sm",
|
|
337
|
+
onClick: handleResend,
|
|
338
|
+
disabled: resending || cooldownLeft > 0 || submitting,
|
|
339
|
+
loading: resending,
|
|
340
|
+
children: cooldownLabel
|
|
341
|
+
}
|
|
342
|
+
) : null
|
|
343
|
+
] })
|
|
344
|
+
] }) });
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export { AuthVerifyOtp };
|
|
348
|
+
//# sourceMappingURL=auth-verify-otp.js.map
|
|
349
|
+
//# sourceMappingURL=auth-verify-otp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/components/alert/alert.tsx","../src/components/input-otp/input-otp.tsx","../src/primitives/button/button-variants.ts","../src/primitives/button/button.tsx","../src/blocks/auth-verify-otp/auth-verify-otp.tsx"],"names":["React","React2","jsx","cva","React3","jsxs"],"mappings":"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","file":"auth-verify-otp.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","import { type VariantProps, cva } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\nconst alertVariants = cva(\n\t[\n\t\t\"relative w-full rounded-lg border px-[var(--space-4,1rem)] py-[var(--space-3,0.75rem)] text-sm\",\n\t\t\"transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\"[&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:h-4 [&>svg]:w-4 [&>svg]:text-foreground\",\n\t\t\"[&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px]\",\n\t].join(\" \"),\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault: \"border-foreground/[0.08] bg-background text-foreground\",\n\t\t\t\tdestructive:\n\t\t\t\t\t\"border-destructive/50 text-destructive [&>svg]:text-destructive bg-destructive/5\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: { variant: \"default\" },\n\t},\n);\n\n/** An inline notification banner for important messages. */\nconst Alert = React.forwardRef<\n\tHTMLDivElement,\n\tReact.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>\n>(({ className, variant, ...props }, ref) => (\n\t<div\n\t\tref={ref}\n\t\trole=\"alert\"\n\t\tclassName={cn(alertVariants({ variant }), className)}\n\t\t{...props}\n\t/>\n));\nAlert.displayName = \"Alert\";\n\n/** The alert title heading. */\nconst AlertTitle = React.forwardRef<\n\tHTMLHeadingElement,\n\tReact.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n\t<h5\n\t\tref={ref}\n\t\tclassName={cn(\"mb-[var(--space-1,0.25rem)] font-medium leading-none tracking-tight\", className)}\n\t\t{...props}\n\t/>\n));\nAlertTitle.displayName = \"AlertTitle\";\n\n/** The alert description. Renders a div so paragraph children can be styled via [&_p]. */\nconst AlertDescription = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(\n\t({ className, ...props }, ref) => (\n\t\t<div ref={ref} className={cn(\"text-sm [&_p]:leading-relaxed\", className)} {...props} />\n\t),\n);\nAlertDescription.displayName = \"AlertDescription\";\n\nexport { Alert, AlertTitle, AlertDescription, alertVariants };\n","\"use client\";\n\nimport { OTPInput, OTPInputContext } from \"input-otp\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/** Props for the root InputOTP component (mirrors input-otp's OTPInput). */\ntype InputOTPProps = React.ComponentPropsWithoutRef<typeof OTPInput>;\n\n/** Root OTP input. Wraps input-otp's OTPInput and exposes slot context to children. */\nconst InputOTP = React.forwardRef<React.ComponentRef<typeof OTPInput>, InputOTPProps>(\n\t({ className, containerClassName, ...props }, ref) => (\n\t<OTPInput\n\t\tref={ref}\n\t\tcontainerClassName={cn(\n\t\t\t\"flex items-center gap-[var(--gap-sm,0.5rem)] has-[:disabled]:opacity-50\",\n\t\t\tcontainerClassName,\n\t\t)}\n\t\tclassName={cn(\"disabled:cursor-not-allowed\", className)}\n\t\t{...props}\n\t/>\n));\nInputOTP.displayName = \"InputOTP\";\n\n/** Groups slots together; place between runs of slots to add visual dividers. */\nconst InputOTPGroup = React.forwardRef<\n\tReact.ComponentRef<\"div\">,\n\tReact.ComponentPropsWithoutRef<\"div\">\n>(({ className, ...props }, ref) => (\n\t<div ref={ref} className={cn(\"flex items-center\", className)} {...props} />\n));\nInputOTPGroup.displayName = \"InputOTPGroup\";\n\ninterface InputOTPSlotProps extends React.ComponentPropsWithoutRef<\"div\"> {\n\t/** Index of the slot in the underlying OTP value. */\n\tindex: number;\n}\n\n/** A single character slot. Reads its state from OTPInputContext. */\nconst InputOTPSlot = React.forwardRef<HTMLDivElement, InputOTPSlotProps>(\n\t({ index, className, ...props }, ref) => {\n\t\tconst inputOTPContext = React.useContext(OTPInputContext);\n\t\tconst slot = inputOTPContext.slots[index];\n\t\tconst char = slot?.char ?? null;\n\t\tconst hasFakeCaret = slot?.hasFakeCaret ?? false;\n\t\tconst isActive = slot?.isActive ?? false;\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"relative flex h-[var(--control-height-md,2.5rem)] w-[var(--control-height-md,2.5rem)] items-center justify-center border-y border-r border-input text-sm transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\t\t\"inset-ring-1 inset-ring-foreground/[0.06]\",\n\t\t\t\t\t\"first:rounded-l-md first:border-l last:rounded-r-md\",\n\t\t\t\t\tisActive && \"z-10 ring-2 ring-ring ring-offset-2 ring-offset-background\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{char}\n\t\t\t\t{hasFakeCaret && (\n\t\t\t\t\t<div className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n\t\t\t\t\t\t<div className=\"h-4 w-px animate-pulse bg-foreground duration-1000\" />\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t);\n\t},\n);\nInputOTPSlot.displayName = \"InputOTPSlot\";\n\n/** Visual separator between slot groups (a bullet by default). */\nconst InputOTPSeparator = React.forwardRef<\n\tReact.ComponentRef<\"div\">,\n\tReact.ComponentPropsWithoutRef<\"div\">\n>(({ ...props }, ref) => (\n\t<div ref={ref} role=\"separator\" {...props}>\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"currentColor\"\n\t\t\tclassName=\"h-2 w-2 text-muted-foreground\"\n\t\t\taria-hidden=\"true\"\n\t\t>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"6\" />\n\t\t</svg>\n\t</div>\n));\nInputOTPSeparator.displayName = \"InputOTPSeparator\";\n\nexport { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };\nexport type { InputOTPProps };\n","import { type VariantProps, cva } from \"class-variance-authority\";\n\n/**\n * CVA variants for the Button component.\n *\n * Lives in its own module so RSC-safe consumers (`Pagination`, future\n * link-styled buttons in static layouts) can import variants without\n * pulling in the full `Button` runtime — `Button` itself is client-only\n * because of `Slot` + `forwardRef` + the loading spinner. Splitting the\n * variants out keeps `dist/pagination.js` free of `@radix-ui/react-slot`.\n */\nexport const buttonVariants = cva(\n\t[\n\t\t\"inline-flex items-center justify-center gap-[var(--gap-sm,0.5rem)] whitespace-nowrap rounded-md text-sm font-medium\",\n\t\t\"transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n\t\t\"disabled:pointer-events-none disabled:opacity-50\",\n\t\t\"active:scale-[0.98]\",\n\t\t\"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n\t].join(\" \"),\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault: [\n\t\t\t\t\t\"bg-primary text-primary-foreground\",\n\t\t\t\t\t\"shadow-sm shadow-primary/20\",\n\t\t\t\t\t\"hover:bg-primary/90 hover:shadow-md hover:shadow-primary/25\",\n\t\t\t\t].join(\" \"),\n\t\t\t\tdestructive: [\n\t\t\t\t\t\"bg-destructive text-destructive-foreground\",\n\t\t\t\t\t\"shadow-sm shadow-destructive/20\",\n\t\t\t\t\t\"hover:bg-destructive/90 hover:shadow-md hover:shadow-destructive/25\",\n\t\t\t\t].join(\" \"),\n\t\t\t\toutline: [\n\t\t\t\t\t\"border border-input bg-background\",\n\t\t\t\t\t\"shadow-sm inset-ring-1 inset-ring-foreground/[0.06]\",\n\t\t\t\t\t\"hover:bg-accent hover:text-accent-foreground hover:shadow-md hover:inset-ring-foreground/12\",\n\t\t\t\t].join(\" \"),\n\t\t\t\tsecondary: [\n\t\t\t\t\t\"bg-secondary text-secondary-foreground\",\n\t\t\t\t\t\"shadow-sm inset-ring-1 inset-ring-foreground/[0.08]\",\n\t\t\t\t\t\"hover:bg-secondary/80 hover:shadow-md hover:inset-ring-foreground/15\",\n\t\t\t\t].join(\" \"),\n\t\t\t\tghost: \"hover:bg-accent hover:text-accent-foreground\",\n\t\t\t\tlink: \"text-primary underline-offset-4 hover:underline\",\n\t\t\t},\n\t\t\tsize: {\n\t\t\t\tdefault:\n\t\t\t\t\t\"h-[var(--control-height-md,2.5rem)] px-[var(--space-4,1rem)] py-[var(--space-2,0.5rem)]\",\n\t\t\t\tsm: \"h-[var(--control-height-sm,2.25rem)] rounded-md px-[var(--space-3,0.75rem)]\",\n\t\t\t\tlg: \"h-[var(--control-height-lg,2.75rem)] rounded-md px-[var(--space-8,2rem)] text-base\",\n\t\t\t\ticon: \"h-[var(--control-height-md,2.5rem)] w-[var(--control-height-md,2.5rem)]\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: {\n\t\t\tvariant: \"default\",\n\t\t\tsize: \"default\",\n\t\t},\n\t},\n);\n\nexport type ButtonVariantsProps = VariantProps<typeof buttonVariants>;\n","\"use client\";\n\nimport { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\nimport { type ButtonVariantsProps, buttonVariants } from \"./button-variants.js\";\n\nexport interface ButtonProps\n\textends React.ButtonHTMLAttributes<HTMLButtonElement>,\n\t\tButtonVariantsProps {\n\tasChild?: boolean;\n\tloading?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n\t(\n\t\t{ className, variant, size, asChild = false, loading = false, children, disabled, ...props },\n\t\tref,\n\t) => {\n\t\tconst Comp = asChild ? Slot : \"button\";\n\t\treturn (\n\t\t\t<Comp\n\t\t\t\tclassName={cn(buttonVariants({ variant, size, className }))}\n\t\t\t\tref={ref}\n\t\t\t\tdisabled={disabled || loading}\n\t\t\t\taria-busy={loading || undefined}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{loading ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\tclassName=\"animate-spin h-4 w-4\"\n\t\t\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<circle\n\t\t\t\t\t\t\t\tclassName=\"opacity-25\"\n\t\t\t\t\t\t\t\tcx=\"12\"\n\t\t\t\t\t\t\t\tcy=\"12\"\n\t\t\t\t\t\t\t\tr=\"10\"\n\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\tstrokeWidth=\"4\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\tclassName=\"opacity-75\"\n\t\t\t\t\t\t\t\tfill=\"currentColor\"\n\t\t\t\t\t\t\t\td=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\tchildren\n\t\t\t\t)}\n\t\t\t</Comp>\n\t\t);\n\t},\n);\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants };\n","\"use client\";\n\nimport * as React from \"react\";\nimport { Alert, AlertDescription, AlertTitle } from \"../../components/alert/alert.js\";\nimport {\n\tInputOTP,\n\tInputOTPGroup,\n\tInputOTPSlot,\n} from \"../../components/input-otp/input-otp.js\";\nimport { Button } from \"../../primitives/button/button.js\";\nimport { cn } from \"../../lib/utils.js\";\nimport type { AuthAdapter, AuthOtpIntent } from \"../_shared/auth-adapter.js\";\n\nexport interface AuthVerifyOtpProps {\n\tadapter: AuthAdapter;\n\t/** Forwarded verbatim to adapter.verifyOtp({ code, intent }). */\n\tintent: AuthOtpIntent;\n\t/** Total number of digits in the code. Defaults to 6. */\n\tlength?: number;\n\t/** Seconds the resend button stays disabled after each successful resend. */\n\tresendCooldownSeconds?: number;\n\tclassName?: string;\n\tonSuccess?: (redirect: string | undefined) => void;\n}\n\nconst HEADINGS: Record<AuthOtpIntent, { title: string; description: string }> = {\n\t\"sign-in\": {\n\t\ttitle: \"Enter your sign-in code\",\n\t\tdescription: \"We sent a 6-digit code to your email or phone. Enter it below to sign in.\",\n\t},\n\t\"verify-email\": {\n\t\ttitle: \"Verify your email\",\n\t\tdescription: \"Enter the 6-digit code we sent to confirm your email address.\",\n\t},\n\tmfa: {\n\t\ttitle: \"Two-factor authentication\",\n\t\tdescription: \"Enter the 6-digit code from your authenticator app.\",\n\t},\n};\n\n/**\n * One-time-code verification page. Renders an `InputOTP` of `length` slots\n * and submits automatically when the code is full. Routes verification\n * through `adapter.verifyOtp({ code, intent })`. Optional resend button\n * calls `adapter.resendOtp({ intent })` when implemented.\n */\nexport function AuthVerifyOtp({\n\tadapter,\n\tintent,\n\tlength = 6,\n\tresendCooldownSeconds = 30,\n\tclassName,\n\tonSuccess,\n}: AuthVerifyOtpProps) {\n\tconst [code, setCode] = React.useState(\"\");\n\tconst [submitting, setSubmitting] = React.useState(false);\n\tconst [resending, setResending] = React.useState(false);\n\tconst [cooldownLeft, setCooldownLeft] = React.useState(0);\n\tconst [error, setError] = React.useState<{ code: string; message: string } | null>(null);\n\t// Dedup guard for the auto-submit effect.\n\t//\n\t// The effect depends on `submitting` so it can short-circuit while a\n\t// request is in flight. After the request resolves, `submitting` flips\n\t// false → the effect re-runs → the same `code` value is still full → it\n\t// would auto-submit again. The ref captures the value we last dispatched\n\t// so a second pass is a no-op. Reset back to \"\" on error (alongside\n\t// `setCode(\"\")`) so the user can re-enter the same digits without the\n\t// guard short-circuiting.\n\tconst lastSubmittedRef = React.useRef<string>(\"\");\n\n\tReact.useEffect(() => {\n\t\tif (cooldownLeft <= 0) return;\n\t\tconst timer = setTimeout(() => setCooldownLeft((s) => s - 1), 1000);\n\t\treturn () => clearTimeout(timer);\n\t}, [cooldownLeft]);\n\n\tconst handleSubmit = React.useCallback(\n\t\tasync (codeToSubmit: string) => {\n\t\t\tif (!adapter.verifyOtp) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t\"[AuthVerifyOtp] adapter.verifyOtp is not implemented — wire it up before exposing the form.\",\n\t\t\t\t);\n\t\t\t\tsetError({\n\t\t\t\t\tcode: \"unimplemented\",\n\t\t\t\t\tmessage: \"Verification is currently unavailable. Please try again later.\",\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsetError(null);\n\t\t\tsetSubmitting(true);\n\t\t\ttry {\n\t\t\t\tconst result = await adapter.verifyOtp({ code: codeToSubmit, intent });\n\t\t\t\tif (!result.ok) {\n\t\t\t\t\tsetError(\n\t\t\t\t\t\tresult.error ?? { code: \"unknown\", message: \"Couldn't verify code.\" },\n\t\t\t\t\t);\n\t\t\t\t\t// Reset both the visible value and the dedup ref so the user can\n\t\t\t\t\t// re-enter the same digits without the effect short-circuiting.\n\t\t\t\t\tsetCode(\"\");\n\t\t\t\t\tlastSubmittedRef.current = \"\";\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tonSuccess?.(result.redirect);\n\t\t\t} finally {\n\t\t\t\tsetSubmitting(false);\n\t\t\t}\n\t\t},\n\t\t[adapter, intent, onSuccess],\n\t);\n\n\t// Auto-submit when the code reaches full length. Guarded by a ref so the\n\t// effect doesn't re-fire when `submitting` flips back to false after the\n\t// request resolves — `setCode(\"\")` on error already gives a fresh attempt.\n\tReact.useEffect(() => {\n\t\tif (code.length !== length) return;\n\t\tif (submitting) return;\n\t\tif (lastSubmittedRef.current === code) return;\n\t\tlastSubmittedRef.current = code;\n\t\tvoid handleSubmit(code);\n\t}, [code, length, submitting, handleSubmit]);\n\n\tasync function handleResend() {\n\t\tif (!adapter.resendOtp) {\n\t\t\tconsole.warn(\n\t\t\t\t\"[AuthVerifyOtp] adapter.resendOtp is not implemented — hide the resend button or wire the method.\",\n\t\t\t);\n\t\t\tsetError({\n\t\t\t\tcode: \"unimplemented\",\n\t\t\t\tmessage: \"Resending is currently unavailable. Please try again later.\",\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tsetError(null);\n\t\tsetResending(true);\n\t\ttry {\n\t\t\tconst result = await adapter.resendOtp({ intent });\n\t\t\tif (!result.ok) {\n\t\t\t\tsetError(result.error ?? { code: \"unknown\", message: \"Couldn't resend code.\" });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsetCooldownLeft(resendCooldownSeconds);\n\t\t\tsetCode(\"\");\n\t\t} finally {\n\t\t\tsetResending(false);\n\t\t}\n\t}\n\n\tconst heading = HEADINGS[intent];\n\tconst slots = React.useMemo(\n\t\t() => Array.from({ length }, (_, i) => i),\n\t\t[length],\n\t);\n\tconst cooldownLabel =\n\t\tcooldownLeft > 0 ? `Resend in ${cooldownLeft}s` : \"Resend code\";\n\n\treturn (\n\t\t<div className={cn(\"flex min-h-svh items-center justify-center p-6 sm:p-10\", className)}>\n\t\t\t<div className=\"w-full max-w-sm space-y-6\">\n\t\t\t\t<header className=\"space-y-2 text-center\">\n\t\t\t\t\t<h1 className=\"text-2xl font-semibold tracking-tight\">{heading.title}</h1>\n\t\t\t\t\t<p className=\"text-sm text-muted-foreground\">{heading.description}</p>\n\t\t\t\t</header>\n\n\t\t\t\t{error ? (\n\t\t\t\t\t<Alert variant=\"destructive\">\n\t\t\t\t\t\t<AlertTitle>Couldn’t verify code</AlertTitle>\n\t\t\t\t\t\t<AlertDescription>{error.message}</AlertDescription>\n\t\t\t\t\t</Alert>\n\t\t\t\t) : null}\n\n\t\t\t\t<div className=\"flex flex-col items-center gap-4\">\n\t\t\t\t\t<InputOTP\n\t\t\t\t\t\tmaxLength={length}\n\t\t\t\t\t\tvalue={code}\n\t\t\t\t\t\tonChange={setCode}\n\t\t\t\t\t\tdisabled={submitting}\n\t\t\t\t\t\taria-label=\"One-time code\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<InputOTPGroup>\n\t\t\t\t\t\t\t{slots.map((i) => (\n\t\t\t\t\t\t\t\t<InputOTPSlot key={i} index={i} />\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</InputOTPGroup>\n\t\t\t\t\t</InputOTP>\n\n\t\t\t\t\t{adapter.resendOtp ? (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tonClick={handleResend}\n\t\t\t\t\t\t\tdisabled={resending || cooldownLeft > 0 || submitting}\n\t\t\t\t\t\t\tloading={resending}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{cooldownLabel}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -408,4 +408,23 @@ export { DeckProps } from './_tsup-dts-rollup.js';
|
|
|
408
408
|
export { SpacedRepetition } from './_tsup-dts-rollup.js';
|
|
409
409
|
export { SpacedRepetitionProps } from './_tsup-dts-rollup.js';
|
|
410
410
|
export { SrsRating } from './_tsup-dts-rollup.js';
|
|
411
|
+
export { AuthAdapter } from './_tsup-dts-rollup.js';
|
|
412
|
+
export { AuthAdapterResult } from './_tsup-dts-rollup.js';
|
|
413
|
+
export { AuthForgotPasswordProps } from './_tsup-dts-rollup.js';
|
|
414
|
+
export { AuthOtpIntent } from './_tsup-dts-rollup.js';
|
|
415
|
+
export { AuthResetPasswordProps } from './_tsup-dts-rollup.js';
|
|
416
|
+
export { AuthSignInSocialProvider } from './_tsup-dts-rollup.js';
|
|
417
|
+
export { AuthSignInSplitProps } from './_tsup-dts-rollup.js';
|
|
418
|
+
export { AuthSignUpCardProps } from './_tsup-dts-rollup.js';
|
|
419
|
+
export { AuthSignUpCardSocialProvider } from './_tsup-dts-rollup.js';
|
|
420
|
+
export { AuthSocialProvider } from './_tsup-dts-rollup.js';
|
|
421
|
+
export { AuthVerifyEmailProps } from './_tsup-dts-rollup.js';
|
|
422
|
+
export { AuthVerifyOtpProps } from './_tsup-dts-rollup.js';
|
|
423
|
+
export { AuthForgotPassword } from './_tsup-dts-rollup.js';
|
|
424
|
+
export { AuthResetPassword } from './_tsup-dts-rollup.js';
|
|
425
|
+
export { AuthSignInSplit } from './_tsup-dts-rollup.js';
|
|
426
|
+
export { AuthSignUpCard } from './_tsup-dts-rollup.js';
|
|
427
|
+
export { AuthVerifyEmail } from './_tsup-dts-rollup.js';
|
|
428
|
+
export { AuthVerifyOtp } from './_tsup-dts-rollup.js';
|
|
429
|
+
export { mockAuthAdapter } from './_tsup-dts-rollup.js';
|
|
411
430
|
export { cn } from './_tsup-dts-rollup.js';
|