@hex-core/components 1.8.1 → 1.10.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 +855 -18
- package/dist/accordion.js.map +1 -1
- package/dist/alert-dialog.js.map +1 -1
- package/dist/alert.js.map +1 -1
- package/dist/arc.js.map +1 -1
- package/dist/attachment.js.map +1 -1
- package/dist/audio-player.js.map +1 -1
- package/dist/audio-waveform.js.map +1 -1
- 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/avatar.js.map +1 -1
- package/dist/badge.js.map +1 -1
- package/dist/branch.d.ts +2 -0
- package/dist/branch.js +136 -0
- package/dist/branch.js.map +1 -0
- package/dist/breadcrumb.js.map +1 -1
- package/dist/button.js.map +1 -1
- package/dist/calendar.js.map +1 -1
- package/dist/canvas.js.map +1 -1
- package/dist/card.js.map +1 -1
- package/dist/chain-of-thought.d.ts +3 -0
- package/dist/chain-of-thought.js +119 -0
- package/dist/chain-of-thought.js.map +1 -0
- package/dist/checkbox.js.map +1 -1
- package/dist/chord.js.map +1 -1
- package/dist/citation.js.map +1 -1
- package/dist/cloze.js.map +1 -1
- package/dist/cluster.js.map +1 -1
- package/dist/code-block-copy.js.map +1 -1
- package/dist/code-block.js.map +1 -1
- package/dist/color-picker.js.map +1 -1
- package/dist/combobox.js.map +1 -1
- package/dist/command.js.map +1 -1
- package/dist/compare-table.js.map +1 -1
- package/dist/composer.js.map +1 -1
- package/dist/container.js.map +1 -1
- package/dist/context-menu.js.map +1 -1
- package/dist/conversation.d.ts +3 -0
- package/dist/conversation.js +358 -0
- package/dist/conversation.js.map +1 -0
- package/dist/data-table.js.map +1 -1
- package/dist/date-picker.js.map +1 -1
- package/dist/deck.js.map +1 -1
- package/dist/dendrogram.js.map +1 -1
- package/dist/diagram.js.map +1 -1
- package/dist/dialog.js.map +1 -1
- package/dist/drawer.js.map +1 -1
- package/dist/dropdown-menu.js.map +1 -1
- package/dist/dropzone.js.map +1 -1
- package/dist/empty.js.map +1 -1
- package/dist/error-state.js.map +1 -1
- package/dist/file-tree.js.map +1 -1
- package/dist/flashcard.js.map +1 -1
- package/dist/flowchart.js.map +1 -1
- package/dist/form.js.map +1 -1
- package/dist/funnel.js.map +1 -1
- package/dist/gantt.js.map +1 -1
- package/dist/grid.js.map +1 -1
- package/dist/hover-card.js.map +1 -1
- package/dist/image-occlusion.js.map +1 -1
- package/dist/index.d.ts +40 -0
- package/dist/index.js +4839 -2813
- package/dist/index.js.map +1 -1
- package/dist/inline-citation.d.ts +2 -0
- package/dist/inline-citation.js +108 -0
- package/dist/inline-citation.js.map +1 -0
- package/dist/input-otp.js.map +1 -1
- package/dist/input.js.map +1 -1
- package/dist/label.js.map +1 -1
- package/dist/loading-indicator.js.map +1 -1
- package/dist/loading.js.map +1 -1
- package/dist/markdown.d.ts +1 -0
- package/dist/markdown.js +784 -4
- package/dist/markdown.js.map +1 -1
- package/dist/matrix.js.map +1 -1
- package/dist/menubar.js.map +1 -1
- package/dist/message-actions.js.map +1 -1
- package/dist/message-list.js.map +1 -1
- package/dist/message.js.map +1 -1
- package/dist/mind-map.js.map +1 -1
- package/dist/multi-combobox.js.map +1 -1
- package/dist/navigation-menu.js.map +1 -1
- package/dist/org-chart.js.map +1 -1
- package/dist/pagination.js.map +1 -1
- package/dist/plan.d.ts +3 -0
- package/dist/plan.js +183 -0
- package/dist/plan.js.map +1 -0
- package/dist/popover.js.map +1 -1
- package/dist/progress.js.map +1 -1
- package/dist/pyramid.js.map +1 -1
- package/dist/quiz.js.map +1 -1
- package/dist/radio-group.js.map +1 -1
- package/dist/reasoning.js.map +1 -1
- package/dist/resizable.js.map +1 -1
- package/dist/sankey.js.map +1 -1
- package/dist/schemas.d.ts +8 -0
- package/dist/schemas.js +774 -17
- package/dist/schemas.js.map +1 -1
- package/dist/scroll-area.js.map +1 -1
- package/dist/select.js.map +1 -1
- package/dist/separator.js.map +1 -1
- package/dist/sequence.js.map +1 -1
- package/dist/sheet.js.map +1 -1
- package/dist/shimmer.d.ts +2 -0
- package/dist/shimmer.js +39 -0
- package/dist/shimmer.js.map +1 -0
- package/dist/sidebar.js.map +1 -1
- package/dist/skeleton.js.map +1 -1
- package/dist/slider.js.map +1 -1
- package/dist/sources.d.ts +3 -0
- package/dist/sources.js +164 -0
- package/dist/sources.js.map +1 -0
- package/dist/spaced-repetition.js.map +1 -1
- package/dist/spacer.js.map +1 -1
- package/dist/speech-recognition.js.map +1 -1
- package/dist/stack.js.map +1 -1
- package/dist/stepper.js.map +1 -1
- package/dist/suggestion.js.map +1 -1
- package/dist/sunburst.js.map +1 -1
- package/dist/switch.js.map +1 -1
- package/dist/table.js.map +1 -1
- package/dist/tabs.js.map +1 -1
- package/dist/tag.js.map +1 -1
- package/dist/task.d.ts +3 -0
- package/dist/task.js +189 -0
- package/dist/task.js.map +1 -0
- package/dist/terminal.js +11 -0
- package/dist/terminal.js.map +1 -1
- package/dist/textarea.js.map +1 -1
- package/dist/time-axis.js.map +1 -1
- package/dist/time-picker.js.map +1 -1
- package/dist/timeline.js.map +1 -1
- package/dist/toggle-group.js.map +1 -1
- package/dist/toggle.js.map +1 -1
- package/dist/tool-call.js +5 -6
- package/dist/tool-call.js.map +1 -1
- package/dist/toolbar.js.map +1 -1
- package/dist/tooltip.js.map +1 -1
- package/dist/tree-map.js.map +1 -1
- package/dist/tree.js.map +1 -1
- package/dist/venn.js.map +1 -1
- package/package.json +9 -4
|
@@ -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\nconst SAFE_URL_SCHEMES = [\"http:\", \"https:\", \"mailto:\"] as const;\n\n/**\n * Allowlist a URL for use as an `<a href>` against untrusted input.\n *\n * Returns the raw string when it's `http(s):` / `mailto:` / a relative\n * URL (no scheme); returns `undefined` otherwise. Defends against\n * `javascript:` / `data:` / `vbscript:` injection from streamed model\n * output or third-party JSON payloads that flow into citation chips.\n *\n * Inside a Markdown render path, `rehype-sanitize` already strips\n * `javascript:` from inline-link hrefs — but it does NOT introspect\n * JSON nested inside attribute values (e.g. `<sources data='[…]'/>`),\n * so the components that consume that data must guard themselves.\n *\n * @param raw - The candidate URL, or `undefined` when none was supplied.\n * @returns The URL when safe to render, otherwise `undefined`.\n */\nexport function safeUrl(raw: string | undefined): string | undefined {\n\tif (raw === undefined || raw === \"\") return undefined;\n\t// Relative URLs have no scheme — `new URL(relative)` throws without a base,\n\t// so a thrown URL means either malformed input OR a relative path. Treat\n\t// \"throws + does not contain a colon\" as a relative path (safe).\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\treturn raw.includes(\":\") ? undefined : raw;\n\t}\n\treturn SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : undefined;\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/avatar.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/utils.ts","../src/primitives/avatar/avatar.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACHA,IAAM,MAAA,GAAe,iBAGnB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC3B,GAAA;AAAA,EAAiB,eAAA,CAAA,IAAA;AAAA,EAAhB;AAAA,IACA,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,6HAAA,EAA+H,SAAS,CAAA;AAAA,IACrJ,GAAG;AAAA;AACL,CACA;AACD,MAAA,CAAO,WAAA,GAAc,QAAA;AAGrB,IAAM,WAAA,GAAoB,iBAGxB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC3B,GAAA;AAAA,EAAiB,eAAA,CAAA,KAAA;AAAA,EAAhB;AAAA,IACA,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,0CAAA,EAA4C,SAAS,CAAA;AAAA,IAClE,GAAG;AAAA;AACL,CACA;AACD,WAAA,CAAY,WAAA,GAAc,aAAA;AAG1B,IAAM,cAAA,GAAuB,iBAG3B,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC3B,GAAA;AAAA,EAAiB,eAAA,CAAA,QAAA;AAAA,EAAhB;AAAA,IACA,GAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACV,gHAAA;AAAA,MACA;AAAA,KACD;AAAA,IACC,GAAG;AAAA;AACL,CACA;AACD,cAAA,CAAe,WAAA,GAAc,gBAAA","file":"avatar.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","\"use client\";\n\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/** Root container for an avatar (image + fallback). */\nconst Avatar = React.forwardRef<\n\tReact.ComponentRef<typeof AvatarPrimitive.Root>,\n\tReact.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>\n>(({ className, ...props }, ref) => (\n\t<AvatarPrimitive.Root\n\t\tref={ref}\n\t\tclassName={cn(\"relative flex h-[var(--control-height-md,2.5rem)] w-[var(--control-height-md,2.5rem)] shrink-0 overflow-hidden rounded-full\", className)}\n\t\t{...props}\n\t/>\n));\nAvatar.displayName = \"Avatar\";\n\n/** Avatar image. AvatarFallback renders in its place when the image is missing or errors. */\nconst AvatarImage = React.forwardRef<\n\tReact.ComponentRef<typeof AvatarPrimitive.Image>,\n\tReact.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>\n>(({ className, ...props }, ref) => (\n\t<AvatarPrimitive.Image\n\t\tref={ref}\n\t\tclassName={cn(\"aspect-square h-full w-full object-cover\", className)}\n\t\t{...props}\n\t/>\n));\nAvatarImage.displayName = \"AvatarImage\";\n\n/** Fallback content (usually initials or an icon) shown when the image is missing or fails. Supports delayMs to avoid flashing for fast-loading images. */\nconst AvatarFallback = React.forwardRef<\n\tReact.ComponentRef<typeof AvatarPrimitive.Fallback>,\n\tReact.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>\n>(({ className, ...props }, ref) => (\n\t<AvatarPrimitive.Fallback\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"flex h-full w-full items-center justify-center rounded-full bg-muted text-sm font-medium text-muted-foreground\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nAvatarFallback.displayName = \"AvatarFallback\";\n\nexport { Avatar, AvatarImage, AvatarFallback };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/primitives/avatar/avatar.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACHA,IAAM,MAAA,GAAe,iBAGnB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC3B,GAAA;AAAA,EAAiB,eAAA,CAAA,IAAA;AAAA,EAAhB;AAAA,IACA,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,6HAAA,EAA+H,SAAS,CAAA;AAAA,IACrJ,GAAG;AAAA;AACL,CACA;AACD,MAAA,CAAO,WAAA,GAAc,QAAA;AAGrB,IAAM,WAAA,GAAoB,iBAGxB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC3B,GAAA;AAAA,EAAiB,eAAA,CAAA,KAAA;AAAA,EAAhB;AAAA,IACA,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,0CAAA,EAA4C,SAAS,CAAA;AAAA,IAClE,GAAG;AAAA;AACL,CACA;AACD,WAAA,CAAY,WAAA,GAAc,aAAA;AAG1B,IAAM,cAAA,GAAuB,iBAG3B,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC3B,GAAA;AAAA,EAAiB,eAAA,CAAA,QAAA;AAAA,EAAhB;AAAA,IACA,GAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACV,gHAAA;AAAA,MACA;AAAA,KACD;AAAA,IACC,GAAG;AAAA;AACL,CACA;AACD,cAAA,CAAe,WAAA,GAAc,gBAAA","file":"avatar.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\nconst SAFE_URL_SCHEMES = [\"http:\", \"https:\", \"mailto:\"] as const;\n\n/**\n * Allowlist a URL for use as an `<a href>` against untrusted input.\n *\n * Returns the raw string when it's `http(s):` / `mailto:` / a relative\n * URL (no scheme); returns `undefined` otherwise. Defends against\n * `javascript:` / `data:` / `vbscript:` injection from streamed model\n * output or third-party JSON payloads that flow into citation chips.\n *\n * Inside a Markdown render path, `rehype-sanitize` already strips\n * `javascript:` from inline-link hrefs — but it does NOT introspect\n * JSON nested inside attribute values (e.g. `<sources data='[…]'/>`),\n * so the components that consume that data must guard themselves.\n *\n * @param raw - The candidate URL, or `undefined` when none was supplied.\n * @returns The URL when safe to render, otherwise `undefined`.\n */\nexport function safeUrl(raw: string | undefined): string | undefined {\n\tif (raw === undefined || raw === \"\") return undefined;\n\t// Relative URLs have no scheme — `new URL(relative)` throws without a base,\n\t// so a thrown URL means either malformed input OR a relative path. Treat\n\t// \"throws + does not contain a colon\" as a relative path (safe).\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\treturn raw.includes(\":\") ? undefined : raw;\n\t}\n\treturn SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : undefined;\n}\n","\"use client\";\n\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/** Root container for an avatar (image + fallback). */\nconst Avatar = React.forwardRef<\n\tReact.ComponentRef<typeof AvatarPrimitive.Root>,\n\tReact.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>\n>(({ className, ...props }, ref) => (\n\t<AvatarPrimitive.Root\n\t\tref={ref}\n\t\tclassName={cn(\"relative flex h-[var(--control-height-md,2.5rem)] w-[var(--control-height-md,2.5rem)] shrink-0 overflow-hidden rounded-full\", className)}\n\t\t{...props}\n\t/>\n));\nAvatar.displayName = \"Avatar\";\n\n/** Avatar image. AvatarFallback renders in its place when the image is missing or errors. */\nconst AvatarImage = React.forwardRef<\n\tReact.ComponentRef<typeof AvatarPrimitive.Image>,\n\tReact.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>\n>(({ className, ...props }, ref) => (\n\t<AvatarPrimitive.Image\n\t\tref={ref}\n\t\tclassName={cn(\"aspect-square h-full w-full object-cover\", className)}\n\t\t{...props}\n\t/>\n));\nAvatarImage.displayName = \"AvatarImage\";\n\n/** Fallback content (usually initials or an icon) shown when the image is missing or fails. Supports delayMs to avoid flashing for fast-loading images. */\nconst AvatarFallback = React.forwardRef<\n\tReact.ComponentRef<typeof AvatarPrimitive.Fallback>,\n\tReact.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>\n>(({ className, ...props }, ref) => (\n\t<AvatarPrimitive.Fallback\n\t\tref={ref}\n\t\tclassName={cn(\n\t\t\t\"flex h-full w-full items-center justify-center rounded-full bg-muted text-sm font-medium text-muted-foreground\",\n\t\t\tclassName,\n\t\t)}\n\t\t{...props}\n\t/>\n));\nAvatarFallback.displayName = \"AvatarFallback\";\n\nexport { Avatar, AvatarImage, AvatarFallback };\n"]}
|
package/dist/badge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/utils.ts","../src/primitives/badge/badge.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACNA,IAAM,aAAA,GAAgB,GAAA;AAAA,EACrB;AAAA,IACC,kFAAA;AAAA,IACA,iEAAA;AAAA,IACA;AAAA,GACD,CAAE,KAAK,GAAG,CAAA;AAAA,EACV;AAAA,IACC,QAAA,EAAU;AAAA,MACT,OAAA,EAAS;AAAA,QACR,OAAA,EAAS,2EAAA;AAAA,QACT,SAAA,EACC,8GAAA;AAAA,QACD,WAAA,EACC,uFAAA;AAAA,QACD,OAAA,EAAS;AAAA;AACV,KACD;AAAA,IACA,eAAA,EAAiB;AAAA,MAChB,OAAA,EAAS;AAAA;AACV;AAEF;AAeA,SAAS,MAAM,EAAE,SAAA,EAAW,OAAA,EAAS,GAAG,OAAM,EAAe;AAC5D,EAAA,uBAAO,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,aAAA,CAAc,EAAE,OAAA,EAAS,CAAA,EAAG,SAAS,CAAA,EAAI,GAAG,KAAA,EAAO,CAAA;AAC9E","file":"badge.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 badgeVariants = cva(\n\t[\n\t\t\"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold\",\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].join(\" \"),\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault: \"border-transparent bg-primary text-primary-foreground hover:bg-primary/80\",\n\t\t\t\tsecondary:\n\t\t\t\t\t\"border-foreground/15 bg-secondary text-secondary-foreground hover:bg-secondary/80 hover:border-foreground/20\",\n\t\t\t\tdestructive:\n\t\t\t\t\t\"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80\",\n\t\t\t\toutline: \"border-foreground/20 text-foreground hover:border-foreground/30\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: {\n\t\t\tvariant: \"default\",\n\t\t},\n\t},\n);\n\n/**\n * A small status indicator badge with multiple style variants.\n * Used for tags, statuses, counts, and categorization.\n */\nexport interface BadgeProps\n\textends React.HTMLAttributes<HTMLDivElement>,\n\t\tVariantProps<typeof badgeVariants> {}\n\n/**\n * Renders an inline badge element with variant-based styling.\n * @param props - Badge props including variant and className\n * @returns A styled div element\n */\nfunction Badge({ className, variant, ...props }: BadgeProps) {\n\treturn <div className={cn(badgeVariants({ variant }), className)} {...props} />;\n}\n\nexport { Badge, badgeVariants };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/primitives/badge/badge.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACNA,IAAM,aAAA,GAAgB,GAAA;AAAA,EACrB;AAAA,IACC,kFAAA;AAAA,IACA,iEAAA;AAAA,IACA;AAAA,GACD,CAAE,KAAK,GAAG,CAAA;AAAA,EACV;AAAA,IACC,QAAA,EAAU;AAAA,MACT,OAAA,EAAS;AAAA,QACR,OAAA,EAAS,2EAAA;AAAA,QACT,SAAA,EACC,8GAAA;AAAA,QACD,WAAA,EACC,uFAAA;AAAA,QACD,OAAA,EAAS;AAAA;AACV,KACD;AAAA,IACA,eAAA,EAAiB;AAAA,MAChB,OAAA,EAAS;AAAA;AACV;AAEF;AAeA,SAAS,MAAM,EAAE,SAAA,EAAW,OAAA,EAAS,GAAG,OAAM,EAAe;AAC5D,EAAA,uBAAO,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,aAAA,CAAc,EAAE,OAAA,EAAS,CAAA,EAAG,SAAS,CAAA,EAAI,GAAG,KAAA,EAAO,CAAA;AAC9E","file":"badge.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\nconst SAFE_URL_SCHEMES = [\"http:\", \"https:\", \"mailto:\"] as const;\n\n/**\n * Allowlist a URL for use as an `<a href>` against untrusted input.\n *\n * Returns the raw string when it's `http(s):` / `mailto:` / a relative\n * URL (no scheme); returns `undefined` otherwise. Defends against\n * `javascript:` / `data:` / `vbscript:` injection from streamed model\n * output or third-party JSON payloads that flow into citation chips.\n *\n * Inside a Markdown render path, `rehype-sanitize` already strips\n * `javascript:` from inline-link hrefs — but it does NOT introspect\n * JSON nested inside attribute values (e.g. `<sources data='[…]'/>`),\n * so the components that consume that data must guard themselves.\n *\n * @param raw - The candidate URL, or `undefined` when none was supplied.\n * @returns The URL when safe to render, otherwise `undefined`.\n */\nexport function safeUrl(raw: string | undefined): string | undefined {\n\tif (raw === undefined || raw === \"\") return undefined;\n\t// Relative URLs have no scheme — `new URL(relative)` throws without a base,\n\t// so a thrown URL means either malformed input OR a relative path. Treat\n\t// \"throws + does not contain a colon\" as a relative path (safe).\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\treturn raw.includes(\":\") ? undefined : raw;\n\t}\n\treturn SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : undefined;\n}\n","import { type VariantProps, cva } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\nconst badgeVariants = cva(\n\t[\n\t\t\"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold\",\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].join(\" \"),\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault: \"border-transparent bg-primary text-primary-foreground hover:bg-primary/80\",\n\t\t\t\tsecondary:\n\t\t\t\t\t\"border-foreground/15 bg-secondary text-secondary-foreground hover:bg-secondary/80 hover:border-foreground/20\",\n\t\t\t\tdestructive:\n\t\t\t\t\t\"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80\",\n\t\t\t\toutline: \"border-foreground/20 text-foreground hover:border-foreground/30\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: {\n\t\t\tvariant: \"default\",\n\t\t},\n\t},\n);\n\n/**\n * A small status indicator badge with multiple style variants.\n * Used for tags, statuses, counts, and categorization.\n */\nexport interface BadgeProps\n\textends React.HTMLAttributes<HTMLDivElement>,\n\t\tVariantProps<typeof badgeVariants> {}\n\n/**\n * Renders an inline badge element with variant-based styling.\n * @param props - Badge props including variant and className\n * @returns A styled div element\n */\nfunction Badge({ className, variant, ...props }: BadgeProps) {\n\treturn <div className={cn(badgeVariants({ variant }), className)} {...props} />;\n}\n\nexport { Badge, badgeVariants };\n"]}
|
package/dist/branch.d.ts
ADDED
package/dist/branch.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
function cn(...inputs) {
|
|
7
|
+
return twMerge(clsx(inputs));
|
|
8
|
+
}
|
|
9
|
+
function Branch({
|
|
10
|
+
current,
|
|
11
|
+
total,
|
|
12
|
+
onCurrentChange,
|
|
13
|
+
children,
|
|
14
|
+
"aria-label": ariaLabel = "Response branches",
|
|
15
|
+
className
|
|
16
|
+
}) {
|
|
17
|
+
if (total <= 0) return null;
|
|
18
|
+
const interactive = typeof onCurrentChange === "function";
|
|
19
|
+
const atFirst = current <= 0;
|
|
20
|
+
const atLast = current >= total - 1;
|
|
21
|
+
function go(delta) {
|
|
22
|
+
if (!interactive) return;
|
|
23
|
+
const next = current + delta;
|
|
24
|
+
if (next < 0 || next > total - 1) return;
|
|
25
|
+
onCurrentChange(next);
|
|
26
|
+
}
|
|
27
|
+
function handleKeyDown(event) {
|
|
28
|
+
if (!interactive) return;
|
|
29
|
+
if (event.key === "ArrowLeft") {
|
|
30
|
+
event.preventDefault();
|
|
31
|
+
go(-1);
|
|
32
|
+
} else if (event.key === "ArrowRight") {
|
|
33
|
+
event.preventDefault();
|
|
34
|
+
go(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return /* @__PURE__ */ jsxs(
|
|
38
|
+
"div",
|
|
39
|
+
{
|
|
40
|
+
role: "group",
|
|
41
|
+
"aria-label": ariaLabel,
|
|
42
|
+
onKeyDown: handleKeyDown,
|
|
43
|
+
className: cn("flex flex-col gap-2", className),
|
|
44
|
+
children: [
|
|
45
|
+
/* @__PURE__ */ jsx("div", { children }),
|
|
46
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-end gap-1", children: [
|
|
47
|
+
/* @__PURE__ */ jsx(
|
|
48
|
+
"button",
|
|
49
|
+
{
|
|
50
|
+
type: "button",
|
|
51
|
+
"aria-label": "Previous response",
|
|
52
|
+
disabled: !interactive || atFirst,
|
|
53
|
+
onClick: () => go(-1),
|
|
54
|
+
className: cn(
|
|
55
|
+
"inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground",
|
|
56
|
+
"transition-all duration-[var(--duration-normal,200ms)] ease-out",
|
|
57
|
+
"hover:bg-muted hover:text-foreground",
|
|
58
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
59
|
+
"disabled:pointer-events-none disabled:opacity-40"
|
|
60
|
+
),
|
|
61
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, {})
|
|
62
|
+
}
|
|
63
|
+
),
|
|
64
|
+
/* @__PURE__ */ jsxs(
|
|
65
|
+
"span",
|
|
66
|
+
{
|
|
67
|
+
"aria-live": interactive ? "polite" : void 0,
|
|
68
|
+
"aria-atomic": interactive ? "true" : void 0,
|
|
69
|
+
className: "select-none px-1 text-xs tabular-nums text-muted-foreground",
|
|
70
|
+
children: [
|
|
71
|
+
current + 1,
|
|
72
|
+
" of ",
|
|
73
|
+
total
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
),
|
|
77
|
+
/* @__PURE__ */ jsx(
|
|
78
|
+
"button",
|
|
79
|
+
{
|
|
80
|
+
type: "button",
|
|
81
|
+
"aria-label": "Next response",
|
|
82
|
+
disabled: !interactive || atLast,
|
|
83
|
+
onClick: () => go(1),
|
|
84
|
+
className: cn(
|
|
85
|
+
"inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground",
|
|
86
|
+
"transition-all duration-[var(--duration-normal,200ms)] ease-out",
|
|
87
|
+
"hover:bg-muted hover:text-foreground",
|
|
88
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
89
|
+
"disabled:pointer-events-none disabled:opacity-40"
|
|
90
|
+
),
|
|
91
|
+
children: /* @__PURE__ */ jsx(ChevronRight, {})
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
] })
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
function ChevronLeft() {
|
|
100
|
+
return /* @__PURE__ */ jsx(
|
|
101
|
+
"svg",
|
|
102
|
+
{
|
|
103
|
+
"aria-hidden": true,
|
|
104
|
+
viewBox: "0 0 16 16",
|
|
105
|
+
width: "14",
|
|
106
|
+
height: "14",
|
|
107
|
+
fill: "none",
|
|
108
|
+
stroke: "currentColor",
|
|
109
|
+
strokeWidth: "1.75",
|
|
110
|
+
strokeLinecap: "round",
|
|
111
|
+
strokeLinejoin: "round",
|
|
112
|
+
children: /* @__PURE__ */ jsx("path", { d: "M10 4l-4 4 4 4" })
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
function ChevronRight() {
|
|
117
|
+
return /* @__PURE__ */ jsx(
|
|
118
|
+
"svg",
|
|
119
|
+
{
|
|
120
|
+
"aria-hidden": true,
|
|
121
|
+
viewBox: "0 0 16 16",
|
|
122
|
+
width: "14",
|
|
123
|
+
height: "14",
|
|
124
|
+
fill: "none",
|
|
125
|
+
stroke: "currentColor",
|
|
126
|
+
strokeWidth: "1.75",
|
|
127
|
+
strokeLinecap: "round",
|
|
128
|
+
strokeLinejoin: "round",
|
|
129
|
+
children: /* @__PURE__ */ jsx("path", { d: "M6 4l4 4-4 4" })
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export { Branch };
|
|
135
|
+
//# sourceMappingURL=branch.js.map
|
|
136
|
+
//# sourceMappingURL=branch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/ai/branch/branch.tsx"],"names":[],"mappings":"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","file":"branch.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\nconst SAFE_URL_SCHEMES = [\"http:\", \"https:\", \"mailto:\"] as const;\n\n/**\n * Allowlist a URL for use as an `<a href>` against untrusted input.\n *\n * Returns the raw string when it's `http(s):` / `mailto:` / a relative\n * URL (no scheme); returns `undefined` otherwise. Defends against\n * `javascript:` / `data:` / `vbscript:` injection from streamed model\n * output or third-party JSON payloads that flow into citation chips.\n *\n * Inside a Markdown render path, `rehype-sanitize` already strips\n * `javascript:` from inline-link hrefs — but it does NOT introspect\n * JSON nested inside attribute values (e.g. `<sources data='[…]'/>`),\n * so the components that consume that data must guard themselves.\n *\n * @param raw - The candidate URL, or `undefined` when none was supplied.\n * @returns The URL when safe to render, otherwise `undefined`.\n */\nexport function safeUrl(raw: string | undefined): string | undefined {\n\tif (raw === undefined || raw === \"\") return undefined;\n\t// Relative URLs have no scheme — `new URL(relative)` throws without a base,\n\t// so a thrown URL means either malformed input OR a relative path. Treat\n\t// \"throws + does not contain a colon\" as a relative path (safe).\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\treturn raw.includes(\":\") ? undefined : raw;\n\t}\n\treturn SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : undefined;\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * Headless alternate-response navigator. Renders the active branch\n * (`children`) with a prev/next control chip beneath it. Stateless —\n * the consumer owns `current` (zero-indexed) and `total`.\n *\n * Keyboard: ArrowLeft / ArrowRight step through branches when focus\n * lives anywhere inside the group (the wrapper itself is not focusable;\n * the prev/next buttons or any focusable descendant carry the keys).\n * Read-only when `onCurrentChange` is omitted.\n *\n * @example\n * <Branch current={index} total={alternatives.length} onCurrentChange={setIndex}>\n * <Message role=\"assistant\">\n * <Markdown>{alternatives[index]}</Markdown>\n * </Message>\n * </Branch>\n */\nexport interface BranchProps {\n\t/** Zero-indexed active branch. */\n\tcurrent: number;\n\t/** Total number of branches. */\n\ttotal: number;\n\t/** Optional change handler — when omitted, the controls render disabled. */\n\tonCurrentChange?: (next: number) => void;\n\t/** The active branch content (typically a `<Message>` or `<Markdown>`). */\n\tchildren: React.ReactNode;\n\t/** Override the accessible label for the navigator landmark. */\n\t\"aria-label\"?: string;\n\tclassName?: string;\n}\n\n/**\n * Render a single-active-branch navigator with prev/next controls.\n * @param props - current/total + change handler + body\n * @returns A nav landmark wrapping the active branch and a control chip\n */\nfunction Branch({\n\tcurrent,\n\ttotal,\n\tonCurrentChange,\n\tchildren,\n\t\"aria-label\": ariaLabel = \"Response branches\",\n\tclassName,\n}: BranchProps) {\n\t// `total === 0` is a nonsense state (no branches to navigate) — render\n\t// nothing so the chip never reads \"1 of 0\". Consumers should guard\n\t// upstream, but a defensive return beats nonsensical UI.\n\tif (total <= 0) return null;\n\tconst interactive = typeof onCurrentChange === \"function\";\n\tconst atFirst = current <= 0;\n\tconst atLast = current >= total - 1;\n\n\tfunction go(delta: number) {\n\t\tif (!interactive) return;\n\t\tconst next = current + delta;\n\t\tif (next < 0 || next > total - 1) return;\n\t\tonCurrentChange(next);\n\t}\n\n\tfunction handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {\n\t\tif (!interactive) return;\n\t\tif (event.key === \"ArrowLeft\") {\n\t\t\tevent.preventDefault();\n\t\t\tgo(-1);\n\t\t} else if (event.key === \"ArrowRight\") {\n\t\t\tevent.preventDefault();\n\t\t\tgo(1);\n\t\t}\n\t}\n\n\treturn (\n\t\t<div\n\t\t\trole=\"group\"\n\t\t\taria-label={ariaLabel}\n\t\t\tonKeyDown={handleKeyDown}\n\t\t\tclassName={cn(\"flex flex-col gap-2\", className)}\n\t\t>\n\t\t\t<div>{children}</div>\n\t\t\t<div className=\"flex items-center justify-end gap-1\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\taria-label=\"Previous response\"\n\t\t\t\t\tdisabled={!interactive || atFirst}\n\t\t\t\t\tonClick={() => go(-1)}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground\",\n\t\t\t\t\t\t\"transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\t\t\t\"hover:bg-muted hover:text-foreground\",\n\t\t\t\t\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n\t\t\t\t\t\t\"disabled:pointer-events-none disabled:opacity-40\",\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t<ChevronLeft />\n\t\t\t\t</button>\n\t\t\t\t<span\n\t\t\t\t\t/*\n\t\t\t\t\t * Live-region only when the consumer wired up navigation —\n\t\t\t\t\t * read-only branches don't change, so announcing every\n\t\t\t\t\t * mount would be noise in a chat surface with many\n\t\t\t\t\t * <Branch> blocks. aria-atomic ensures the chip reads as\n\t\t\t\t\t * one unit (\"2 of 3\") rather than two diff'd numbers.\n\t\t\t\t\t */\n\t\t\t\t\taria-live={interactive ? \"polite\" : undefined}\n\t\t\t\t\taria-atomic={interactive ? \"true\" : undefined}\n\t\t\t\t\tclassName=\"select-none px-1 text-xs tabular-nums text-muted-foreground\"\n\t\t\t\t>\n\t\t\t\t\t{current + 1} of {total}\n\t\t\t\t</span>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\taria-label=\"Next response\"\n\t\t\t\t\tdisabled={!interactive || atLast}\n\t\t\t\t\tonClick={() => go(1)}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground\",\n\t\t\t\t\t\t\"transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\t\t\t\"hover:bg-muted hover:text-foreground\",\n\t\t\t\t\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n\t\t\t\t\t\t\"disabled:pointer-events-none disabled:opacity-40\",\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t<ChevronRight />\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nfunction ChevronLeft() {\n\treturn (\n\t\t<svg\n\t\t\taria-hidden\n\t\t\tviewBox=\"0 0 16 16\"\n\t\t\twidth=\"14\"\n\t\t\theight=\"14\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth=\"1.75\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t>\n\t\t\t<path d=\"M10 4l-4 4 4 4\" />\n\t\t</svg>\n\t);\n}\n\nfunction ChevronRight() {\n\treturn (\n\t\t<svg\n\t\t\taria-hidden\n\t\t\tviewBox=\"0 0 16 16\"\n\t\t\twidth=\"14\"\n\t\t\theight=\"14\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth=\"1.75\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t>\n\t\t\t<path d=\"M6 4l4 4-4 4\" />\n\t\t</svg>\n\t);\n}\n\nexport { Branch };\n"]}
|