@tangle-network/sandbox-ui 0.10.3 → 0.10.5
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/{chunk-D4CZWJCD.js → chunk-36QY2W5G.js} +187 -90
- package/dist/{chunk-OHPW55EV.js → chunk-QMU2PWOU.js} +3 -1
- package/dist/{chunk-7LBHRASD.js → chunk-Z5PSS3VD.js} +127 -58
- package/dist/dashboard.d.ts +2 -2
- package/dist/dashboard.js +7 -3
- package/dist/globals.css +27 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/pages.d.ts +16 -2
- package/dist/pages.js +552 -187
- package/dist/primitives.d.ts +48 -296
- package/dist/primitives.js +3 -1
- package/dist/sidebar-drop-zone-tDBsuOH5.d.ts +301 -0
- package/dist/styles.css +27 -0
- package/dist/{usage-chart-SSiOgeQI.d.ts → usage-chart-CPTcNlGs.d.ts} +8 -1
- package/dist/{variant-list-DHP2OXFE.d.ts → variant-list-DAhiR-7S.d.ts} +14 -1
- package/package.json +1 -1
|
@@ -115,11 +115,107 @@ var SelectSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__P
|
|
|
115
115
|
));
|
|
116
116
|
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
117
117
|
|
|
118
|
+
// src/primitives/segmented-control.tsx
|
|
119
|
+
import * as React2 from "react";
|
|
120
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
121
|
+
function SegmentedControl({
|
|
122
|
+
value,
|
|
123
|
+
onValueChange,
|
|
124
|
+
options,
|
|
125
|
+
variant = "row",
|
|
126
|
+
className,
|
|
127
|
+
...rest
|
|
128
|
+
}) {
|
|
129
|
+
if (typeof process !== "undefined" && process?.env?.NODE_ENV !== "production" && !rest["aria-label"] && !rest["aria-labelledby"]) {
|
|
130
|
+
console.warn(
|
|
131
|
+
'[SegmentedControl] role="radiogroup" requires either aria-label or aria-labelledby for accessibility.'
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
const optionRefs = React2.useRef(/* @__PURE__ */ new Map());
|
|
135
|
+
const hasMatch = options.some((o) => o.value === value);
|
|
136
|
+
const handleKeyDown = (e) => {
|
|
137
|
+
if (options.length === 0) return;
|
|
138
|
+
let idx = options.findIndex((o) => o.value === value);
|
|
139
|
+
if (idx === -1) idx = 0;
|
|
140
|
+
let next;
|
|
141
|
+
if (e.key === "ArrowRight" || e.key === "ArrowDown") next = (idx + 1) % options.length;
|
|
142
|
+
else if (e.key === "ArrowLeft" || e.key === "ArrowUp") next = (idx - 1 + options.length) % options.length;
|
|
143
|
+
else if (e.key === "Home") next = 0;
|
|
144
|
+
else if (e.key === "End") next = options.length - 1;
|
|
145
|
+
if (next !== void 0) {
|
|
146
|
+
e.preventDefault();
|
|
147
|
+
if (options[next].value !== value) {
|
|
148
|
+
onValueChange(options[next].value);
|
|
149
|
+
}
|
|
150
|
+
optionRefs.current.get(options[next].value)?.focus();
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
return /* @__PURE__ */ jsx2(
|
|
154
|
+
"div",
|
|
155
|
+
{
|
|
156
|
+
role: "radiogroup",
|
|
157
|
+
id: rest.id,
|
|
158
|
+
"aria-label": rest["aria-label"],
|
|
159
|
+
"aria-labelledby": rest["aria-labelledby"],
|
|
160
|
+
onKeyDown: handleKeyDown,
|
|
161
|
+
className: cn(
|
|
162
|
+
"flex gap-1",
|
|
163
|
+
variant === "row" && "flex-wrap items-center rounded-lg border border-border bg-card p-1",
|
|
164
|
+
variant === "tabs" && "flex-nowrap items-end border-b border-border pb-0 overflow-x-auto",
|
|
165
|
+
className
|
|
166
|
+
),
|
|
167
|
+
children: options.map((option, i) => {
|
|
168
|
+
const active = option.value === value;
|
|
169
|
+
const focusable = active || !hasMatch && i === 0;
|
|
170
|
+
return /* @__PURE__ */ jsxs2(
|
|
171
|
+
"button",
|
|
172
|
+
{
|
|
173
|
+
ref: (el) => {
|
|
174
|
+
if (el) optionRefs.current.set(option.value, el);
|
|
175
|
+
else optionRefs.current.delete(option.value);
|
|
176
|
+
},
|
|
177
|
+
type: "button",
|
|
178
|
+
role: "radio",
|
|
179
|
+
"aria-checked": active,
|
|
180
|
+
tabIndex: focusable ? 0 : -1,
|
|
181
|
+
onClick: () => {
|
|
182
|
+
if (!active) onValueChange(option.value);
|
|
183
|
+
},
|
|
184
|
+
className: cn(
|
|
185
|
+
"relative inline-flex items-center gap-2 whitespace-nowrap text-sm transition-colors",
|
|
186
|
+
variant === "row" && "rounded-md px-3 py-1.5",
|
|
187
|
+
variant === "tabs" && "rounded-none border-b-2 -mb-px px-4 py-2",
|
|
188
|
+
// Active styling is the ONLY styled state — unselected
|
|
189
|
+
// segments stay transparent on purpose so they don't
|
|
190
|
+
// compete visually with the selection.
|
|
191
|
+
active ? variant === "row" ? "border border-transparent bg-[var(--accent-surface)] text-[var(--accent-text)] font-semibold" : "border-[var(--accent-text)] text-[var(--accent-text)] font-semibold" : variant === "row" ? "border border-transparent text-muted-foreground hover:text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"
|
|
192
|
+
),
|
|
193
|
+
children: [
|
|
194
|
+
/* @__PURE__ */ jsx2("span", { children: option.label }),
|
|
195
|
+
option.adornment && /* @__PURE__ */ jsx2(
|
|
196
|
+
"span",
|
|
197
|
+
{
|
|
198
|
+
className: cn(
|
|
199
|
+
"text-xs",
|
|
200
|
+
active ? "text-[var(--accent-text)]/80" : "text-muted-foreground"
|
|
201
|
+
),
|
|
202
|
+
children: option.adornment
|
|
203
|
+
}
|
|
204
|
+
)
|
|
205
|
+
]
|
|
206
|
+
},
|
|
207
|
+
option.value
|
|
208
|
+
);
|
|
209
|
+
})
|
|
210
|
+
}
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
118
214
|
// src/primitives/switch.tsx
|
|
119
215
|
import * as SwitchPrimitives from "@radix-ui/react-switch";
|
|
120
|
-
import * as
|
|
121
|
-
import { jsx as
|
|
122
|
-
var Switch =
|
|
216
|
+
import * as React3 from "react";
|
|
217
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
218
|
+
var Switch = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx3(
|
|
123
219
|
SwitchPrimitives.Root,
|
|
124
220
|
{
|
|
125
221
|
className: cn(
|
|
@@ -128,7 +224,7 @@ var Switch = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
128
224
|
),
|
|
129
225
|
...props,
|
|
130
226
|
ref,
|
|
131
|
-
children: /* @__PURE__ */
|
|
227
|
+
children: /* @__PURE__ */ jsx3(
|
|
132
228
|
SwitchPrimitives.Thumb,
|
|
133
229
|
{
|
|
134
230
|
className: cn(
|
|
@@ -149,8 +245,8 @@ import {
|
|
|
149
245
|
Info,
|
|
150
246
|
X
|
|
151
247
|
} from "lucide-react";
|
|
152
|
-
import * as
|
|
153
|
-
import { jsx as
|
|
248
|
+
import * as React4 from "react";
|
|
249
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
154
250
|
var toastVariants = cva(
|
|
155
251
|
"pointer-events-auto relative flex w-full items-center justify-between gap-3 overflow-hidden rounded-lg border p-4 shadow-lg transition-all",
|
|
156
252
|
{
|
|
@@ -183,28 +279,28 @@ function ToastComponent({
|
|
|
183
279
|
onDismiss
|
|
184
280
|
}) {
|
|
185
281
|
const Icon2 = icons[variant];
|
|
186
|
-
return /* @__PURE__ */
|
|
282
|
+
return /* @__PURE__ */ jsxs3(
|
|
187
283
|
"div",
|
|
188
284
|
{
|
|
189
285
|
className: cn(toastVariants({ variant })),
|
|
190
286
|
role: "alert",
|
|
191
287
|
"aria-live": "polite",
|
|
192
288
|
children: [
|
|
193
|
-
/* @__PURE__ */
|
|
194
|
-
/* @__PURE__ */
|
|
195
|
-
/* @__PURE__ */
|
|
196
|
-
/* @__PURE__ */
|
|
197
|
-
description && /* @__PURE__ */
|
|
289
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-start gap-3", children: [
|
|
290
|
+
/* @__PURE__ */ jsx4(Icon2, { className: "h-5 w-5 shrink-0", "aria-hidden": "true" }),
|
|
291
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex-1", children: [
|
|
292
|
+
/* @__PURE__ */ jsx4("p", { className: "font-medium text-sm", children: title }),
|
|
293
|
+
description && /* @__PURE__ */ jsx4("p", { className: "mt-1 text-sm opacity-80", children: description })
|
|
198
294
|
] })
|
|
199
295
|
] }),
|
|
200
|
-
/* @__PURE__ */
|
|
296
|
+
/* @__PURE__ */ jsx4(
|
|
201
297
|
"button",
|
|
202
298
|
{
|
|
203
299
|
type: "button",
|
|
204
300
|
onClick: () => onDismiss(id),
|
|
205
301
|
className: "shrink-0 rounded-md p-1 opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2",
|
|
206
302
|
"aria-label": "Dismiss notification",
|
|
207
|
-
children: /* @__PURE__ */
|
|
303
|
+
children: /* @__PURE__ */ jsx4(X, { className: "h-4 w-4" })
|
|
208
304
|
}
|
|
209
305
|
)
|
|
210
306
|
]
|
|
@@ -212,22 +308,22 @@ function ToastComponent({
|
|
|
212
308
|
);
|
|
213
309
|
}
|
|
214
310
|
function ToastContainer({ toasts, onDismiss }) {
|
|
215
|
-
return /* @__PURE__ */
|
|
311
|
+
return /* @__PURE__ */ jsx4(
|
|
216
312
|
"div",
|
|
217
313
|
{
|
|
218
314
|
className: "fixed right-4 bottom-4 z-50 flex max-w-md flex-col gap-2",
|
|
219
315
|
"aria-label": "Notifications",
|
|
220
|
-
children: toasts.map((toast) => /* @__PURE__ */
|
|
316
|
+
children: toasts.map((toast) => /* @__PURE__ */ jsx4(ToastComponent, { ...toast, onDismiss }, toast.id))
|
|
221
317
|
}
|
|
222
318
|
);
|
|
223
319
|
}
|
|
224
|
-
var ToastContext =
|
|
320
|
+
var ToastContext = React4.createContext(null);
|
|
225
321
|
function ToastProvider({ children }) {
|
|
226
|
-
const [toasts, setToasts] =
|
|
227
|
-
const dismiss =
|
|
322
|
+
const [toasts, setToasts] = React4.useState([]);
|
|
323
|
+
const dismiss = React4.useCallback((id) => {
|
|
228
324
|
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
229
325
|
}, []);
|
|
230
|
-
const toast =
|
|
326
|
+
const toast = React4.useCallback(
|
|
231
327
|
(input) => {
|
|
232
328
|
const id = Math.random().toString(36).slice(2);
|
|
233
329
|
const newToast = { id, ...input };
|
|
@@ -239,41 +335,41 @@ function ToastProvider({ children }) {
|
|
|
239
335
|
},
|
|
240
336
|
[dismiss]
|
|
241
337
|
);
|
|
242
|
-
const success =
|
|
338
|
+
const success = React4.useCallback(
|
|
243
339
|
(title, description) => {
|
|
244
340
|
toast({ title, description, variant: "success" });
|
|
245
341
|
},
|
|
246
342
|
[toast]
|
|
247
343
|
);
|
|
248
|
-
const error =
|
|
344
|
+
const error = React4.useCallback(
|
|
249
345
|
(title, description) => {
|
|
250
346
|
toast({ title, description, variant: "error" });
|
|
251
347
|
},
|
|
252
348
|
[toast]
|
|
253
349
|
);
|
|
254
|
-
const warning =
|
|
350
|
+
const warning = React4.useCallback(
|
|
255
351
|
(title, description) => {
|
|
256
352
|
toast({ title, description, variant: "warning" });
|
|
257
353
|
},
|
|
258
354
|
[toast]
|
|
259
355
|
);
|
|
260
|
-
const info =
|
|
356
|
+
const info = React4.useCallback(
|
|
261
357
|
(title, description) => {
|
|
262
358
|
toast({ title, description, variant: "info" });
|
|
263
359
|
},
|
|
264
360
|
[toast]
|
|
265
361
|
);
|
|
266
|
-
const value =
|
|
362
|
+
const value = React4.useMemo(
|
|
267
363
|
() => ({ toasts, toast, success, error, warning, info, dismiss }),
|
|
268
364
|
[toasts, toast, success, error, warning, info, dismiss]
|
|
269
365
|
);
|
|
270
|
-
return /* @__PURE__ */
|
|
366
|
+
return /* @__PURE__ */ jsxs3(ToastContext.Provider, { value, children: [
|
|
271
367
|
children,
|
|
272
|
-
/* @__PURE__ */
|
|
368
|
+
/* @__PURE__ */ jsx4(ToastContainer, { toasts, onDismiss: dismiss })
|
|
273
369
|
] });
|
|
274
370
|
}
|
|
275
371
|
function useToast() {
|
|
276
|
-
const context =
|
|
372
|
+
const context = React4.useContext(ToastContext);
|
|
277
373
|
if (!context) {
|
|
278
374
|
throw new Error("useToast must be used within a ToastProvider");
|
|
279
375
|
}
|
|
@@ -283,12 +379,12 @@ function useToast() {
|
|
|
283
379
|
// src/primitives/label.tsx
|
|
284
380
|
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
285
381
|
import { cva as cva2 } from "class-variance-authority";
|
|
286
|
-
import * as
|
|
287
|
-
import { jsx as
|
|
382
|
+
import * as React5 from "react";
|
|
383
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
288
384
|
var labelVariants = cva2(
|
|
289
385
|
"font-medium text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
|
290
386
|
);
|
|
291
|
-
var Label2 =
|
|
387
|
+
var Label2 = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx5(
|
|
292
388
|
LabelPrimitive.Root,
|
|
293
389
|
{
|
|
294
390
|
ref,
|
|
@@ -299,10 +395,10 @@ var Label2 = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
299
395
|
Label2.displayName = LabelPrimitive.Root.displayName;
|
|
300
396
|
|
|
301
397
|
// src/primitives/terminal-display.tsx
|
|
302
|
-
import * as
|
|
303
|
-
import { useEffect, useRef } from "react";
|
|
304
|
-
import { jsx as
|
|
305
|
-
var TerminalDisplay =
|
|
398
|
+
import * as React6 from "react";
|
|
399
|
+
import { useEffect, useRef as useRef2 } from "react";
|
|
400
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
401
|
+
var TerminalDisplay = React6.forwardRef(
|
|
306
402
|
({
|
|
307
403
|
className,
|
|
308
404
|
variant = "default",
|
|
@@ -313,7 +409,7 @@ var TerminalDisplay = React5.forwardRef(
|
|
|
313
409
|
children,
|
|
314
410
|
...props
|
|
315
411
|
}, ref) => {
|
|
316
|
-
const containerRef =
|
|
412
|
+
const containerRef = useRef2(null);
|
|
317
413
|
useEffect(() => {
|
|
318
414
|
if (autoScroll && containerRef.current) {
|
|
319
415
|
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
|
@@ -323,7 +419,7 @@ var TerminalDisplay = React5.forwardRef(
|
|
|
323
419
|
default: "border-border",
|
|
324
420
|
sandbox: "border-border shadow-[var(--shadow-accent)]"
|
|
325
421
|
};
|
|
326
|
-
return /* @__PURE__ */
|
|
422
|
+
return /* @__PURE__ */ jsxs4(
|
|
327
423
|
"div",
|
|
328
424
|
{
|
|
329
425
|
ref,
|
|
@@ -334,8 +430,8 @@ var TerminalDisplay = React5.forwardRef(
|
|
|
334
430
|
),
|
|
335
431
|
...props,
|
|
336
432
|
children: [
|
|
337
|
-
showHeader && /* @__PURE__ */
|
|
338
|
-
/* @__PURE__ */
|
|
433
|
+
showHeader && /* @__PURE__ */ jsx6("div", { className: "flex items-center border-b border-border bg-card px-4 py-3", children: /* @__PURE__ */ jsx6("span", { className: "text-muted-foreground text-xs", children: title }) }),
|
|
434
|
+
/* @__PURE__ */ jsx6(
|
|
339
435
|
"div",
|
|
340
436
|
{
|
|
341
437
|
ref: containerRef,
|
|
@@ -350,7 +446,7 @@ var TerminalDisplay = React5.forwardRef(
|
|
|
350
446
|
}
|
|
351
447
|
);
|
|
352
448
|
TerminalDisplay.displayName = "TerminalDisplay";
|
|
353
|
-
var TerminalLine =
|
|
449
|
+
var TerminalLine = React6.forwardRef(
|
|
354
450
|
({ className, type = "output", prompt = "$", timestamp, children, ...props }, ref) => {
|
|
355
451
|
const typeStyles = {
|
|
356
452
|
input: "text-foreground",
|
|
@@ -362,7 +458,7 @@ var TerminalLine = React5.forwardRef(
|
|
|
362
458
|
command: "text-foreground",
|
|
363
459
|
warning: "text-[var(--surface-warning-text)]"
|
|
364
460
|
};
|
|
365
|
-
return /* @__PURE__ */
|
|
461
|
+
return /* @__PURE__ */ jsxs4(
|
|
366
462
|
"div",
|
|
367
463
|
{
|
|
368
464
|
ref,
|
|
@@ -373,21 +469,21 @@ var TerminalLine = React5.forwardRef(
|
|
|
373
469
|
),
|
|
374
470
|
...props,
|
|
375
471
|
children: [
|
|
376
|
-
(type === "input" || type === "command") && /* @__PURE__ */
|
|
377
|
-
type === "thinking" && /* @__PURE__ */
|
|
378
|
-
timestamp && /* @__PURE__ */
|
|
472
|
+
(type === "input" || type === "command") && /* @__PURE__ */ jsx6("span", { className: "shrink-0 select-none text-[var(--surface-success-text)]", children: prompt }),
|
|
473
|
+
type === "thinking" && /* @__PURE__ */ jsx6("span", { className: "shrink-0 select-none", children: "..." }),
|
|
474
|
+
timestamp && /* @__PURE__ */ jsxs4("span", { className: "shrink-0 select-none text-muted-foreground opacity-50", children: [
|
|
379
475
|
"[",
|
|
380
476
|
timestamp,
|
|
381
477
|
"]"
|
|
382
478
|
] }),
|
|
383
|
-
/* @__PURE__ */
|
|
479
|
+
/* @__PURE__ */ jsx6("span", { className: "whitespace-pre-wrap break-all", children })
|
|
384
480
|
]
|
|
385
481
|
}
|
|
386
482
|
);
|
|
387
483
|
}
|
|
388
484
|
);
|
|
389
485
|
TerminalLine.displayName = "TerminalLine";
|
|
390
|
-
var TerminalCursor =
|
|
486
|
+
var TerminalCursor = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx6(
|
|
391
487
|
"span",
|
|
392
488
|
{
|
|
393
489
|
ref,
|
|
@@ -399,9 +495,9 @@ var TerminalCursor = React5.forwardRef(({ className, ...props }, ref) => /* @__P
|
|
|
399
495
|
}
|
|
400
496
|
));
|
|
401
497
|
TerminalCursor.displayName = "TerminalCursor";
|
|
402
|
-
var TerminalInput =
|
|
498
|
+
var TerminalInput = React6.forwardRef(
|
|
403
499
|
({ className, onSubmit, variant = "default", ...props }, ref) => {
|
|
404
|
-
const [value, setValue] =
|
|
500
|
+
const [value, setValue] = React6.useState("");
|
|
405
501
|
const handleKeyDown = (e) => {
|
|
406
502
|
if (e.key === "Enter" && value.trim() && onSubmit) {
|
|
407
503
|
onSubmit(value.trim());
|
|
@@ -412,7 +508,7 @@ var TerminalInput = React5.forwardRef(
|
|
|
412
508
|
default: "border-border focus-within:border-border",
|
|
413
509
|
sandbox: "border-border focus-within:border-[var(--border-accent-hover)]"
|
|
414
510
|
};
|
|
415
|
-
return /* @__PURE__ */
|
|
511
|
+
return /* @__PURE__ */ jsxs4(
|
|
416
512
|
"div",
|
|
417
513
|
{
|
|
418
514
|
className: cn(
|
|
@@ -421,8 +517,8 @@ var TerminalInput = React5.forwardRef(
|
|
|
421
517
|
className
|
|
422
518
|
),
|
|
423
519
|
children: [
|
|
424
|
-
/* @__PURE__ */
|
|
425
|
-
/* @__PURE__ */
|
|
520
|
+
/* @__PURE__ */ jsx6("span", { className: "mr-2 select-none text-[var(--surface-success-text)]", children: "$" }),
|
|
521
|
+
/* @__PURE__ */ jsx6(
|
|
426
522
|
"input",
|
|
427
523
|
{
|
|
428
524
|
ref,
|
|
@@ -434,7 +530,7 @@ var TerminalInput = React5.forwardRef(
|
|
|
434
530
|
...props
|
|
435
531
|
}
|
|
436
532
|
),
|
|
437
|
-
/* @__PURE__ */
|
|
533
|
+
/* @__PURE__ */ jsx6(TerminalCursor, {})
|
|
438
534
|
]
|
|
439
535
|
}
|
|
440
536
|
);
|
|
@@ -443,8 +539,8 @@ var TerminalInput = React5.forwardRef(
|
|
|
443
539
|
TerminalInput.displayName = "TerminalInput";
|
|
444
540
|
|
|
445
541
|
// src/primitives/drop-zone.tsx
|
|
446
|
-
import { useCallback as useCallback2, useRef as
|
|
447
|
-
import { jsx as
|
|
542
|
+
import { useCallback as useCallback2, useRef as useRef3, useState as useState3 } from "react";
|
|
543
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
448
544
|
function DropZone({
|
|
449
545
|
onDrop,
|
|
450
546
|
accept,
|
|
@@ -457,7 +553,7 @@ function DropZone({
|
|
|
457
553
|
className
|
|
458
554
|
}) {
|
|
459
555
|
const [dragOver, setDragOver] = useState3(false);
|
|
460
|
-
const counter =
|
|
556
|
+
const counter = useRef3(0);
|
|
461
557
|
const isAccepted = useCallback2(
|
|
462
558
|
(file) => {
|
|
463
559
|
if (!accept) return true;
|
|
@@ -500,7 +596,7 @@ function DropZone({
|
|
|
500
596
|
},
|
|
501
597
|
[disabled, accept, isAccepted, onDrop]
|
|
502
598
|
);
|
|
503
|
-
return /* @__PURE__ */
|
|
599
|
+
return /* @__PURE__ */ jsxs5(
|
|
504
600
|
"div",
|
|
505
601
|
{
|
|
506
602
|
onDragEnter: handleDragEnter,
|
|
@@ -509,15 +605,15 @@ function DropZone({
|
|
|
509
605
|
onDrop: handleDrop,
|
|
510
606
|
className: cn("relative", className),
|
|
511
607
|
children: [
|
|
512
|
-
dragOver && (overlay || /* @__PURE__ */
|
|
513
|
-
/* @__PURE__ */
|
|
514
|
-
/* @__PURE__ */
|
|
515
|
-
/* @__PURE__ */
|
|
516
|
-
/* @__PURE__ */
|
|
517
|
-
/* @__PURE__ */
|
|
608
|
+
dragOver && (overlay || /* @__PURE__ */ jsx7("div", { className: "fixed inset-0 z-[100] flex items-center justify-center pointer-events-none bg-background", children: /* @__PURE__ */ jsxs5("div", { className: "rounded-2xl border-2 border-dashed border-border bg-card p-16 text-center shadow-[var(--shadow-dropdown)] max-w-lg mx-auto", children: [
|
|
609
|
+
/* @__PURE__ */ jsx7("div", { className: "mx-auto mb-6 flex h-20 w-20 items-center justify-center rounded-2xl border border-border bg-[var(--accent-surface-soft)]", children: typeof icon === "string" ? /* @__PURE__ */ jsxs5("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", className: "h-10 w-10 text-[var(--accent-text)]", children: [
|
|
610
|
+
/* @__PURE__ */ jsx7("title", { children: "Upload" }),
|
|
611
|
+
/* @__PURE__ */ jsx7("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
612
|
+
/* @__PURE__ */ jsx7("polyline", { points: "17 8 12 3 7 8" }),
|
|
613
|
+
/* @__PURE__ */ jsx7("line", { x1: "12", x2: "12", y1: "3", y2: "15" })
|
|
518
614
|
] }) : icon }),
|
|
519
|
-
/* @__PURE__ */
|
|
520
|
-
/* @__PURE__ */
|
|
615
|
+
/* @__PURE__ */ jsx7("h2", { className: "text-2xl font-bold text-foreground", children: title }),
|
|
616
|
+
/* @__PURE__ */ jsx7("p", { className: "mt-2 text-sm text-muted-foreground", children: description })
|
|
521
617
|
] }) })),
|
|
522
618
|
children
|
|
523
619
|
]
|
|
@@ -527,7 +623,7 @@ function DropZone({
|
|
|
527
623
|
|
|
528
624
|
// src/primitives/upload-progress.tsx
|
|
529
625
|
import { AlertCircle as AlertCircle2, CheckCircle2 as CheckCircle22, FileText, Loader2, RefreshCw, X as X2 } from "lucide-react";
|
|
530
|
-
import { jsx as
|
|
626
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
531
627
|
function formatSize(bytes) {
|
|
532
628
|
if (bytes < 1024) return `${bytes}B`;
|
|
533
629
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)}KB`;
|
|
@@ -535,7 +631,7 @@ function formatSize(bytes) {
|
|
|
535
631
|
}
|
|
536
632
|
function UploadProgress({ files, onRemove, onRetry, className }) {
|
|
537
633
|
if (files.length === 0) return null;
|
|
538
|
-
return /* @__PURE__ */
|
|
634
|
+
return /* @__PURE__ */ jsx8("div", { className: cn("space-y-2", className), children: files.map((file) => /* @__PURE__ */ jsxs6(
|
|
539
635
|
"div",
|
|
540
636
|
{
|
|
541
637
|
className: cn(
|
|
@@ -543,41 +639,41 @@ function UploadProgress({ files, onRemove, onRetry, className }) {
|
|
|
543
639
|
file.status === "error" ? "border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)]" : file.status === "complete" ? "border-[var(--surface-success-border)] bg-[var(--surface-success-bg)]" : "border-border bg-card"
|
|
544
640
|
),
|
|
545
641
|
children: [
|
|
546
|
-
file.status === "complete" && /* @__PURE__ */
|
|
547
|
-
file.status === "error" && /* @__PURE__ */
|
|
548
|
-
file.status === "uploading" && /* @__PURE__ */
|
|
549
|
-
file.status === "pending" && /* @__PURE__ */
|
|
550
|
-
/* @__PURE__ */
|
|
551
|
-
/* @__PURE__ */
|
|
552
|
-
/* @__PURE__ */
|
|
553
|
-
/* @__PURE__ */
|
|
642
|
+
file.status === "complete" && /* @__PURE__ */ jsx8(CheckCircle22, { className: "h-4 w-4 shrink-0 text-[var(--surface-success-text)]" }),
|
|
643
|
+
file.status === "error" && /* @__PURE__ */ jsx8(AlertCircle2, { className: "h-4 w-4 shrink-0 text-[var(--surface-danger-text)]" }),
|
|
644
|
+
file.status === "uploading" && /* @__PURE__ */ jsx8(Loader2, { className: "h-4 w-4 shrink-0 animate-spin text-primary" }),
|
|
645
|
+
file.status === "pending" && /* @__PURE__ */ jsx8(FileText, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
|
|
646
|
+
/* @__PURE__ */ jsxs6("div", { className: "min-w-0 flex-1", children: [
|
|
647
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
|
|
648
|
+
/* @__PURE__ */ jsx8("span", { className: "truncate font-medium text-foreground", children: file.name }),
|
|
649
|
+
/* @__PURE__ */ jsx8("span", { className: "shrink-0 text-xs text-muted-foreground", children: formatSize(file.size) })
|
|
554
650
|
] }),
|
|
555
|
-
file.status === "uploading" && file.progress !== void 0 && /* @__PURE__ */
|
|
651
|
+
file.status === "uploading" && file.progress !== void 0 && /* @__PURE__ */ jsx8("div", { className: "mt-1 h-1 w-full overflow-hidden rounded-full bg-muted/50", children: /* @__PURE__ */ jsx8(
|
|
556
652
|
"div",
|
|
557
653
|
{
|
|
558
654
|
className: "h-full rounded-full bg-primary transition-all",
|
|
559
655
|
style: { width: `${file.progress}%` }
|
|
560
656
|
}
|
|
561
657
|
) }),
|
|
562
|
-
file.status === "error" && file.error && /* @__PURE__ */
|
|
658
|
+
file.status === "error" && file.error && /* @__PURE__ */ jsx8("p", { className: "mt-0.5 text-xs text-[var(--surface-danger-text)]", children: file.error })
|
|
563
659
|
] }),
|
|
564
|
-
/* @__PURE__ */
|
|
565
|
-
file.status === "error" && onRetry && /* @__PURE__ */
|
|
660
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex shrink-0 items-center gap-1", children: [
|
|
661
|
+
file.status === "error" && onRetry && /* @__PURE__ */ jsx8(
|
|
566
662
|
"button",
|
|
567
663
|
{
|
|
568
664
|
type: "button",
|
|
569
665
|
onClick: () => onRetry(file.id),
|
|
570
666
|
className: "rounded p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
|
|
571
|
-
children: /* @__PURE__ */
|
|
667
|
+
children: /* @__PURE__ */ jsx8(RefreshCw, { className: "h-3.5 w-3.5" })
|
|
572
668
|
}
|
|
573
669
|
),
|
|
574
|
-
onRemove && /* @__PURE__ */
|
|
670
|
+
onRemove && /* @__PURE__ */ jsx8(
|
|
575
671
|
"button",
|
|
576
672
|
{
|
|
577
673
|
type: "button",
|
|
578
674
|
onClick: () => onRemove(file.id),
|
|
579
675
|
className: "rounded p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
|
|
580
|
-
children: /* @__PURE__ */
|
|
676
|
+
children: /* @__PURE__ */ jsx8(X2, { className: "h-3.5 w-3.5" })
|
|
581
677
|
}
|
|
582
678
|
)
|
|
583
679
|
] })
|
|
@@ -588,9 +684,9 @@ function UploadProgress({ files, onRemove, onRetry, className }) {
|
|
|
588
684
|
}
|
|
589
685
|
|
|
590
686
|
// src/primitives/sidebar-drop-zone.tsx
|
|
591
|
-
import { useCallback as useCallback3, useRef as
|
|
687
|
+
import { useCallback as useCallback3, useRef as useRef4, useState as useState4 } from "react";
|
|
592
688
|
import { Upload } from "lucide-react";
|
|
593
|
-
import { jsx as
|
|
689
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
594
690
|
function SidebarDropZone({
|
|
595
691
|
onDrop,
|
|
596
692
|
accept,
|
|
@@ -602,7 +698,7 @@ function SidebarDropZone({
|
|
|
602
698
|
className
|
|
603
699
|
}) {
|
|
604
700
|
const [dragOver, setDragOver] = useState4(false);
|
|
605
|
-
const counter =
|
|
701
|
+
const counter = useRef4(0);
|
|
606
702
|
const isAccepted = useCallback3(
|
|
607
703
|
(file) => {
|
|
608
704
|
if (!accept) return true;
|
|
@@ -650,7 +746,7 @@ function SidebarDropZone({
|
|
|
650
746
|
[disabled, accept, isAccepted, onDrop]
|
|
651
747
|
);
|
|
652
748
|
const isVisible = persistent || dragOver;
|
|
653
|
-
return /* @__PURE__ */
|
|
749
|
+
return /* @__PURE__ */ jsx9(
|
|
654
750
|
"div",
|
|
655
751
|
{
|
|
656
752
|
onDragEnter: handleDragEnter,
|
|
@@ -664,16 +760,16 @@ function SidebarDropZone({
|
|
|
664
760
|
disabled && "opacity-50 pointer-events-none",
|
|
665
761
|
className
|
|
666
762
|
),
|
|
667
|
-
children: isVisible && /* @__PURE__ */
|
|
668
|
-
/* @__PURE__ */
|
|
763
|
+
children: isVisible && /* @__PURE__ */ jsxs7("div", { className: "flex flex-col items-center gap-2 text-center", children: [
|
|
764
|
+
/* @__PURE__ */ jsx9("div", { className: cn(
|
|
669
765
|
"flex h-8 w-8 items-center justify-center rounded-lg transition-colors",
|
|
670
766
|
dragOver ? "bg-[var(--brand-cool,hsl(var(--primary)))]/15 text-[var(--brand-cool,hsl(var(--primary)))]" : "text-[var(--text-muted,hsl(var(--muted-foreground)))]"
|
|
671
|
-
), children: icon ?? /* @__PURE__ */
|
|
672
|
-
/* @__PURE__ */
|
|
767
|
+
), children: icon ?? /* @__PURE__ */ jsx9(Upload, { className: "h-4 w-4" }) }),
|
|
768
|
+
/* @__PURE__ */ jsx9("p", { className: cn(
|
|
673
769
|
"text-xs font-medium",
|
|
674
770
|
dragOver ? "text-[var(--text-primary,hsl(var(--foreground)))]" : "text-[var(--text-muted,hsl(var(--muted-foreground)))]"
|
|
675
771
|
), children: title }),
|
|
676
|
-
description && /* @__PURE__ */
|
|
772
|
+
description && /* @__PURE__ */ jsx9("p", { className: "text-[10px] text-[var(--text-muted,hsl(var(--muted-foreground)))]", children: description })
|
|
677
773
|
] })
|
|
678
774
|
}
|
|
679
775
|
);
|
|
@@ -690,6 +786,7 @@ export {
|
|
|
690
786
|
SelectLabel,
|
|
691
787
|
SelectItem,
|
|
692
788
|
SelectSeparator,
|
|
789
|
+
SegmentedControl,
|
|
693
790
|
Switch,
|
|
694
791
|
ToastContainer,
|
|
695
792
|
ToastProvider,
|
|
@@ -255,7 +255,8 @@ function BillingDashboard({
|
|
|
255
255
|
import { Check, Zap } from "lucide-react";
|
|
256
256
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
257
257
|
function formatPrice(cents) {
|
|
258
|
-
|
|
258
|
+
if (!Number.isFinite(cents) || cents < 0) return "$0";
|
|
259
|
+
return cents % 100 === 0 ? `$${cents / 100}` : `$${(cents / 100).toFixed(2)}`;
|
|
259
260
|
}
|
|
260
261
|
function PricingPage({
|
|
261
262
|
tiers,
|
|
@@ -486,6 +487,7 @@ function UsageChart({ data, title, unit, className }) {
|
|
|
486
487
|
|
|
487
488
|
export {
|
|
488
489
|
BillingDashboard,
|
|
490
|
+
formatPrice,
|
|
489
491
|
PricingPage,
|
|
490
492
|
UsageChart
|
|
491
493
|
};
|