@memelabui/ui 0.2.0 → 0.4.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/README.md +34 -5
- package/dist/index.cjs +1704 -204
- package/dist/index.d.cts +223 -2
- package/dist/index.d.ts +223 -2
- package/dist/index.js +1561 -89
- package/dist/styles/index.css +404 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React = require('react');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var reactDom = require('react-dom');
|
|
6
6
|
|
|
7
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
|
|
9
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
10
|
+
|
|
7
11
|
// src/utils/cn.ts
|
|
8
12
|
function toClassName(out, value) {
|
|
9
13
|
if (!value) return;
|
|
@@ -59,16 +63,16 @@ function focusSafely(el) {
|
|
|
59
63
|
}
|
|
60
64
|
}
|
|
61
65
|
function useClipboard(timeout = 2e3) {
|
|
62
|
-
const [copied, setCopied] =
|
|
63
|
-
const timerRef =
|
|
64
|
-
|
|
66
|
+
const [copied, setCopied] = React.useState(false);
|
|
67
|
+
const timerRef = React.useRef(null);
|
|
68
|
+
React.useEffect(() => {
|
|
65
69
|
return () => {
|
|
66
70
|
if (timerRef.current !== null) {
|
|
67
71
|
clearTimeout(timerRef.current);
|
|
68
72
|
}
|
|
69
73
|
};
|
|
70
74
|
}, []);
|
|
71
|
-
const copy =
|
|
75
|
+
const copy = React.useCallback(
|
|
72
76
|
async (text) => {
|
|
73
77
|
try {
|
|
74
78
|
await navigator.clipboard.writeText(text);
|
|
@@ -89,18 +93,18 @@ function useClipboard(timeout = 2e3) {
|
|
|
89
93
|
return { copy, copied };
|
|
90
94
|
}
|
|
91
95
|
function useDisclosure(defaultOpen = false) {
|
|
92
|
-
const [isOpen, setIsOpen] =
|
|
93
|
-
const open =
|
|
94
|
-
const close =
|
|
95
|
-
const toggle =
|
|
96
|
+
const [isOpen, setIsOpen] = React.useState(defaultOpen);
|
|
97
|
+
const open = React.useCallback(() => setIsOpen(true), []);
|
|
98
|
+
const close = React.useCallback(() => setIsOpen(false), []);
|
|
99
|
+
const toggle = React.useCallback(() => setIsOpen((prev) => !prev), []);
|
|
96
100
|
return { isOpen, open, close, toggle };
|
|
97
101
|
}
|
|
98
102
|
function useMediaQuery(query) {
|
|
99
|
-
const [matches, setMatches] =
|
|
103
|
+
const [matches, setMatches] = React.useState(() => {
|
|
100
104
|
if (typeof window === "undefined") return false;
|
|
101
105
|
return window.matchMedia(query).matches;
|
|
102
106
|
});
|
|
103
|
-
|
|
107
|
+
React.useEffect(() => {
|
|
104
108
|
if (typeof window === "undefined") return;
|
|
105
109
|
const mediaQueryList = window.matchMedia(query);
|
|
106
110
|
setMatches(mediaQueryList.matches);
|
|
@@ -115,8 +119,8 @@ function useMediaQuery(query) {
|
|
|
115
119
|
return matches;
|
|
116
120
|
}
|
|
117
121
|
function useDebounce(value, delayMs = 300) {
|
|
118
|
-
const [debouncedValue, setDebouncedValue] =
|
|
119
|
-
|
|
122
|
+
const [debouncedValue, setDebouncedValue] = React.useState(value);
|
|
123
|
+
React.useEffect(() => {
|
|
120
124
|
const timer = setTimeout(() => {
|
|
121
125
|
setDebouncedValue(value);
|
|
122
126
|
}, delayMs);
|
|
@@ -146,8 +150,56 @@ var colors = {
|
|
|
146
150
|
warning: "#f59e0b",
|
|
147
151
|
danger: "#f43f5e"
|
|
148
152
|
};
|
|
149
|
-
var base = "inline-flex items-center justify-center gap-2 rounded-xl font-semibold leading-none transition-[transform,background-color,box-shadow,opacity] select-none [-webkit-tap-highlight-color:transparent] active:translate-y-[0.5px] disabled:opacity-60 disabled:pointer-events-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent";
|
|
150
153
|
var sizeClass = {
|
|
154
|
+
sm: "w-8 h-8 text-xs",
|
|
155
|
+
md: "w-10 h-10 text-sm",
|
|
156
|
+
lg: "w-12 h-12 text-base",
|
|
157
|
+
xl: "w-16 h-16 text-lg"
|
|
158
|
+
};
|
|
159
|
+
function getInitials(name) {
|
|
160
|
+
if (!name) return "";
|
|
161
|
+
const parts = name.trim().split(/\s+/);
|
|
162
|
+
const first = parts[0]?.[0] ?? "";
|
|
163
|
+
const second = parts[1]?.[0] ?? "";
|
|
164
|
+
return (first + second).toUpperCase();
|
|
165
|
+
}
|
|
166
|
+
var Avatar = React.forwardRef(function Avatar2({ src, alt, name, size = "md", className }, ref) {
|
|
167
|
+
const [imgError, setImgError] = React.useState(false);
|
|
168
|
+
const showFallback = !src || imgError;
|
|
169
|
+
const initials = getInitials(name);
|
|
170
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
171
|
+
"div",
|
|
172
|
+
{
|
|
173
|
+
ref,
|
|
174
|
+
className: cn(
|
|
175
|
+
"relative inline-flex items-center justify-center shrink-0 rounded-full overflow-hidden ring-1 ring-white/10",
|
|
176
|
+
sizeClass[size],
|
|
177
|
+
className
|
|
178
|
+
),
|
|
179
|
+
children: [
|
|
180
|
+
!showFallback && /* @__PURE__ */ jsxRuntime.jsx(
|
|
181
|
+
"img",
|
|
182
|
+
{
|
|
183
|
+
src,
|
|
184
|
+
alt: alt ?? name ?? "",
|
|
185
|
+
onError: () => setImgError(true),
|
|
186
|
+
className: "w-full h-full object-cover"
|
|
187
|
+
}
|
|
188
|
+
),
|
|
189
|
+
showFallback && /* @__PURE__ */ jsxRuntime.jsx(
|
|
190
|
+
"span",
|
|
191
|
+
{
|
|
192
|
+
"aria-label": name,
|
|
193
|
+
className: "w-full h-full inline-flex items-center justify-center bg-gradient-to-br from-primary to-accent font-semibold text-white leading-none select-none",
|
|
194
|
+
children: initials
|
|
195
|
+
}
|
|
196
|
+
)
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
);
|
|
200
|
+
});
|
|
201
|
+
var base = "inline-flex items-center justify-center gap-2 rounded-xl font-semibold leading-none transition-[transform,background-color,box-shadow,opacity] select-none [-webkit-tap-highlight-color:transparent] active:translate-y-[0.5px] disabled:opacity-60 disabled:pointer-events-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent";
|
|
202
|
+
var sizeClass2 = {
|
|
151
203
|
sm: "px-3 py-2 text-sm",
|
|
152
204
|
md: "px-3.5 py-2.5 text-sm",
|
|
153
205
|
lg: "px-4 py-3 text-base"
|
|
@@ -160,7 +212,7 @@ var variantClass = {
|
|
|
160
212
|
secondary: "text-white bg-white/5 ring-1 ring-white/10 hover:bg-white/10 hover:ring-white/20 backdrop-blur-sm",
|
|
161
213
|
ghost: "text-white/70 hover:text-white hover:bg-white/5"
|
|
162
214
|
};
|
|
163
|
-
var Button =
|
|
215
|
+
var Button = React.forwardRef(function Button2({ variant = "secondary", size = "md", leftIcon, rightIcon, loading, className, disabled, children, type, ...props }, ref) {
|
|
164
216
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
165
217
|
"button",
|
|
166
218
|
{
|
|
@@ -169,7 +221,7 @@ var Button = react.forwardRef(function Button2({ variant = "secondary", size = "
|
|
|
169
221
|
...props,
|
|
170
222
|
disabled: disabled || loading,
|
|
171
223
|
...loading ? { "aria-busy": true } : {},
|
|
172
|
-
className: cn(base,
|
|
224
|
+
className: cn(base, sizeClass2[size], variantClass[variant], className),
|
|
173
225
|
children: loading ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center justify-center gap-2", children: [
|
|
174
226
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin" }),
|
|
175
227
|
children
|
|
@@ -182,7 +234,7 @@ var Button = react.forwardRef(function Button2({ variant = "secondary", size = "
|
|
|
182
234
|
);
|
|
183
235
|
});
|
|
184
236
|
var base2 = "inline-flex items-center justify-center rounded-xl font-semibold leading-none transition-[transform,background-color,box-shadow,opacity] select-none [-webkit-tap-highlight-color:transparent] active:translate-y-[0.5px] disabled:opacity-60 disabled:pointer-events-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent";
|
|
185
|
-
var
|
|
237
|
+
var sizeClass3 = {
|
|
186
238
|
sm: "p-1.5 w-7 h-7",
|
|
187
239
|
md: "p-2 w-9 h-9",
|
|
188
240
|
lg: "p-2.5 w-11 h-11"
|
|
@@ -195,7 +247,7 @@ var variantClass2 = {
|
|
|
195
247
|
secondary: "text-white bg-white/10 shadow-sm ring-1 ring-white/10",
|
|
196
248
|
ghost: "text-white hover:bg-white/10"
|
|
197
249
|
};
|
|
198
|
-
var IconButton =
|
|
250
|
+
var IconButton = React.forwardRef(function IconButton2({ icon, variant = "ghost", size = "md", className, disabled, type, ...props }, ref) {
|
|
199
251
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
200
252
|
"button",
|
|
201
253
|
{
|
|
@@ -203,14 +255,14 @@ var IconButton = react.forwardRef(function IconButton2({ icon, variant = "ghost"
|
|
|
203
255
|
type: type === "submit" ? "submit" : type === "reset" ? "reset" : "button",
|
|
204
256
|
...props,
|
|
205
257
|
disabled,
|
|
206
|
-
className: cn(base2,
|
|
258
|
+
className: cn(base2, sizeClass3[size], variantClass2[variant], className),
|
|
207
259
|
children: /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: icon })
|
|
208
260
|
}
|
|
209
261
|
);
|
|
210
262
|
});
|
|
211
263
|
var inputBase = "w-full rounded-xl px-3 py-2.5 text-sm bg-white/10 text-white shadow-sm outline-none placeholder-white/30 focus-visible:ring-2 focus-visible:ring-primary/40 transition-shadow";
|
|
212
|
-
var Input =
|
|
213
|
-
const generatedId =
|
|
264
|
+
var Input = React.forwardRef(function Input2({ hasError, label, error, helperText, className, id: externalId, ...props }, ref) {
|
|
265
|
+
const generatedId = React.useId();
|
|
214
266
|
const inputId = externalId || generatedId;
|
|
215
267
|
const showError = hasError || !!error;
|
|
216
268
|
const errorId = error ? `${inputId}-error` : void 0;
|
|
@@ -235,8 +287,8 @@ var Input = react.forwardRef(function Input2({ hasError, label, error, helperTex
|
|
|
235
287
|
] });
|
|
236
288
|
});
|
|
237
289
|
var inputBase2 = "w-full rounded-xl pl-10 pr-3 py-2.5 text-sm bg-white/10 text-white shadow-sm outline-none placeholder-white/30 focus-visible:ring-2 focus-visible:ring-primary/40 transition-shadow";
|
|
238
|
-
var SearchInput =
|
|
239
|
-
const generatedId =
|
|
290
|
+
var SearchInput = React.forwardRef(function SearchInput2({ label, onClear, className, id: externalId, placeholder = "Search...", value, ...props }, ref) {
|
|
291
|
+
const generatedId = React.useId();
|
|
240
292
|
const inputId = externalId || generatedId;
|
|
241
293
|
const hasValue = value !== void 0 && value !== "";
|
|
242
294
|
const wrapper = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
@@ -307,8 +359,8 @@ var SearchInput = react.forwardRef(function SearchInput2({ label, onClear, class
|
|
|
307
359
|
] });
|
|
308
360
|
});
|
|
309
361
|
var selectBase = "w-full rounded-xl px-3 py-2.5 text-sm bg-white/10 text-white shadow-sm outline-none focus-visible:ring-2 focus-visible:ring-primary/40 transition-shadow";
|
|
310
|
-
var Select =
|
|
311
|
-
const generatedId =
|
|
362
|
+
var Select = React.forwardRef(function Select2({ hasError, label, error, helperText, className, id: externalId, children, ...props }, ref) {
|
|
363
|
+
const generatedId = React.useId();
|
|
312
364
|
const selectId = externalId || generatedId;
|
|
313
365
|
const showError = hasError || !!error;
|
|
314
366
|
const errorId = error ? `${selectId}-error` : void 0;
|
|
@@ -334,8 +386,8 @@ var Select = react.forwardRef(function Select2({ hasError, label, error, helperT
|
|
|
334
386
|
] });
|
|
335
387
|
});
|
|
336
388
|
var textareaBase = "w-full rounded-xl px-3 py-2.5 text-sm bg-white/10 text-white shadow-sm outline-none placeholder-white/30 focus-visible:ring-2 focus-visible:ring-primary/40 transition-shadow resize-y";
|
|
337
|
-
var Textarea =
|
|
338
|
-
const generatedId =
|
|
389
|
+
var Textarea = React.forwardRef(function Textarea2({ hasError, label, error, helperText, className, id: externalId, ...props }, ref) {
|
|
390
|
+
const generatedId = React.useId();
|
|
339
391
|
const textareaId = externalId || generatedId;
|
|
340
392
|
const showError = hasError || !!error;
|
|
341
393
|
const errorId = error ? `${textareaId}-error` : void 0;
|
|
@@ -359,8 +411,128 @@ var Textarea = react.forwardRef(function Textarea2({ hasError, label, error, hel
|
|
|
359
411
|
helperText && !error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: helperId, className: "text-white/40 text-xs mt-1", children: helperText })
|
|
360
412
|
] });
|
|
361
413
|
});
|
|
414
|
+
function TagInput({
|
|
415
|
+
value,
|
|
416
|
+
onChange,
|
|
417
|
+
placeholder,
|
|
418
|
+
disabled = false,
|
|
419
|
+
label,
|
|
420
|
+
error,
|
|
421
|
+
maxTags,
|
|
422
|
+
className,
|
|
423
|
+
id: externalId
|
|
424
|
+
}) {
|
|
425
|
+
const generatedId = React.useId();
|
|
426
|
+
const inputId = externalId ?? generatedId;
|
|
427
|
+
const errorId = error ? `${inputId}-error` : void 0;
|
|
428
|
+
const inputRef = React.useRef(null);
|
|
429
|
+
const atMax = maxTags !== void 0 && value.length >= maxTags;
|
|
430
|
+
function addTag(raw) {
|
|
431
|
+
const tag = raw.trim();
|
|
432
|
+
if (!tag || value.includes(tag) || atMax) return;
|
|
433
|
+
onChange([...value, tag]);
|
|
434
|
+
}
|
|
435
|
+
function removeTag(index) {
|
|
436
|
+
onChange(value.filter((_, i) => i !== index));
|
|
437
|
+
}
|
|
438
|
+
function handleKeyDown(e) {
|
|
439
|
+
const input = inputRef.current;
|
|
440
|
+
if (!input) return;
|
|
441
|
+
if (e.key === "Enter" || e.key === "," || e.key === "Tab") {
|
|
442
|
+
if (input.value) {
|
|
443
|
+
e.preventDefault();
|
|
444
|
+
addTag(input.value);
|
|
445
|
+
input.value = "";
|
|
446
|
+
}
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
if (e.key === "Backspace" && !input.value && value.length > 0) {
|
|
450
|
+
removeTag(value.length - 1);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
function handlePaste(e) {
|
|
454
|
+
const pasted = e.clipboardData.getData("text");
|
|
455
|
+
if (!pasted.includes(",")) return;
|
|
456
|
+
e.preventDefault();
|
|
457
|
+
const parts = pasted.split(",");
|
|
458
|
+
const next = [...value];
|
|
459
|
+
for (const part of parts) {
|
|
460
|
+
const tag = part.trim();
|
|
461
|
+
if (tag && !next.includes(tag)) {
|
|
462
|
+
if (maxTags !== void 0 && next.length >= maxTags) break;
|
|
463
|
+
next.push(tag);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
onChange(next);
|
|
467
|
+
if (inputRef.current) inputRef.current.value = "";
|
|
468
|
+
}
|
|
469
|
+
const wrapper = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
470
|
+
"div",
|
|
471
|
+
{
|
|
472
|
+
className: cn(
|
|
473
|
+
"flex flex-wrap items-center gap-1.5 min-h-[42px] w-full rounded-xl px-3 py-2 bg-white/10 ring-1 ring-white/10 transition-shadow focus-within:ring-2 focus-within:ring-primary/40",
|
|
474
|
+
error && "ring-2 ring-rose-500/40 focus-within:ring-rose-500/40",
|
|
475
|
+
disabled && "opacity-50 cursor-not-allowed",
|
|
476
|
+
className
|
|
477
|
+
),
|
|
478
|
+
onClick: () => inputRef.current?.focus(),
|
|
479
|
+
children: [
|
|
480
|
+
value.map((tag, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
481
|
+
"span",
|
|
482
|
+
{
|
|
483
|
+
className: "inline-flex items-center gap-1 bg-white/10 text-white/90 rounded-full text-xs px-2.5 py-1 ring-1 ring-white/10",
|
|
484
|
+
children: [
|
|
485
|
+
tag,
|
|
486
|
+
!disabled && /* @__PURE__ */ jsxRuntime.jsx(
|
|
487
|
+
"button",
|
|
488
|
+
{
|
|
489
|
+
type: "button",
|
|
490
|
+
"aria-label": `Remove ${tag}`,
|
|
491
|
+
onClick: (e) => {
|
|
492
|
+
e.stopPropagation();
|
|
493
|
+
removeTag(i);
|
|
494
|
+
},
|
|
495
|
+
className: "text-white/50 hover:text-white/90 transition-colors leading-none",
|
|
496
|
+
children: "\u2715"
|
|
497
|
+
}
|
|
498
|
+
)
|
|
499
|
+
]
|
|
500
|
+
},
|
|
501
|
+
`${tag}-${i}`
|
|
502
|
+
)),
|
|
503
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
504
|
+
"input",
|
|
505
|
+
{
|
|
506
|
+
ref: inputRef,
|
|
507
|
+
id: inputId,
|
|
508
|
+
type: "text",
|
|
509
|
+
disabled: disabled || atMax,
|
|
510
|
+
placeholder: value.length === 0 ? placeholder : void 0,
|
|
511
|
+
"aria-invalid": !!error || void 0,
|
|
512
|
+
"aria-describedby": errorId,
|
|
513
|
+
onKeyDown: handleKeyDown,
|
|
514
|
+
onPaste: handlePaste,
|
|
515
|
+
onBlur: (e) => {
|
|
516
|
+
if (e.target.value) {
|
|
517
|
+
addTag(e.target.value);
|
|
518
|
+
e.target.value = "";
|
|
519
|
+
}
|
|
520
|
+
},
|
|
521
|
+
className: "flex-1 min-w-[120px] bg-transparent text-sm text-white outline-none placeholder-white/30 disabled:cursor-not-allowed"
|
|
522
|
+
}
|
|
523
|
+
)
|
|
524
|
+
]
|
|
525
|
+
}
|
|
526
|
+
);
|
|
527
|
+
if (!label && !error) return wrapper;
|
|
528
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
529
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: inputId, className: "block text-sm text-white/70 mb-1.5", children: label }),
|
|
530
|
+
wrapper,
|
|
531
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, className: "text-rose-400 text-xs mt-1", children: error })
|
|
532
|
+
] });
|
|
533
|
+
}
|
|
362
534
|
var base3 = "inline-flex items-center justify-center rounded-full font-semibold ring-1 ring-white/10";
|
|
363
|
-
var
|
|
535
|
+
var sizeClass4 = {
|
|
364
536
|
sm: "text-xs px-2.5 py-1",
|
|
365
537
|
md: "text-sm px-3 py-1.5"
|
|
366
538
|
};
|
|
@@ -374,8 +546,8 @@ var variantClass3 = {
|
|
|
374
546
|
dangerSolid: "bg-rose-600 text-white ring-0",
|
|
375
547
|
accent: "bg-accent/15 text-accent-light ring-accent/20"
|
|
376
548
|
};
|
|
377
|
-
var Badge =
|
|
378
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { ref, ...props, className: cn(base3,
|
|
549
|
+
var Badge = React.forwardRef(function Badge2({ children, variant = "neutral", size = "sm", className, ...props }, ref) {
|
|
550
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { ref, ...props, className: cn(base3, sizeClass4[size], variantClass3[variant], className), children });
|
|
379
551
|
});
|
|
380
552
|
var Pill = Badge;
|
|
381
553
|
var trackSize = {
|
|
@@ -386,8 +558,8 @@ var thumbSize = {
|
|
|
386
558
|
sm: { base: "w-4 h-4", translate: "translate-x-4" },
|
|
387
559
|
md: { base: "w-5 h-5", translate: "translate-x-5" }
|
|
388
560
|
};
|
|
389
|
-
var Toggle =
|
|
390
|
-
const generatedId =
|
|
561
|
+
var Toggle = React.forwardRef(function Toggle2({ checked, onChange, disabled, busy, label, size = "md", id: externalId, "aria-label": ariaLabel }, ref) {
|
|
562
|
+
const generatedId = React.useId();
|
|
391
563
|
const toggleId = externalId || generatedId;
|
|
392
564
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
393
565
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -399,7 +571,8 @@ var Toggle = react.forwardRef(function Toggle2({ checked, onChange, disabled, la
|
|
|
399
571
|
role: "switch",
|
|
400
572
|
"aria-checked": checked,
|
|
401
573
|
"aria-label": ariaLabel || label,
|
|
402
|
-
disabled,
|
|
574
|
+
disabled: disabled || busy,
|
|
575
|
+
"aria-busy": busy || void 0,
|
|
403
576
|
onClick: () => onChange(!checked),
|
|
404
577
|
className: cn(
|
|
405
578
|
"relative rounded-full transition-colors duration-200 focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-surface",
|
|
@@ -411,9 +584,18 @@ var Toggle = react.forwardRef(function Toggle2({ checked, onChange, disabled, la
|
|
|
411
584
|
"span",
|
|
412
585
|
{
|
|
413
586
|
className: cn(
|
|
414
|
-
"absolute top-0.5 left-0.5 rounded-full bg-white transition-transform duration-200",
|
|
587
|
+
"absolute top-0.5 left-0.5 rounded-full bg-white transition-transform duration-200 flex items-center justify-center",
|
|
415
588
|
thumbSize[size].base,
|
|
416
589
|
checked ? thumbSize[size].translate : "translate-x-0"
|
|
590
|
+
),
|
|
591
|
+
children: busy && /* @__PURE__ */ jsxRuntime.jsx(
|
|
592
|
+
"span",
|
|
593
|
+
{
|
|
594
|
+
className: cn(
|
|
595
|
+
"border-2 border-primary/30 border-t-primary rounded-full animate-spin",
|
|
596
|
+
size === "sm" ? "w-2.5 h-2.5" : "w-3 h-3"
|
|
597
|
+
)
|
|
598
|
+
}
|
|
417
599
|
)
|
|
418
600
|
}
|
|
419
601
|
)
|
|
@@ -422,12 +604,180 @@ var Toggle = react.forwardRef(function Toggle2({ checked, onChange, disabled, la
|
|
|
422
604
|
label && /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: toggleId, className: "text-sm text-white/60 cursor-pointer", children: label })
|
|
423
605
|
] });
|
|
424
606
|
});
|
|
425
|
-
var
|
|
426
|
-
|
|
607
|
+
var Slider = React.forwardRef(function Slider2({
|
|
608
|
+
label,
|
|
609
|
+
showValue = false,
|
|
610
|
+
formatValue,
|
|
611
|
+
onChange,
|
|
612
|
+
disabled,
|
|
613
|
+
min = 0,
|
|
614
|
+
max = 100,
|
|
615
|
+
step = 1,
|
|
616
|
+
value,
|
|
617
|
+
defaultValue,
|
|
618
|
+
className,
|
|
619
|
+
id: externalId,
|
|
620
|
+
...props
|
|
621
|
+
}, ref) {
|
|
622
|
+
const generatedId = React.useId();
|
|
623
|
+
const sliderId = externalId || generatedId;
|
|
624
|
+
const numericValue = React.useMemo(() => {
|
|
625
|
+
const raw = value !== void 0 ? value : defaultValue;
|
|
626
|
+
return raw !== void 0 ? Number(raw) : Number(min);
|
|
627
|
+
}, [value, defaultValue, min]);
|
|
628
|
+
const percentage = React.useMemo(() => {
|
|
629
|
+
const numMin = Number(min);
|
|
630
|
+
const numMax = Number(max);
|
|
631
|
+
if (numMax === numMin) return 0;
|
|
632
|
+
return Math.max(0, Math.min(100, (numericValue - numMin) / (numMax - numMin) * 100));
|
|
633
|
+
}, [numericValue, min, max]);
|
|
634
|
+
const trackGradient = `linear-gradient(to right, var(--ml-primary, #8b5cf6) ${percentage}%, rgba(255,255,255,0.1) ${percentage}%)`;
|
|
635
|
+
const displayValue = formatValue ? formatValue(numericValue) : String(numericValue);
|
|
636
|
+
const handleChange = (e) => {
|
|
637
|
+
onChange?.(Number(e.target.value));
|
|
638
|
+
};
|
|
639
|
+
const inputEl = /* @__PURE__ */ jsxRuntime.jsx(
|
|
640
|
+
"input",
|
|
641
|
+
{
|
|
642
|
+
...props,
|
|
643
|
+
ref,
|
|
644
|
+
id: sliderId,
|
|
645
|
+
type: "range",
|
|
646
|
+
min,
|
|
647
|
+
max,
|
|
648
|
+
step,
|
|
649
|
+
value,
|
|
650
|
+
defaultValue: value === void 0 ? defaultValue ?? Number(min) : void 0,
|
|
651
|
+
disabled,
|
|
652
|
+
onChange: handleChange,
|
|
653
|
+
style: { background: trackGradient },
|
|
654
|
+
className: cn(
|
|
655
|
+
// Layout + reset
|
|
656
|
+
"w-full h-2 appearance-none rounded-full outline-none cursor-pointer",
|
|
657
|
+
// bg is set via inline style (trackGradient); keep transparent fallback for SSR
|
|
658
|
+
"bg-white/10",
|
|
659
|
+
// Webkit thumb
|
|
660
|
+
"[&::-webkit-slider-thumb]:appearance-none",
|
|
661
|
+
"[&::-webkit-slider-thumb]:w-4",
|
|
662
|
+
"[&::-webkit-slider-thumb]:h-4",
|
|
663
|
+
"[&::-webkit-slider-thumb]:rounded-full",
|
|
664
|
+
"[&::-webkit-slider-thumb]:bg-white",
|
|
665
|
+
"[&::-webkit-slider-thumb]:border-2",
|
|
666
|
+
"[&::-webkit-slider-thumb]:border-[var(--ml-primary,#8b5cf6)]",
|
|
667
|
+
"[&::-webkit-slider-thumb]:transition-shadow",
|
|
668
|
+
"[&::-webkit-slider-thumb]:duration-150",
|
|
669
|
+
// Moz thumb
|
|
670
|
+
"[&::-moz-range-thumb]:w-4",
|
|
671
|
+
"[&::-moz-range-thumb]:h-4",
|
|
672
|
+
"[&::-moz-range-thumb]:rounded-full",
|
|
673
|
+
"[&::-moz-range-thumb]:bg-white",
|
|
674
|
+
"[&::-moz-range-thumb]:border-2",
|
|
675
|
+
"[&::-moz-range-thumb]:border-[var(--ml-primary,#8b5cf6)]",
|
|
676
|
+
"[&::-moz-range-thumb]:transition-shadow",
|
|
677
|
+
"[&::-moz-range-thumb]:duration-150",
|
|
678
|
+
// Moz track — transparent so the gradient on the element shows through
|
|
679
|
+
"[&::-moz-range-track]:bg-transparent",
|
|
680
|
+
"[&::-moz-range-track]:rounded-full",
|
|
681
|
+
// Focus ring on thumb
|
|
682
|
+
"focus-visible:outline-none",
|
|
683
|
+
"focus-visible:[&::-webkit-slider-thumb]:ring-2",
|
|
684
|
+
"focus-visible:[&::-webkit-slider-thumb]:ring-primary/40",
|
|
685
|
+
"focus-visible:[&::-webkit-slider-thumb]:ring-offset-2",
|
|
686
|
+
"focus-visible:[&::-webkit-slider-thumb]:ring-offset-surface",
|
|
687
|
+
"focus-visible:[&::-moz-range-thumb]:ring-2",
|
|
688
|
+
"focus-visible:[&::-moz-range-thumb]:ring-primary/40",
|
|
689
|
+
// Disabled
|
|
690
|
+
disabled && "opacity-50 cursor-not-allowed",
|
|
691
|
+
className
|
|
692
|
+
)
|
|
693
|
+
}
|
|
694
|
+
);
|
|
695
|
+
if (!label && !showValue) return inputEl;
|
|
696
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full space-y-1.5", children: [
|
|
697
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
698
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: sliderId, className: "text-sm text-white/70", children: label }),
|
|
699
|
+
showValue && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-white/90 tabular-nums ml-auto", children: displayValue })
|
|
700
|
+
] }),
|
|
701
|
+
inputEl
|
|
702
|
+
] });
|
|
703
|
+
});
|
|
704
|
+
var ColorInput = React.forwardRef(function ColorInput2({ value, onChange, label, disabled, className, id: idProp }, ref) {
|
|
705
|
+
const autoId = React.useId();
|
|
706
|
+
const id = idProp ?? autoId;
|
|
707
|
+
const nativePickerRef = React.useRef(null);
|
|
708
|
+
function handleSwatchClick() {
|
|
709
|
+
if (!disabled) {
|
|
710
|
+
nativePickerRef.current?.click();
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
function handleTextChange(e) {
|
|
714
|
+
onChange(e.target.value);
|
|
715
|
+
}
|
|
716
|
+
function handleNativeChange(e) {
|
|
717
|
+
onChange(e.target.value);
|
|
718
|
+
}
|
|
719
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-1.5", className), children: [
|
|
720
|
+
label ? /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: "block text-sm text-white/70", children: label }) : null,
|
|
721
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
722
|
+
"div",
|
|
723
|
+
{
|
|
724
|
+
className: cn(
|
|
725
|
+
"flex items-center gap-2 bg-white/10 rounded-xl ring-1 ring-white/10 px-3 py-2 transition-shadow",
|
|
726
|
+
"focus-within:ring-2 focus-within:ring-primary/40",
|
|
727
|
+
disabled && "opacity-60 pointer-events-none"
|
|
728
|
+
),
|
|
729
|
+
children: [
|
|
730
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
731
|
+
"input",
|
|
732
|
+
{
|
|
733
|
+
type: "color",
|
|
734
|
+
ref: nativePickerRef,
|
|
735
|
+
value,
|
|
736
|
+
onChange: handleNativeChange,
|
|
737
|
+
disabled,
|
|
738
|
+
"aria-hidden": "true",
|
|
739
|
+
tabIndex: -1,
|
|
740
|
+
className: "sr-only"
|
|
741
|
+
}
|
|
742
|
+
),
|
|
743
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
744
|
+
"button",
|
|
745
|
+
{
|
|
746
|
+
type: "button",
|
|
747
|
+
onClick: handleSwatchClick,
|
|
748
|
+
disabled,
|
|
749
|
+
"aria-label": "Open color picker",
|
|
750
|
+
className: cn(
|
|
751
|
+
"w-8 h-8 rounded-lg border border-white/20 flex-shrink-0 transition-transform hover:scale-105 active:scale-95 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60"
|
|
752
|
+
),
|
|
753
|
+
style: { backgroundColor: value }
|
|
754
|
+
}
|
|
755
|
+
),
|
|
756
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
757
|
+
"input",
|
|
758
|
+
{
|
|
759
|
+
ref,
|
|
760
|
+
id,
|
|
761
|
+
type: "text",
|
|
762
|
+
value,
|
|
763
|
+
onChange: handleTextChange,
|
|
764
|
+
disabled,
|
|
765
|
+
spellCheck: false,
|
|
766
|
+
className: "flex-1 min-w-0 bg-transparent text-sm text-white placeholder:text-white/30 outline-none font-mono",
|
|
767
|
+
placeholder: "#000000"
|
|
768
|
+
}
|
|
769
|
+
)
|
|
770
|
+
]
|
|
771
|
+
}
|
|
772
|
+
)
|
|
773
|
+
] });
|
|
774
|
+
});
|
|
775
|
+
var Checkbox = React.forwardRef(function Checkbox2({ label, error, indeterminate, className, id: externalId, disabled, checked, onChange, ...props }, ref) {
|
|
776
|
+
const generatedId = React.useId();
|
|
427
777
|
const inputId = externalId || generatedId;
|
|
428
778
|
const errorId = error ? `${inputId}-error` : void 0;
|
|
429
|
-
const internalRef =
|
|
430
|
-
|
|
779
|
+
const internalRef = React.useRef(null);
|
|
780
|
+
React.useEffect(() => {
|
|
431
781
|
const el = internalRef.current;
|
|
432
782
|
if (el) {
|
|
433
783
|
el.indeterminate = indeterminate ?? false;
|
|
@@ -514,9 +864,9 @@ var Checkbox = react.forwardRef(function Checkbox2({ label, error, indeterminate
|
|
|
514
864
|
error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, className: "text-rose-400 text-xs ml-7", children: error })
|
|
515
865
|
] });
|
|
516
866
|
});
|
|
517
|
-
var RadioGroupContext =
|
|
867
|
+
var RadioGroupContext = React.createContext(null);
|
|
518
868
|
function useRadioGroup() {
|
|
519
|
-
const ctx =
|
|
869
|
+
const ctx = React.useContext(RadioGroupContext);
|
|
520
870
|
if (!ctx) {
|
|
521
871
|
throw new Error("RadioItem must be used inside a RadioGroup");
|
|
522
872
|
}
|
|
@@ -534,13 +884,13 @@ function RadioGroup({
|
|
|
534
884
|
children,
|
|
535
885
|
className
|
|
536
886
|
}) {
|
|
537
|
-
const groupId =
|
|
538
|
-
const generatedName =
|
|
887
|
+
const groupId = React.useId();
|
|
888
|
+
const generatedName = React.useId();
|
|
539
889
|
const name = externalName ?? generatedName;
|
|
540
|
-
const [uncontrolledValue, setUncontrolledValue] =
|
|
890
|
+
const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue);
|
|
541
891
|
const isControlled = controlledValue !== void 0;
|
|
542
892
|
const currentValue = isControlled ? controlledValue : uncontrolledValue;
|
|
543
|
-
const handleChange =
|
|
893
|
+
const handleChange = React.useCallback(
|
|
544
894
|
(val) => {
|
|
545
895
|
if (!isControlled) setUncontrolledValue(val);
|
|
546
896
|
onValueChange?.(val);
|
|
@@ -549,7 +899,7 @@ function RadioGroup({
|
|
|
549
899
|
);
|
|
550
900
|
const labelId = label ? `${groupId}-label` : void 0;
|
|
551
901
|
const errorId = error ? `${groupId}-error` : void 0;
|
|
552
|
-
const ctxValue =
|
|
902
|
+
const ctxValue = React.useMemo(
|
|
553
903
|
() => ({ value: currentValue, onChange: handleChange, name, disabled, groupId }),
|
|
554
904
|
[currentValue, handleChange, name, disabled, groupId]
|
|
555
905
|
);
|
|
@@ -580,8 +930,8 @@ function RadioGroup({
|
|
|
580
930
|
}
|
|
581
931
|
function RadioItem({ value, disabled: itemDisabled, children, className }) {
|
|
582
932
|
const { value: groupValue, onChange, name, disabled: groupDisabled, groupId } = useRadioGroup();
|
|
583
|
-
const inputId =
|
|
584
|
-
const inputRef =
|
|
933
|
+
const inputId = React.useId();
|
|
934
|
+
const inputRef = React.useRef(null);
|
|
585
935
|
const isDisabled = groupDisabled || itemDisabled;
|
|
586
936
|
const isSelected = groupValue === value;
|
|
587
937
|
const handleKeyDown = (e) => {
|
|
@@ -647,7 +997,7 @@ function RadioItem({ value, disabled: itemDisabled, children, className }) {
|
|
|
647
997
|
}
|
|
648
998
|
);
|
|
649
999
|
}
|
|
650
|
-
var
|
|
1000
|
+
var sizeClass5 = {
|
|
651
1001
|
sm: "h-3 w-3 border",
|
|
652
1002
|
md: "h-4 w-4 border-2",
|
|
653
1003
|
lg: "h-6 w-6 border-2"
|
|
@@ -656,7 +1006,7 @@ function Spinner({ className, size = "md", label }) {
|
|
|
656
1006
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
657
1007
|
"span",
|
|
658
1008
|
{
|
|
659
|
-
className: cn("inline-block rounded-full border-white/15 border-t-primary animate-spin",
|
|
1009
|
+
className: cn("inline-block rounded-full border-white/15 border-t-primary animate-spin", sizeClass5[size], className),
|
|
660
1010
|
role: label ? "status" : void 0,
|
|
661
1011
|
"aria-hidden": label ? void 0 : "true",
|
|
662
1012
|
"aria-label": label || void 0
|
|
@@ -672,9 +1022,9 @@ function Skeleton({ className, circle }) {
|
|
|
672
1022
|
}
|
|
673
1023
|
);
|
|
674
1024
|
}
|
|
675
|
-
var TabsContext =
|
|
1025
|
+
var TabsContext = React.createContext(null);
|
|
676
1026
|
function useTabsContext() {
|
|
677
|
-
const ctx =
|
|
1027
|
+
const ctx = React.useContext(TabsContext);
|
|
678
1028
|
if (!ctx) throw new Error("Tabs sub-components must be used inside <Tabs>");
|
|
679
1029
|
return ctx;
|
|
680
1030
|
}
|
|
@@ -686,18 +1036,18 @@ function Tabs({
|
|
|
686
1036
|
children,
|
|
687
1037
|
className
|
|
688
1038
|
}) {
|
|
689
|
-
const baseId =
|
|
1039
|
+
const baseId = React.useId();
|
|
690
1040
|
const isControlled = value !== void 0;
|
|
691
|
-
const [internalValue, setInternalValue] =
|
|
1041
|
+
const [internalValue, setInternalValue] = React.useState(defaultValue);
|
|
692
1042
|
const activeValue = isControlled ? value ?? "" : internalValue;
|
|
693
|
-
const setActiveValue =
|
|
1043
|
+
const setActiveValue = React.useCallback(
|
|
694
1044
|
(next) => {
|
|
695
1045
|
if (!isControlled) setInternalValue(next);
|
|
696
1046
|
onValueChange?.(next);
|
|
697
1047
|
},
|
|
698
1048
|
[isControlled, onValueChange]
|
|
699
1049
|
);
|
|
700
|
-
const ctxValue =
|
|
1050
|
+
const ctxValue = React.useMemo(
|
|
701
1051
|
() => ({ activeValue, setActiveValue, variant, baseId }),
|
|
702
1052
|
[activeValue, setActiveValue, variant, baseId]
|
|
703
1053
|
);
|
|
@@ -705,7 +1055,7 @@ function Tabs({
|
|
|
705
1055
|
}
|
|
706
1056
|
function TabList({ children, className }) {
|
|
707
1057
|
const { variant } = useTabsContext();
|
|
708
|
-
const listRef =
|
|
1058
|
+
const listRef = React.useRef(null);
|
|
709
1059
|
const handleKeyDown = (e) => {
|
|
710
1060
|
const list = listRef.current;
|
|
711
1061
|
if (!list) return;
|
|
@@ -810,7 +1160,7 @@ function TabPanel({ value, children, className }) {
|
|
|
810
1160
|
}
|
|
811
1161
|
);
|
|
812
1162
|
}
|
|
813
|
-
var Card =
|
|
1163
|
+
var Card = React.forwardRef(function Card2({ hoverable, variant = "surface", className, ...props }, ref) {
|
|
814
1164
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
815
1165
|
"div",
|
|
816
1166
|
{
|
|
@@ -850,9 +1200,9 @@ function Modal({
|
|
|
850
1200
|
contentClassName,
|
|
851
1201
|
zIndexClassName = "z-50"
|
|
852
1202
|
}) {
|
|
853
|
-
const dialogRef =
|
|
854
|
-
const lastActiveElementRef =
|
|
855
|
-
|
|
1203
|
+
const dialogRef = React.useRef(null);
|
|
1204
|
+
const lastActiveElementRef = React.useRef(null);
|
|
1205
|
+
React.useEffect(() => {
|
|
856
1206
|
if (!isOpen) return;
|
|
857
1207
|
lastActiveElementRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
858
1208
|
const raf = window.requestAnimationFrame(() => {
|
|
@@ -868,7 +1218,7 @@ function Modal({
|
|
|
868
1218
|
if (lastActive?.isConnected) focusSafely(lastActive);
|
|
869
1219
|
};
|
|
870
1220
|
}, [isOpen]);
|
|
871
|
-
|
|
1221
|
+
React.useEffect(() => {
|
|
872
1222
|
if (!isOpen) return;
|
|
873
1223
|
lockScroll();
|
|
874
1224
|
return () => unlockScroll();
|
|
@@ -961,7 +1311,7 @@ function ConfirmDialog({
|
|
|
961
1311
|
variant = "danger",
|
|
962
1312
|
isLoading = false
|
|
963
1313
|
}) {
|
|
964
|
-
const titleId =
|
|
1314
|
+
const titleId = React.useId();
|
|
965
1315
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
966
1316
|
Modal,
|
|
967
1317
|
{
|
|
@@ -1006,22 +1356,22 @@ function ConfirmDialog({
|
|
|
1006
1356
|
);
|
|
1007
1357
|
}
|
|
1008
1358
|
function Tooltip({ content, delayMs = 500, placement = "top", className, children }) {
|
|
1009
|
-
const tooltipId =
|
|
1010
|
-
const openTimerRef =
|
|
1011
|
-
const anchorRef =
|
|
1012
|
-
const [open, setOpen] =
|
|
1013
|
-
const [pos, setPos] =
|
|
1014
|
-
|
|
1359
|
+
const tooltipId = React.useId();
|
|
1360
|
+
const openTimerRef = React.useRef(null);
|
|
1361
|
+
const anchorRef = React.useRef(null);
|
|
1362
|
+
const [open, setOpen] = React.useState(false);
|
|
1363
|
+
const [pos, setPos] = React.useState(null);
|
|
1364
|
+
React.useMemo(() => {
|
|
1015
1365
|
if (typeof content === "string") return content.trim();
|
|
1016
1366
|
return "";
|
|
1017
1367
|
}, [content]);
|
|
1018
|
-
const clearTimer =
|
|
1368
|
+
const clearTimer = React.useCallback(() => {
|
|
1019
1369
|
if (openTimerRef.current !== null) {
|
|
1020
1370
|
window.clearTimeout(openTimerRef.current);
|
|
1021
1371
|
openTimerRef.current = null;
|
|
1022
1372
|
}
|
|
1023
1373
|
}, []);
|
|
1024
|
-
const updatePosition =
|
|
1374
|
+
const updatePosition = React.useCallback(() => {
|
|
1025
1375
|
const el = anchorRef.current;
|
|
1026
1376
|
if (!el) return;
|
|
1027
1377
|
const r = el.getBoundingClientRect();
|
|
@@ -1037,17 +1387,17 @@ function Tooltip({ content, delayMs = 500, placement = "top", className, childre
|
|
|
1037
1387
|
placement: effPlacement
|
|
1038
1388
|
});
|
|
1039
1389
|
}, [placement]);
|
|
1040
|
-
const scheduleOpen =
|
|
1390
|
+
const scheduleOpen = React.useCallback(() => {
|
|
1041
1391
|
clearTimer();
|
|
1042
1392
|
openTimerRef.current = window.setTimeout(() => {
|
|
1043
1393
|
setOpen(true);
|
|
1044
1394
|
}, Math.max(0, delayMs));
|
|
1045
1395
|
}, [clearTimer, delayMs]);
|
|
1046
|
-
const close =
|
|
1396
|
+
const close = React.useCallback(() => {
|
|
1047
1397
|
clearTimer();
|
|
1048
1398
|
setOpen(false);
|
|
1049
1399
|
}, [clearTimer]);
|
|
1050
|
-
|
|
1400
|
+
React.useEffect(() => {
|
|
1051
1401
|
if (!open) return;
|
|
1052
1402
|
updatePosition();
|
|
1053
1403
|
const onScroll = () => updatePosition();
|
|
@@ -1059,11 +1409,11 @@ function Tooltip({ content, delayMs = 500, placement = "top", className, childre
|
|
|
1059
1409
|
window.removeEventListener("resize", onResize);
|
|
1060
1410
|
};
|
|
1061
1411
|
}, [open, updatePosition]);
|
|
1062
|
-
|
|
1412
|
+
React.useEffect(() => {
|
|
1063
1413
|
return () => clearTimer();
|
|
1064
1414
|
}, [clearTimer]);
|
|
1065
|
-
if (!
|
|
1066
|
-
const child =
|
|
1415
|
+
if (!React.isValidElement(children)) return children;
|
|
1416
|
+
const child = React.cloneElement(children, {
|
|
1067
1417
|
ref: (node) => {
|
|
1068
1418
|
anchorRef.current = node;
|
|
1069
1419
|
const childProps = children.props;
|
|
@@ -1128,8 +1478,8 @@ function EmptyState({ icon: Icon, title, description, actionLabel, onAction, chi
|
|
|
1128
1478
|
] });
|
|
1129
1479
|
}
|
|
1130
1480
|
function CollapsibleSection({ title, defaultOpen = true, children, right, className }) {
|
|
1131
|
-
const [isOpen, setIsOpen] =
|
|
1132
|
-
const contentId =
|
|
1481
|
+
const [isOpen, setIsOpen] = React.useState(defaultOpen);
|
|
1482
|
+
const contentId = React.useId();
|
|
1133
1483
|
const titleId = `${contentId}-title`;
|
|
1134
1484
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("rounded-xl ring-1 ring-white/10 bg-white/5 overflow-hidden", className), children: [
|
|
1135
1485
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -1176,21 +1526,21 @@ function CollapsibleSection({ title, defaultOpen = true, children, right, classN
|
|
|
1176
1526
|
)
|
|
1177
1527
|
] });
|
|
1178
1528
|
}
|
|
1179
|
-
var DropdownContext =
|
|
1529
|
+
var DropdownContext = React.createContext(null);
|
|
1180
1530
|
function useDropdownContext(component) {
|
|
1181
|
-
const ctx =
|
|
1531
|
+
const ctx = React.useContext(DropdownContext);
|
|
1182
1532
|
if (!ctx) {
|
|
1183
1533
|
throw new Error(`<${component}> must be rendered inside <Dropdown>`);
|
|
1184
1534
|
}
|
|
1185
1535
|
return ctx;
|
|
1186
1536
|
}
|
|
1187
1537
|
function Dropdown({ children, className }) {
|
|
1188
|
-
const [open, setOpen] =
|
|
1189
|
-
const triggerId =
|
|
1190
|
-
const menuId =
|
|
1191
|
-
const triggerRef =
|
|
1192
|
-
const toggleOpen =
|
|
1193
|
-
const ctxValue =
|
|
1538
|
+
const [open, setOpen] = React.useState(false);
|
|
1539
|
+
const triggerId = React.useId();
|
|
1540
|
+
const menuId = React.useId();
|
|
1541
|
+
const triggerRef = React.useRef(null);
|
|
1542
|
+
const toggleOpen = React.useCallback(() => setOpen((prev) => !prev), []);
|
|
1543
|
+
const ctxValue = React.useMemo(
|
|
1194
1544
|
() => ({ open, setOpen, toggleOpen, triggerId, menuId, triggerRef }),
|
|
1195
1545
|
[open, setOpen, toggleOpen, triggerId, menuId, triggerRef]
|
|
1196
1546
|
);
|
|
@@ -1198,8 +1548,8 @@ function Dropdown({ children, className }) {
|
|
|
1198
1548
|
}
|
|
1199
1549
|
function DropdownTrigger({ children, className }) {
|
|
1200
1550
|
const { open, toggleOpen, triggerId, menuId, triggerRef } = useDropdownContext("DropdownTrigger");
|
|
1201
|
-
if (!
|
|
1202
|
-
return
|
|
1551
|
+
if (!React.isValidElement(children)) return children;
|
|
1552
|
+
return React.cloneElement(children, {
|
|
1203
1553
|
id: triggerId,
|
|
1204
1554
|
"aria-haspopup": "menu",
|
|
1205
1555
|
"aria-expanded": open,
|
|
@@ -1221,10 +1571,10 @@ function DropdownTrigger({ children, className }) {
|
|
|
1221
1571
|
}
|
|
1222
1572
|
function DropdownMenu({ children, className, align = "left" }) {
|
|
1223
1573
|
const { open, setOpen, menuId, triggerId, triggerRef } = useDropdownContext("DropdownMenu");
|
|
1224
|
-
const menuRef =
|
|
1225
|
-
const [pos, setPos] =
|
|
1226
|
-
const [visible, setVisible] =
|
|
1227
|
-
const updatePosition =
|
|
1574
|
+
const menuRef = React.useRef(null);
|
|
1575
|
+
const [pos, setPos] = React.useState(null);
|
|
1576
|
+
const [visible, setVisible] = React.useState(false);
|
|
1577
|
+
const updatePosition = React.useCallback(() => {
|
|
1228
1578
|
const trigger = triggerRef.current;
|
|
1229
1579
|
if (!trigger) return;
|
|
1230
1580
|
const rect = trigger.getBoundingClientRect();
|
|
@@ -1234,7 +1584,7 @@ function DropdownMenu({ children, className, align = "left" }) {
|
|
|
1234
1584
|
left: Math.round(left)
|
|
1235
1585
|
});
|
|
1236
1586
|
}, [align, triggerRef]);
|
|
1237
|
-
|
|
1587
|
+
React.useEffect(() => {
|
|
1238
1588
|
if (!open) {
|
|
1239
1589
|
setVisible(false);
|
|
1240
1590
|
return;
|
|
@@ -1249,7 +1599,7 @@ function DropdownMenu({ children, className, align = "left" }) {
|
|
|
1249
1599
|
});
|
|
1250
1600
|
return () => window.cancelAnimationFrame(raf);
|
|
1251
1601
|
}, [open, updatePosition]);
|
|
1252
|
-
|
|
1602
|
+
React.useEffect(() => {
|
|
1253
1603
|
if (!open) return;
|
|
1254
1604
|
function handlePointerDown(e) {
|
|
1255
1605
|
const target = e.target;
|
|
@@ -1260,7 +1610,7 @@ function DropdownMenu({ children, className, align = "left" }) {
|
|
|
1260
1610
|
document.addEventListener("pointerdown", handlePointerDown, true);
|
|
1261
1611
|
return () => document.removeEventListener("pointerdown", handlePointerDown, true);
|
|
1262
1612
|
}, [open, setOpen, triggerRef]);
|
|
1263
|
-
|
|
1613
|
+
React.useEffect(() => {
|
|
1264
1614
|
if (!open) return;
|
|
1265
1615
|
const onScroll = () => updatePosition();
|
|
1266
1616
|
const onResize = () => updatePosition();
|
|
@@ -1336,7 +1686,7 @@ function DropdownMenu({ children, className, align = "left" }) {
|
|
|
1336
1686
|
}
|
|
1337
1687
|
function DropdownItem({ onSelect, disabled = false, children, className }) {
|
|
1338
1688
|
const { setOpen, triggerRef } = useDropdownContext("DropdownItem");
|
|
1339
|
-
const handleSelect =
|
|
1689
|
+
const handleSelect = React.useCallback(() => {
|
|
1340
1690
|
if (disabled) return;
|
|
1341
1691
|
setOpen(false);
|
|
1342
1692
|
focusSafely(triggerRef.current);
|
|
@@ -1389,10 +1739,10 @@ function DropZone({
|
|
|
1389
1739
|
className,
|
|
1390
1740
|
"aria-label": ariaLabel = "File drop zone"
|
|
1391
1741
|
}) {
|
|
1392
|
-
const [isDragging, setIsDragging] =
|
|
1393
|
-
const inputRef =
|
|
1394
|
-
const dragCounterRef =
|
|
1395
|
-
const processFiles =
|
|
1742
|
+
const [isDragging, setIsDragging] = React.useState(false);
|
|
1743
|
+
const inputRef = React.useRef(null);
|
|
1744
|
+
const dragCounterRef = React.useRef(0);
|
|
1745
|
+
const processFiles = React.useCallback(
|
|
1396
1746
|
(fileList) => {
|
|
1397
1747
|
if (!fileList || disabled) return;
|
|
1398
1748
|
let files = Array.from(fileList);
|
|
@@ -1409,7 +1759,7 @@ function DropZone({
|
|
|
1409
1759
|
},
|
|
1410
1760
|
[accept, disabled, maxFiles, maxSize, onFilesDropped]
|
|
1411
1761
|
);
|
|
1412
|
-
const handleDragEnter =
|
|
1762
|
+
const handleDragEnter = React.useCallback(
|
|
1413
1763
|
(e) => {
|
|
1414
1764
|
e.preventDefault();
|
|
1415
1765
|
dragCounterRef.current++;
|
|
@@ -1417,18 +1767,18 @@ function DropZone({
|
|
|
1417
1767
|
},
|
|
1418
1768
|
[disabled]
|
|
1419
1769
|
);
|
|
1420
|
-
const handleDragOver =
|
|
1770
|
+
const handleDragOver = React.useCallback(
|
|
1421
1771
|
(e) => {
|
|
1422
1772
|
e.preventDefault();
|
|
1423
1773
|
},
|
|
1424
1774
|
[]
|
|
1425
1775
|
);
|
|
1426
|
-
const handleDragLeave =
|
|
1776
|
+
const handleDragLeave = React.useCallback((e) => {
|
|
1427
1777
|
e.preventDefault();
|
|
1428
1778
|
dragCounterRef.current--;
|
|
1429
1779
|
if (dragCounterRef.current === 0) setIsDragging(false);
|
|
1430
1780
|
}, []);
|
|
1431
|
-
const handleDrop =
|
|
1781
|
+
const handleDrop = React.useCallback(
|
|
1432
1782
|
(e) => {
|
|
1433
1783
|
e.preventDefault();
|
|
1434
1784
|
dragCounterRef.current = 0;
|
|
@@ -1438,10 +1788,10 @@ function DropZone({
|
|
|
1438
1788
|
},
|
|
1439
1789
|
[disabled, processFiles]
|
|
1440
1790
|
);
|
|
1441
|
-
const handleClick =
|
|
1791
|
+
const handleClick = React.useCallback(() => {
|
|
1442
1792
|
if (!disabled) inputRef.current?.click();
|
|
1443
1793
|
}, [disabled]);
|
|
1444
|
-
const handleKeyDown =
|
|
1794
|
+
const handleKeyDown = React.useCallback(
|
|
1445
1795
|
(e) => {
|
|
1446
1796
|
if (disabled) return;
|
|
1447
1797
|
if (e.key === "Enter" || e.key === " ") {
|
|
@@ -1451,7 +1801,7 @@ function DropZone({
|
|
|
1451
1801
|
},
|
|
1452
1802
|
[disabled]
|
|
1453
1803
|
);
|
|
1454
|
-
const handleInputChange =
|
|
1804
|
+
const handleInputChange = React.useCallback(() => {
|
|
1455
1805
|
processFiles(inputRef.current?.files ?? null);
|
|
1456
1806
|
if (inputRef.current) inputRef.current.value = "";
|
|
1457
1807
|
}, [processFiles]);
|
|
@@ -1519,97 +1869,798 @@ function DropZone({
|
|
|
1519
1869
|
}
|
|
1520
1870
|
);
|
|
1521
1871
|
}
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1872
|
+
function FormField({ label, error, helperText, children, className, id: idProp }) {
|
|
1873
|
+
const autoId = React.useId();
|
|
1874
|
+
const id = idProp ?? autoId;
|
|
1875
|
+
const descIds = [];
|
|
1876
|
+
const errorId = error ? `${id}-error` : void 0;
|
|
1877
|
+
const helperId = helperText ? `${id}-helper` : void 0;
|
|
1878
|
+
if (errorId) descIds.push(errorId);
|
|
1879
|
+
if (helperId) descIds.push(helperId);
|
|
1880
|
+
const describedBy = descIds.length > 0 ? descIds.join(" ") : void 0;
|
|
1881
|
+
const child = React.cloneElement(children, {
|
|
1882
|
+
id,
|
|
1883
|
+
...describedBy ? { "aria-describedby": describedBy } : {},
|
|
1884
|
+
...error ? { "aria-invalid": true } : {}
|
|
1885
|
+
});
|
|
1886
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col", className), children: [
|
|
1887
|
+
label ? /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: "block text-sm text-white/70 mb-1.5", children: label }) : null,
|
|
1888
|
+
child,
|
|
1889
|
+
error ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, className: "text-rose-400 text-xs mt-1", role: "alert", children: error }) : null,
|
|
1890
|
+
helperText && !error ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: helperId, className: "text-white/40 text-xs mt-1", children: helperText }) : null
|
|
1535
1891
|
] });
|
|
1536
1892
|
}
|
|
1537
|
-
function
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
className,
|
|
1542
|
-
mainClassName,
|
|
1543
|
-
containerClassName,
|
|
1544
|
-
maxWidth = "xl",
|
|
1545
|
-
children
|
|
1546
|
-
}) {
|
|
1547
|
-
const showDefaultBackground = variant !== "minimal" && !background;
|
|
1548
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative overflow-hidden flex-1 min-h-full flex flex-col", className), children: [
|
|
1549
|
-
background,
|
|
1550
|
-
showDefaultBackground ? defaultBackground() : null,
|
|
1551
|
-
header,
|
|
1552
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1553
|
-
"main",
|
|
1893
|
+
function Divider({ orientation = "horizontal", label, className }) {
|
|
1894
|
+
if (orientation === "vertical") {
|
|
1895
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1896
|
+
"div",
|
|
1554
1897
|
{
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
containerClassName,
|
|
1559
|
-
mainClassName
|
|
1560
|
-
),
|
|
1561
|
-
children
|
|
1898
|
+
role: "separator",
|
|
1899
|
+
"aria-orientation": "vertical",
|
|
1900
|
+
className: cn("border-l border-white/10 h-full mx-3 self-stretch", className)
|
|
1562
1901
|
}
|
|
1563
|
-
)
|
|
1564
|
-
|
|
1902
|
+
);
|
|
1903
|
+
}
|
|
1904
|
+
if (label) {
|
|
1905
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1906
|
+
"div",
|
|
1907
|
+
{
|
|
1908
|
+
role: "separator",
|
|
1909
|
+
"aria-orientation": "horizontal",
|
|
1910
|
+
className: cn("flex items-center gap-3 my-3 w-full", className),
|
|
1911
|
+
children: [
|
|
1912
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 border-t border-white/10" }),
|
|
1913
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-white/40 leading-none select-none", children: label }),
|
|
1914
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 border-t border-white/10" })
|
|
1915
|
+
]
|
|
1916
|
+
}
|
|
1917
|
+
);
|
|
1918
|
+
}
|
|
1919
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1920
|
+
"hr",
|
|
1921
|
+
{
|
|
1922
|
+
role: "separator",
|
|
1923
|
+
"aria-orientation": "horizontal",
|
|
1924
|
+
className: cn("border-t border-white/10 w-full my-3", className)
|
|
1925
|
+
}
|
|
1926
|
+
);
|
|
1565
1927
|
}
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1928
|
+
var Table = React.forwardRef(({ children, className }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl ring-1 ring-white/10 overflow-hidden bg-white/5", children: /* @__PURE__ */ jsxRuntime.jsx("table", { ref, className: cn("w-full text-sm text-white", className), children }) }));
|
|
1929
|
+
Table.displayName = "Table";
|
|
1930
|
+
var TableHeader = React.forwardRef(
|
|
1931
|
+
({ children, className }, ref) => /* @__PURE__ */ jsxRuntime.jsx("thead", { ref, className: cn("bg-white/5 border-b border-white/10", className), children })
|
|
1932
|
+
);
|
|
1933
|
+
TableHeader.displayName = "TableHeader";
|
|
1934
|
+
var TableBody = React.forwardRef(
|
|
1935
|
+
({ children, className }, ref) => /* @__PURE__ */ jsxRuntime.jsx("tbody", { ref, className: cn("divide-y divide-white/[0.06]", className), children })
|
|
1936
|
+
);
|
|
1937
|
+
TableBody.displayName = "TableBody";
|
|
1938
|
+
var TableRow = React.forwardRef(
|
|
1939
|
+
({ children, className, hoverable }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1940
|
+
"tr",
|
|
1941
|
+
{
|
|
1942
|
+
ref,
|
|
1943
|
+
className: cn(hoverable && "hover:bg-white/[0.03] transition-colors", className),
|
|
1944
|
+
children
|
|
1945
|
+
}
|
|
1946
|
+
)
|
|
1947
|
+
);
|
|
1948
|
+
TableRow.displayName = "TableRow";
|
|
1949
|
+
var TableHead = React.forwardRef(
|
|
1950
|
+
({ children, className }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1951
|
+
"th",
|
|
1952
|
+
{
|
|
1953
|
+
ref,
|
|
1954
|
+
className: cn(
|
|
1955
|
+
"px-4 py-3 text-left text-xs font-semibold text-white/50 uppercase tracking-wider",
|
|
1956
|
+
className
|
|
1957
|
+
),
|
|
1958
|
+
children
|
|
1959
|
+
}
|
|
1960
|
+
)
|
|
1961
|
+
);
|
|
1962
|
+
TableHead.displayName = "TableHead";
|
|
1963
|
+
var alignClass = {
|
|
1964
|
+
left: "text-left",
|
|
1965
|
+
center: "text-center",
|
|
1966
|
+
right: "text-right"
|
|
1967
|
+
};
|
|
1968
|
+
var TableCell = React.forwardRef(
|
|
1969
|
+
({ children, className, align = "left" }, ref) => /* @__PURE__ */ jsxRuntime.jsx("td", { ref, className: cn("px-4 py-3 text-white/80", alignClass[align], className), children })
|
|
1970
|
+
);
|
|
1971
|
+
TableCell.displayName = "TableCell";
|
|
1972
|
+
function TrendIndicator({ trend }) {
|
|
1973
|
+
if (trend.value > 0) {
|
|
1974
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-emerald-400", children: [
|
|
1975
|
+
/* @__PURE__ */ jsxRuntime.jsx("svg", { "aria-hidden": "true", className: "w-3 h-3 shrink-0", fill: "none", viewBox: "0 0 12 12", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 9V3M3 6l3-3 3 3" }) }),
|
|
1976
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
1977
|
+
"+",
|
|
1978
|
+
trend.value,
|
|
1979
|
+
trend.label ? ` ${trend.label}` : ""
|
|
1980
|
+
] })
|
|
1981
|
+
] });
|
|
1982
|
+
}
|
|
1983
|
+
if (trend.value < 0) {
|
|
1984
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-rose-400", children: [
|
|
1985
|
+
/* @__PURE__ */ jsxRuntime.jsx("svg", { "aria-hidden": "true", className: "w-3 h-3 shrink-0", fill: "none", viewBox: "0 0 12 12", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 3v6M3 6l3 3 3-3" }) }),
|
|
1986
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
1987
|
+
trend.value,
|
|
1988
|
+
trend.label ? ` ${trend.label}` : ""
|
|
1989
|
+
] })
|
|
1990
|
+
] });
|
|
1991
|
+
}
|
|
1992
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-white/40", children: [
|
|
1993
|
+
/* @__PURE__ */ jsxRuntime.jsx("svg", { "aria-hidden": "true", className: "w-3 h-3 shrink-0", fill: "none", viewBox: "0 0 12 12", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M2 6h8" }) }),
|
|
1994
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
1995
|
+
trend.value,
|
|
1996
|
+
trend.label ? ` ${trend.label}` : ""
|
|
1997
|
+
] })
|
|
1998
|
+
] });
|
|
1571
1999
|
}
|
|
1572
|
-
function
|
|
2000
|
+
function StatCard({ value, label, icon, trend, className }) {
|
|
1573
2001
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1574
|
-
"
|
|
2002
|
+
"div",
|
|
1575
2003
|
{
|
|
1576
2004
|
className: cn(
|
|
1577
|
-
"
|
|
1578
|
-
collapsed ? "w-16" : "w-64",
|
|
2005
|
+
"bg-white/5 ring-1 ring-white/10 rounded-xl p-4 flex items-start gap-3",
|
|
1579
2006
|
className
|
|
1580
2007
|
),
|
|
1581
2008
|
children: [
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
{
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
"aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
|
|
1589
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1590
|
-
"svg",
|
|
1591
|
-
{
|
|
1592
|
-
className: cn("h-5 w-5 transition-transform duration-200", collapsed && "rotate-180"),
|
|
1593
|
-
fill: "none",
|
|
1594
|
-
viewBox: "0 0 24 24",
|
|
1595
|
-
stroke: "currentColor",
|
|
1596
|
-
strokeWidth: 2,
|
|
1597
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M11 19l-7-7 7-7m8 14l-7-7 7-7" })
|
|
1598
|
-
}
|
|
1599
|
-
)
|
|
1600
|
-
}
|
|
1601
|
-
),
|
|
1602
|
-
/* @__PURE__ */ jsxRuntime.jsx("nav", { className: "flex-1 overflow-y-auto py-2", children })
|
|
2009
|
+
icon != null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-10 rounded-lg bg-white/10 flex items-center justify-center text-primary shrink-0", children: icon }),
|
|
2010
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5 min-w-0", children: [
|
|
2011
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-2xl font-bold text-white tabular-nums leading-none", children: value }),
|
|
2012
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-white/50 truncate", children: label }),
|
|
2013
|
+
trend != null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(TrendIndicator, { trend }) })
|
|
2014
|
+
] })
|
|
1603
2015
|
]
|
|
1604
2016
|
}
|
|
1605
2017
|
);
|
|
1606
2018
|
}
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
2019
|
+
function getPageRange(page, totalPages, siblingCount) {
|
|
2020
|
+
if (totalPages <= 1) return [1];
|
|
2021
|
+
const siblingStart = Math.max(2, page - siblingCount);
|
|
2022
|
+
const siblingEnd = Math.min(totalPages - 1, page + siblingCount);
|
|
2023
|
+
const showLeftEllipsis = siblingStart > 2;
|
|
2024
|
+
const showRightEllipsis = siblingEnd < totalPages - 1;
|
|
2025
|
+
const items = [1];
|
|
2026
|
+
if (showLeftEllipsis) {
|
|
2027
|
+
items.push("...");
|
|
2028
|
+
} else {
|
|
2029
|
+
for (let i = 2; i < siblingStart; i++) {
|
|
2030
|
+
items.push(i);
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
for (let i = siblingStart; i <= siblingEnd; i++) {
|
|
2034
|
+
items.push(i);
|
|
2035
|
+
}
|
|
2036
|
+
if (showRightEllipsis) {
|
|
2037
|
+
items.push("...");
|
|
2038
|
+
} else {
|
|
2039
|
+
for (let i = siblingEnd + 1; i < totalPages; i++) {
|
|
2040
|
+
items.push(i);
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
if (totalPages > 1) {
|
|
2044
|
+
items.push(totalPages);
|
|
2045
|
+
}
|
|
2046
|
+
return items;
|
|
2047
|
+
}
|
|
2048
|
+
var buttonBase = "inline-flex items-center justify-center rounded-lg px-3 py-2 text-sm font-medium transition-[background-color,opacity] select-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40";
|
|
2049
|
+
var pageButton = cn(buttonBase, "bg-white/5 ring-1 ring-white/10 text-white/80 hover:bg-white/10 hover:text-white");
|
|
2050
|
+
var activeButton = cn(buttonBase, "bg-primary text-white ring-1 ring-primary/20");
|
|
2051
|
+
var navButton = cn(buttonBase, "bg-white/5 ring-1 ring-white/10 text-white/80 hover:bg-white/10 hover:text-white");
|
|
2052
|
+
var ChevronLeft = () => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2053
|
+
"svg",
|
|
2054
|
+
{
|
|
2055
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2056
|
+
width: "16",
|
|
2057
|
+
height: "16",
|
|
2058
|
+
viewBox: "0 0 24 24",
|
|
2059
|
+
fill: "none",
|
|
2060
|
+
stroke: "currentColor",
|
|
2061
|
+
strokeWidth: "2",
|
|
2062
|
+
strokeLinecap: "round",
|
|
2063
|
+
strokeLinejoin: "round",
|
|
2064
|
+
"aria-hidden": "true",
|
|
2065
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "15 18 9 12 15 6" })
|
|
2066
|
+
}
|
|
2067
|
+
);
|
|
2068
|
+
var ChevronRight = () => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2069
|
+
"svg",
|
|
2070
|
+
{
|
|
2071
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2072
|
+
width: "16",
|
|
2073
|
+
height: "16",
|
|
2074
|
+
viewBox: "0 0 24 24",
|
|
2075
|
+
fill: "none",
|
|
2076
|
+
stroke: "currentColor",
|
|
2077
|
+
strokeWidth: "2",
|
|
2078
|
+
strokeLinecap: "round",
|
|
2079
|
+
strokeLinejoin: "round",
|
|
2080
|
+
"aria-hidden": "true",
|
|
2081
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "9 18 15 12 9 6" })
|
|
2082
|
+
}
|
|
2083
|
+
);
|
|
2084
|
+
function Pagination({
|
|
2085
|
+
page,
|
|
2086
|
+
totalPages,
|
|
2087
|
+
onPageChange,
|
|
2088
|
+
siblingCount = 1,
|
|
2089
|
+
className
|
|
2090
|
+
}) {
|
|
2091
|
+
if (totalPages <= 1) return null;
|
|
2092
|
+
const items = getPageRange(page, totalPages, siblingCount);
|
|
2093
|
+
const isPrevDisabled = page <= 1;
|
|
2094
|
+
const isNextDisabled = page >= totalPages;
|
|
2095
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2096
|
+
"nav",
|
|
2097
|
+
{
|
|
2098
|
+
role: "navigation",
|
|
2099
|
+
"aria-label": "Pagination",
|
|
2100
|
+
className: cn("flex items-center gap-1", className),
|
|
2101
|
+
children: [
|
|
2102
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2103
|
+
"button",
|
|
2104
|
+
{
|
|
2105
|
+
type: "button",
|
|
2106
|
+
onClick: () => onPageChange(page - 1),
|
|
2107
|
+
disabled: isPrevDisabled,
|
|
2108
|
+
"aria-label": "Previous page",
|
|
2109
|
+
className: cn(navButton, isPrevDisabled && "opacity-40 cursor-not-allowed pointer-events-none"),
|
|
2110
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLeft, {})
|
|
2111
|
+
}
|
|
2112
|
+
),
|
|
2113
|
+
items.map(
|
|
2114
|
+
(item, index) => item === "..." ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2115
|
+
"span",
|
|
2116
|
+
{
|
|
2117
|
+
className: "inline-flex items-center justify-center px-3 py-2 text-sm text-white/40 select-none",
|
|
2118
|
+
"aria-hidden": "true",
|
|
2119
|
+
children: "\u2026"
|
|
2120
|
+
},
|
|
2121
|
+
`ellipsis-${index}`
|
|
2122
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2123
|
+
"button",
|
|
2124
|
+
{
|
|
2125
|
+
type: "button",
|
|
2126
|
+
onClick: () => onPageChange(item),
|
|
2127
|
+
"aria-label": `Page ${item}`,
|
|
2128
|
+
"aria-current": item === page ? "page" : void 0,
|
|
2129
|
+
className: item === page ? activeButton : pageButton,
|
|
2130
|
+
children: item
|
|
2131
|
+
},
|
|
2132
|
+
item
|
|
2133
|
+
)
|
|
2134
|
+
),
|
|
2135
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2136
|
+
"button",
|
|
2137
|
+
{
|
|
2138
|
+
type: "button",
|
|
2139
|
+
onClick: () => onPageChange(page + 1),
|
|
2140
|
+
disabled: isNextDisabled,
|
|
2141
|
+
"aria-label": "Next page",
|
|
2142
|
+
className: cn(navButton, isNextDisabled && "opacity-40 cursor-not-allowed pointer-events-none"),
|
|
2143
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRight, {})
|
|
2144
|
+
}
|
|
2145
|
+
)
|
|
2146
|
+
]
|
|
2147
|
+
}
|
|
2148
|
+
);
|
|
2149
|
+
}
|
|
2150
|
+
function Stepper({ steps, activeStep, className }) {
|
|
2151
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex items-start w-full", className), children: steps.map((step, index) => {
|
|
2152
|
+
const isCompleted = index < activeStep;
|
|
2153
|
+
const isActive = index === activeStep;
|
|
2154
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React__default.default.Fragment, { children: [
|
|
2155
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2156
|
+
"div",
|
|
2157
|
+
{
|
|
2158
|
+
className: "flex flex-col items-center",
|
|
2159
|
+
"aria-current": isActive ? "step" : void 0,
|
|
2160
|
+
children: [
|
|
2161
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2162
|
+
"div",
|
|
2163
|
+
{
|
|
2164
|
+
className: cn(
|
|
2165
|
+
"w-8 h-8 rounded-full flex items-center justify-center text-sm font-semibold",
|
|
2166
|
+
isCompleted && "bg-emerald-600 text-white",
|
|
2167
|
+
isActive && "bg-primary text-white ring-2 ring-primary/40",
|
|
2168
|
+
!isCompleted && !isActive && "bg-white/10 text-white/40"
|
|
2169
|
+
),
|
|
2170
|
+
children: isCompleted ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2171
|
+
"svg",
|
|
2172
|
+
{
|
|
2173
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2174
|
+
viewBox: "0 0 20 20",
|
|
2175
|
+
fill: "currentColor",
|
|
2176
|
+
className: "w-4 h-4",
|
|
2177
|
+
"aria-hidden": "true",
|
|
2178
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2179
|
+
"path",
|
|
2180
|
+
{
|
|
2181
|
+
fillRule: "evenodd",
|
|
2182
|
+
d: "M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z",
|
|
2183
|
+
clipRule: "evenodd"
|
|
2184
|
+
}
|
|
2185
|
+
)
|
|
2186
|
+
}
|
|
2187
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("span", { children: index + 1 })
|
|
2188
|
+
}
|
|
2189
|
+
),
|
|
2190
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2191
|
+
"span",
|
|
2192
|
+
{
|
|
2193
|
+
className: cn(
|
|
2194
|
+
"text-xs mt-2 text-center max-w-[6rem]",
|
|
2195
|
+
isActive ? "text-white/80" : "text-white/50"
|
|
2196
|
+
),
|
|
2197
|
+
children: step.label
|
|
2198
|
+
}
|
|
2199
|
+
),
|
|
2200
|
+
step.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs mt-0.5 text-center text-white/30 max-w-[6rem]", children: step.description })
|
|
2201
|
+
]
|
|
2202
|
+
}
|
|
2203
|
+
),
|
|
2204
|
+
index < steps.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2205
|
+
"div",
|
|
2206
|
+
{
|
|
2207
|
+
className: cn(
|
|
2208
|
+
"h-0.5 flex-1 mx-2 mt-4 self-start",
|
|
2209
|
+
isCompleted ? "bg-emerald-600" : "bg-white/10"
|
|
2210
|
+
),
|
|
2211
|
+
"aria-hidden": "true"
|
|
2212
|
+
}
|
|
2213
|
+
)
|
|
2214
|
+
] }, index);
|
|
2215
|
+
}) });
|
|
2216
|
+
}
|
|
2217
|
+
var sizeClasses = {
|
|
2218
|
+
sm: "h-1",
|
|
2219
|
+
md: "h-2",
|
|
2220
|
+
lg: "h-3"
|
|
2221
|
+
};
|
|
2222
|
+
var variantClasses = {
|
|
2223
|
+
primary: "bg-primary",
|
|
2224
|
+
success: "bg-emerald-500",
|
|
2225
|
+
warning: "bg-amber-500",
|
|
2226
|
+
danger: "bg-rose-500"
|
|
2227
|
+
};
|
|
2228
|
+
function ProgressBar({
|
|
2229
|
+
value,
|
|
2230
|
+
max = 100,
|
|
2231
|
+
variant = "primary",
|
|
2232
|
+
label,
|
|
2233
|
+
showValue = false,
|
|
2234
|
+
size = "md",
|
|
2235
|
+
className
|
|
2236
|
+
}) {
|
|
2237
|
+
const percentage = Math.min(100, Math.max(0, value / max * 100));
|
|
2238
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("w-full", className), children: [
|
|
2239
|
+
(label || showValue) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-1", children: [
|
|
2240
|
+
label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-white/60", children: label }),
|
|
2241
|
+
showValue && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-white/60 ml-auto", children: [
|
|
2242
|
+
Math.round(percentage),
|
|
2243
|
+
"%"
|
|
2244
|
+
] })
|
|
2245
|
+
] }),
|
|
2246
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2247
|
+
"div",
|
|
2248
|
+
{
|
|
2249
|
+
className: cn("w-full rounded-full bg-white/10", sizeClasses[size]),
|
|
2250
|
+
role: "progressbar",
|
|
2251
|
+
"aria-valuenow": value,
|
|
2252
|
+
"aria-valuemin": 0,
|
|
2253
|
+
"aria-valuemax": max,
|
|
2254
|
+
"aria-label": label,
|
|
2255
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2256
|
+
"div",
|
|
2257
|
+
{
|
|
2258
|
+
className: cn(
|
|
2259
|
+
"rounded-full transition-[width] duration-300 ease-out",
|
|
2260
|
+
sizeClasses[size],
|
|
2261
|
+
variantClasses[variant]
|
|
2262
|
+
),
|
|
2263
|
+
style: { width: `${percentage}%` }
|
|
2264
|
+
}
|
|
2265
|
+
)
|
|
2266
|
+
}
|
|
2267
|
+
)
|
|
2268
|
+
] });
|
|
2269
|
+
}
|
|
2270
|
+
var sizeMap = {
|
|
2271
|
+
sm: "w-8 h-8 text-xs",
|
|
2272
|
+
md: "w-12 h-12 text-sm",
|
|
2273
|
+
lg: "w-16 h-16 text-base"
|
|
2274
|
+
};
|
|
2275
|
+
var strokeWidthMap = {
|
|
2276
|
+
sm: 3,
|
|
2277
|
+
md: 3.5,
|
|
2278
|
+
lg: 4
|
|
2279
|
+
};
|
|
2280
|
+
var RADIUS = 15.9155;
|
|
2281
|
+
var CIRCUMFERENCE = 2 * Math.PI * RADIUS;
|
|
2282
|
+
function CooldownRing({
|
|
2283
|
+
duration,
|
|
2284
|
+
remaining,
|
|
2285
|
+
size = "md",
|
|
2286
|
+
className
|
|
2287
|
+
}) {
|
|
2288
|
+
const fraction = duration > 0 ? Math.max(0, Math.min(1, remaining / duration)) : 0;
|
|
2289
|
+
const offset = CIRCUMFERENCE * (1 - fraction);
|
|
2290
|
+
const color = fraction > 0.5 ? "text-primary" : fraction > 0.25 ? "text-amber-500" : "text-rose-500";
|
|
2291
|
+
const pulse = remaining <= 10 && remaining > 0;
|
|
2292
|
+
const strokeWidth = strokeWidthMap[size];
|
|
2293
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative inline-flex items-center justify-center", sizeMap[size], className), children: [
|
|
2294
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2295
|
+
"svg",
|
|
2296
|
+
{
|
|
2297
|
+
viewBox: "0 0 36 36",
|
|
2298
|
+
className: cn("w-full h-full -rotate-90", color, pulse && "animate-pulse"),
|
|
2299
|
+
"aria-label": `Cooldown: ${remaining} seconds remaining`,
|
|
2300
|
+
role: "img",
|
|
2301
|
+
children: [
|
|
2302
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2303
|
+
"circle",
|
|
2304
|
+
{
|
|
2305
|
+
cx: "18",
|
|
2306
|
+
cy: "18",
|
|
2307
|
+
r: RADIUS,
|
|
2308
|
+
fill: "none",
|
|
2309
|
+
stroke: "currentColor",
|
|
2310
|
+
strokeWidth,
|
|
2311
|
+
className: "text-white/10"
|
|
2312
|
+
}
|
|
2313
|
+
),
|
|
2314
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2315
|
+
"circle",
|
|
2316
|
+
{
|
|
2317
|
+
cx: "18",
|
|
2318
|
+
cy: "18",
|
|
2319
|
+
r: RADIUS,
|
|
2320
|
+
fill: "none",
|
|
2321
|
+
stroke: "currentColor",
|
|
2322
|
+
strokeWidth,
|
|
2323
|
+
strokeDasharray: `${CIRCUMFERENCE} ${CIRCUMFERENCE}`,
|
|
2324
|
+
strokeDashoffset: offset,
|
|
2325
|
+
strokeLinecap: "round",
|
|
2326
|
+
style: { transition: "stroke-dashoffset 0.6s ease" }
|
|
2327
|
+
}
|
|
2328
|
+
)
|
|
2329
|
+
]
|
|
2330
|
+
}
|
|
2331
|
+
),
|
|
2332
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2333
|
+
"span",
|
|
2334
|
+
{
|
|
2335
|
+
className: "absolute font-semibold tabular-nums text-white select-none",
|
|
2336
|
+
style: { lineHeight: 1 },
|
|
2337
|
+
children: Math.max(0, Math.ceil(remaining))
|
|
2338
|
+
}
|
|
2339
|
+
)
|
|
2340
|
+
] });
|
|
2341
|
+
}
|
|
2342
|
+
function StageProgress({ stages, activeStage, className }) {
|
|
2343
|
+
const clampedActive = Math.max(0, Math.min(activeStage, stages.length - 1));
|
|
2344
|
+
const fillPercent = stages.length <= 1 ? 100 : clampedActive / (stages.length - 1) * 100;
|
|
2345
|
+
const isComplete = clampedActive >= stages.length - 1;
|
|
2346
|
+
const isAnimating = !isComplete;
|
|
2347
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("w-full", className), children: [
|
|
2348
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-between", children: stages.map((stage, index) => {
|
|
2349
|
+
const isCompleted = index < clampedActive;
|
|
2350
|
+
const isActive = index === clampedActive;
|
|
2351
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2352
|
+
"div",
|
|
2353
|
+
{
|
|
2354
|
+
className: cn(
|
|
2355
|
+
"flex items-center gap-1.5 text-xs font-medium transition-colors duration-300",
|
|
2356
|
+
isCompleted && "text-emerald-400",
|
|
2357
|
+
isActive && "text-white",
|
|
2358
|
+
!isCompleted && !isActive && "text-white/40"
|
|
2359
|
+
),
|
|
2360
|
+
children: [
|
|
2361
|
+
isCompleted ? (
|
|
2362
|
+
// Completed: emerald check circle
|
|
2363
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-3.5 w-3.5 items-center justify-center rounded-full bg-emerald-400/20", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2364
|
+
"svg",
|
|
2365
|
+
{
|
|
2366
|
+
className: "h-2.5 w-2.5 text-emerald-400",
|
|
2367
|
+
viewBox: "0 0 10 10",
|
|
2368
|
+
fill: "none",
|
|
2369
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2370
|
+
"aria-hidden": "true",
|
|
2371
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2372
|
+
"path",
|
|
2373
|
+
{
|
|
2374
|
+
d: "M2 5.5L4 7.5L8 3",
|
|
2375
|
+
stroke: "currentColor",
|
|
2376
|
+
strokeWidth: "1.5",
|
|
2377
|
+
strokeLinecap: "round",
|
|
2378
|
+
strokeLinejoin: "round"
|
|
2379
|
+
}
|
|
2380
|
+
)
|
|
2381
|
+
}
|
|
2382
|
+
) })
|
|
2383
|
+
) : isActive ? (
|
|
2384
|
+
// Active: primary dot with ring
|
|
2385
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-3.5 w-3.5 items-center justify-center rounded-full ring-2 ring-[var(--ml-primary)] ring-offset-1 ring-offset-black/50", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-[var(--ml-primary)]" }) })
|
|
2386
|
+
) : (
|
|
2387
|
+
// Upcoming: hollow dim dot
|
|
2388
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-3.5 w-3.5 rounded-full border border-white/20 bg-transparent" })
|
|
2389
|
+
),
|
|
2390
|
+
stage
|
|
2391
|
+
]
|
|
2392
|
+
},
|
|
2393
|
+
stage
|
|
2394
|
+
);
|
|
2395
|
+
}) }),
|
|
2396
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2397
|
+
"div",
|
|
2398
|
+
{
|
|
2399
|
+
className: "relative mt-3 h-1.5 w-full overflow-hidden rounded-full bg-white/10",
|
|
2400
|
+
role: "progressbar",
|
|
2401
|
+
"aria-valuenow": clampedActive,
|
|
2402
|
+
"aria-valuemin": 0,
|
|
2403
|
+
"aria-valuemax": stages.length - 1,
|
|
2404
|
+
"aria-label": `Stage ${clampedActive + 1} of ${stages.length}: ${stages[clampedActive]}`,
|
|
2405
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2406
|
+
"div",
|
|
2407
|
+
{
|
|
2408
|
+
className: "h-full rounded-full bg-gradient-to-r from-[var(--ml-accent)] to-[var(--ml-primary)] transition-[width] duration-500 ease-in-out",
|
|
2409
|
+
style: { width: `${fillPercent}%` },
|
|
2410
|
+
children: isAnimating && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2411
|
+
"span",
|
|
2412
|
+
{
|
|
2413
|
+
className: "pointer-events-none absolute inset-0 -translate-x-full animate-[ml-shimmer_2s_ease-in-out_infinite] bg-gradient-to-r from-transparent via-white/30 to-transparent",
|
|
2414
|
+
"aria-hidden": "true"
|
|
2415
|
+
}
|
|
2416
|
+
)
|
|
2417
|
+
}
|
|
2418
|
+
)
|
|
2419
|
+
}
|
|
2420
|
+
)
|
|
2421
|
+
] });
|
|
2422
|
+
}
|
|
2423
|
+
function getUrgencyClasses(remaining, max) {
|
|
2424
|
+
const ratio = max > 0 ? remaining / max : 0;
|
|
2425
|
+
if (ratio > 0.5) {
|
|
2426
|
+
return {
|
|
2427
|
+
filled: "bg-emerald-400",
|
|
2428
|
+
empty: "bg-emerald-400/30",
|
|
2429
|
+
label: "text-emerald-400"
|
|
2430
|
+
};
|
|
2431
|
+
}
|
|
2432
|
+
if (ratio > 0.25) {
|
|
2433
|
+
return {
|
|
2434
|
+
filled: "bg-amber-400",
|
|
2435
|
+
empty: "bg-amber-400/30",
|
|
2436
|
+
label: "text-amber-400"
|
|
2437
|
+
};
|
|
2438
|
+
}
|
|
2439
|
+
return {
|
|
2440
|
+
filled: "bg-rose-400",
|
|
2441
|
+
empty: "bg-rose-400/30",
|
|
2442
|
+
label: "text-rose-400"
|
|
2443
|
+
};
|
|
2444
|
+
}
|
|
2445
|
+
function DotIndicator({
|
|
2446
|
+
remaining,
|
|
2447
|
+
max,
|
|
2448
|
+
showLabel = false,
|
|
2449
|
+
labelFormat,
|
|
2450
|
+
className
|
|
2451
|
+
}) {
|
|
2452
|
+
const clampedRemaining = Math.max(0, Math.min(remaining, max));
|
|
2453
|
+
const used = max - clampedRemaining;
|
|
2454
|
+
const urgency = getUrgencyClasses(clampedRemaining, max);
|
|
2455
|
+
const defaultLabel = `${clampedRemaining}/${max}`;
|
|
2456
|
+
const label = labelFormat ? labelFormat(clampedRemaining, max) : defaultLabel;
|
|
2457
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("inline-flex items-center gap-2", className), children: [
|
|
2458
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2459
|
+
"div",
|
|
2460
|
+
{
|
|
2461
|
+
className: "flex items-center gap-1",
|
|
2462
|
+
role: "meter",
|
|
2463
|
+
"aria-valuenow": clampedRemaining,
|
|
2464
|
+
"aria-valuemin": 0,
|
|
2465
|
+
"aria-valuemax": max,
|
|
2466
|
+
"aria-label": label,
|
|
2467
|
+
children: Array.from({ length: max }, (_, index) => {
|
|
2468
|
+
const isFilled = index < used;
|
|
2469
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2470
|
+
"span",
|
|
2471
|
+
{
|
|
2472
|
+
className: cn(
|
|
2473
|
+
"h-2 w-2 rounded-full transition-colors duration-300",
|
|
2474
|
+
isFilled ? urgency.filled : urgency.empty
|
|
2475
|
+
),
|
|
2476
|
+
"aria-hidden": "true"
|
|
2477
|
+
},
|
|
2478
|
+
index
|
|
2479
|
+
);
|
|
2480
|
+
})
|
|
2481
|
+
}
|
|
2482
|
+
),
|
|
2483
|
+
showLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-xs font-medium tabular-nums", urgency.label), children: label })
|
|
2484
|
+
] });
|
|
2485
|
+
}
|
|
2486
|
+
function ActiveFilterPills({
|
|
2487
|
+
filters,
|
|
2488
|
+
onRemove,
|
|
2489
|
+
onClearAll,
|
|
2490
|
+
clearAllLabel = "Clear all",
|
|
2491
|
+
className
|
|
2492
|
+
}) {
|
|
2493
|
+
if (filters.length === 0) return null;
|
|
2494
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-wrap items-center gap-1.5", className), children: [
|
|
2495
|
+
filters.map((filter) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2496
|
+
"span",
|
|
2497
|
+
{
|
|
2498
|
+
className: "inline-flex items-center gap-1 rounded-full bg-white/10 px-2.5 py-1 text-xs text-white/80 ring-1 ring-white/10",
|
|
2499
|
+
children: [
|
|
2500
|
+
filter.label,
|
|
2501
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2502
|
+
"button",
|
|
2503
|
+
{
|
|
2504
|
+
type: "button",
|
|
2505
|
+
onClick: () => onRemove(filter.key),
|
|
2506
|
+
className: "ml-0.5 text-white/50 transition-colors duration-150 hover:text-white focus:outline-none focus-visible:text-white",
|
|
2507
|
+
"aria-label": `Remove filter: ${filter.label}`,
|
|
2508
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2509
|
+
"svg",
|
|
2510
|
+
{
|
|
2511
|
+
className: "h-3 w-3",
|
|
2512
|
+
viewBox: "0 0 12 12",
|
|
2513
|
+
fill: "none",
|
|
2514
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2515
|
+
"aria-hidden": "true",
|
|
2516
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2517
|
+
"path",
|
|
2518
|
+
{
|
|
2519
|
+
d: "M9 3L3 9M3 3L9 9",
|
|
2520
|
+
stroke: "currentColor",
|
|
2521
|
+
strokeWidth: "1.5",
|
|
2522
|
+
strokeLinecap: "round"
|
|
2523
|
+
}
|
|
2524
|
+
)
|
|
2525
|
+
}
|
|
2526
|
+
)
|
|
2527
|
+
}
|
|
2528
|
+
)
|
|
2529
|
+
]
|
|
2530
|
+
},
|
|
2531
|
+
filter.key
|
|
2532
|
+
)),
|
|
2533
|
+
filters.length > 1 && onClearAll && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2534
|
+
"button",
|
|
2535
|
+
{
|
|
2536
|
+
type: "button",
|
|
2537
|
+
onClick: onClearAll,
|
|
2538
|
+
className: "text-xs text-white/40 underline-offset-2 transition-colors duration-150 hover:text-white/70 focus:outline-none focus-visible:text-white/70",
|
|
2539
|
+
children: clearAllLabel
|
|
2540
|
+
}
|
|
2541
|
+
)
|
|
2542
|
+
] });
|
|
2543
|
+
}
|
|
2544
|
+
function SectionCard({
|
|
2545
|
+
title,
|
|
2546
|
+
description,
|
|
2547
|
+
right,
|
|
2548
|
+
overlay,
|
|
2549
|
+
children,
|
|
2550
|
+
className
|
|
2551
|
+
}) {
|
|
2552
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2553
|
+
"div",
|
|
2554
|
+
{
|
|
2555
|
+
className: cn(
|
|
2556
|
+
"relative bg-white/5 ring-1 ring-white/10 rounded-xl overflow-hidden",
|
|
2557
|
+
className
|
|
2558
|
+
),
|
|
2559
|
+
children: [
|
|
2560
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3 px-5 py-4 border-b border-white/[0.06]", children: [
|
|
2561
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
|
|
2562
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold text-white", children: title }),
|
|
2563
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-white/40 mt-0.5", children: description })
|
|
2564
|
+
] }),
|
|
2565
|
+
right && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: right })
|
|
2566
|
+
] }),
|
|
2567
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-5 py-4", children }),
|
|
2568
|
+
overlay
|
|
2569
|
+
]
|
|
2570
|
+
}
|
|
2571
|
+
);
|
|
2572
|
+
}
|
|
2573
|
+
var maxWidthClass = {
|
|
2574
|
+
sm: "max-w-2xl",
|
|
2575
|
+
md: "max-w-4xl",
|
|
2576
|
+
lg: "max-w-5xl",
|
|
2577
|
+
xl: "max-w-7xl",
|
|
2578
|
+
"2xl": "max-w-[92rem]",
|
|
2579
|
+
full: "max-w-full"
|
|
2580
|
+
};
|
|
2581
|
+
function defaultBackground() {
|
|
2582
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-0 overflow-hidden", children: [
|
|
2583
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-32 -left-32 h-[600px] w-[600px] rounded-full bg-violet-600/20 blur-[140px]" }),
|
|
2584
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-20 -right-32 h-[500px] w-[500px] rounded-full bg-purple-500/[0.12] blur-[120px]" }),
|
|
2585
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 left-1/2 h-[400px] w-[500px] -translate-x-1/2 rounded-full bg-accent/[0.10] blur-[120px]" })
|
|
2586
|
+
] });
|
|
2587
|
+
}
|
|
2588
|
+
function PageShell({
|
|
2589
|
+
header,
|
|
2590
|
+
background,
|
|
2591
|
+
variant = "plain",
|
|
2592
|
+
className,
|
|
2593
|
+
mainClassName,
|
|
2594
|
+
containerClassName,
|
|
2595
|
+
maxWidth = "xl",
|
|
2596
|
+
children
|
|
2597
|
+
}) {
|
|
2598
|
+
const showDefaultBackground = variant !== "minimal" && !background;
|
|
2599
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative overflow-hidden flex-1 min-h-full flex flex-col", className), children: [
|
|
2600
|
+
background,
|
|
2601
|
+
showDefaultBackground ? defaultBackground() : null,
|
|
2602
|
+
header,
|
|
2603
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2604
|
+
"main",
|
|
2605
|
+
{
|
|
2606
|
+
className: cn(
|
|
2607
|
+
"relative py-8 flex-1 w-full mx-auto px-4 sm:px-6 lg:px-8",
|
|
2608
|
+
maxWidthClass[maxWidth],
|
|
2609
|
+
containerClassName,
|
|
2610
|
+
mainClassName
|
|
2611
|
+
),
|
|
2612
|
+
children
|
|
2613
|
+
}
|
|
2614
|
+
)
|
|
2615
|
+
] });
|
|
2616
|
+
}
|
|
2617
|
+
function Navbar({ logo, children, className, glass = true }) {
|
|
2618
|
+
return /* @__PURE__ */ jsxRuntime.jsx("header", { className: cn("fixed top-0 w-full z-50", glass && "glass", className), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-7xl mx-auto px-6 h-16 flex items-center justify-between", children: [
|
|
2619
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: logo ?? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-9 h-9 rounded-xl animated-gradient" }) }),
|
|
2620
|
+
children && /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "Main navigation", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-4", children }) })
|
|
2621
|
+
] }) });
|
|
2622
|
+
}
|
|
2623
|
+
function Sidebar({ children, collapsed = false, onToggle, className }) {
|
|
2624
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2625
|
+
"aside",
|
|
2626
|
+
{
|
|
2627
|
+
className: cn(
|
|
2628
|
+
"glass h-full flex flex-col transition-[width] duration-200 overflow-hidden",
|
|
2629
|
+
collapsed ? "w-16" : "w-64",
|
|
2630
|
+
className
|
|
2631
|
+
),
|
|
2632
|
+
children: [
|
|
2633
|
+
onToggle && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2634
|
+
"button",
|
|
2635
|
+
{
|
|
2636
|
+
type: "button",
|
|
2637
|
+
onClick: onToggle,
|
|
2638
|
+
className: "flex items-center justify-center w-full h-12 text-white/40 hover:text-white hover:bg-white/5 transition-colors",
|
|
2639
|
+
"aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
|
|
2640
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2641
|
+
"svg",
|
|
2642
|
+
{
|
|
2643
|
+
className: cn("h-5 w-5 transition-transform duration-200", collapsed && "rotate-180"),
|
|
2644
|
+
fill: "none",
|
|
2645
|
+
viewBox: "0 0 24 24",
|
|
2646
|
+
stroke: "currentColor",
|
|
2647
|
+
strokeWidth: 2,
|
|
2648
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M11 19l-7-7 7-7m8 14l-7-7 7-7" })
|
|
2649
|
+
}
|
|
2650
|
+
)
|
|
2651
|
+
}
|
|
2652
|
+
),
|
|
2653
|
+
/* @__PURE__ */ jsxRuntime.jsx("nav", { className: "flex-1 overflow-y-auto py-2", children })
|
|
2654
|
+
]
|
|
2655
|
+
}
|
|
2656
|
+
);
|
|
2657
|
+
}
|
|
2658
|
+
var maxWidthClass2 = {
|
|
2659
|
+
sm: "max-w-2xl",
|
|
2660
|
+
md: "max-w-4xl",
|
|
2661
|
+
lg: "max-w-5xl",
|
|
2662
|
+
xl: "max-w-7xl",
|
|
2663
|
+
"2xl": "max-w-[92rem]",
|
|
1613
2664
|
full: "max-w-full"
|
|
1614
2665
|
};
|
|
1615
2666
|
function DashboardLayout({ children, navbar, sidebar, className, mainClassName, maxWidth = "lg" }) {
|
|
@@ -1625,7 +2676,320 @@ function DashboardLayout({ children, navbar, sidebar, className, mainClassName,
|
|
|
1625
2676
|
] })
|
|
1626
2677
|
] });
|
|
1627
2678
|
}
|
|
1628
|
-
var
|
|
2679
|
+
var variantBorderColor = {
|
|
2680
|
+
info: "border-blue-500",
|
|
2681
|
+
success: "border-emerald-500",
|
|
2682
|
+
warning: "border-amber-500",
|
|
2683
|
+
error: "border-rose-500"
|
|
2684
|
+
};
|
|
2685
|
+
var variantIconColor = {
|
|
2686
|
+
info: "text-blue-400",
|
|
2687
|
+
success: "text-emerald-400",
|
|
2688
|
+
warning: "text-amber-400",
|
|
2689
|
+
error: "text-rose-400"
|
|
2690
|
+
};
|
|
2691
|
+
function InfoIcon() {
|
|
2692
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2693
|
+
"svg",
|
|
2694
|
+
{
|
|
2695
|
+
"aria-hidden": "true",
|
|
2696
|
+
width: "18",
|
|
2697
|
+
height: "18",
|
|
2698
|
+
viewBox: "0 0 18 18",
|
|
2699
|
+
fill: "none",
|
|
2700
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2701
|
+
children: [
|
|
2702
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "9", cy: "9", r: "7.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
2703
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 8v5", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round" }),
|
|
2704
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "9", cy: "5.5", r: "0.875", fill: "currentColor" })
|
|
2705
|
+
]
|
|
2706
|
+
}
|
|
2707
|
+
);
|
|
2708
|
+
}
|
|
2709
|
+
function SuccessIcon() {
|
|
2710
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2711
|
+
"svg",
|
|
2712
|
+
{
|
|
2713
|
+
"aria-hidden": "true",
|
|
2714
|
+
width: "18",
|
|
2715
|
+
height: "18",
|
|
2716
|
+
viewBox: "0 0 18 18",
|
|
2717
|
+
fill: "none",
|
|
2718
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2719
|
+
children: [
|
|
2720
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "9", cy: "9", r: "7.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
2721
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2722
|
+
"path",
|
|
2723
|
+
{
|
|
2724
|
+
d: "M5.5 9.5l2.5 2.5 4.5-5",
|
|
2725
|
+
stroke: "currentColor",
|
|
2726
|
+
strokeWidth: "1.75",
|
|
2727
|
+
strokeLinecap: "round",
|
|
2728
|
+
strokeLinejoin: "round"
|
|
2729
|
+
}
|
|
2730
|
+
)
|
|
2731
|
+
]
|
|
2732
|
+
}
|
|
2733
|
+
);
|
|
2734
|
+
}
|
|
2735
|
+
function WarningIcon() {
|
|
2736
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2737
|
+
"svg",
|
|
2738
|
+
{
|
|
2739
|
+
"aria-hidden": "true",
|
|
2740
|
+
width: "18",
|
|
2741
|
+
height: "18",
|
|
2742
|
+
viewBox: "0 0 18 18",
|
|
2743
|
+
fill: "none",
|
|
2744
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2745
|
+
children: [
|
|
2746
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2747
|
+
"path",
|
|
2748
|
+
{
|
|
2749
|
+
d: "M7.634 2.896a1.6 1.6 0 0 1 2.732 0l5.866 10.167A1.6 1.6 0 0 1 14.866 15.5H3.134a1.6 1.6 0 0 1-1.366-2.437L7.634 2.896Z",
|
|
2750
|
+
stroke: "currentColor",
|
|
2751
|
+
strokeWidth: "1.5",
|
|
2752
|
+
strokeLinejoin: "round"
|
|
2753
|
+
}
|
|
2754
|
+
),
|
|
2755
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 7v4", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round" }),
|
|
2756
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "9", cy: "12.5", r: "0.875", fill: "currentColor" })
|
|
2757
|
+
]
|
|
2758
|
+
}
|
|
2759
|
+
);
|
|
2760
|
+
}
|
|
2761
|
+
function ErrorIcon() {
|
|
2762
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2763
|
+
"svg",
|
|
2764
|
+
{
|
|
2765
|
+
"aria-hidden": "true",
|
|
2766
|
+
width: "18",
|
|
2767
|
+
height: "18",
|
|
2768
|
+
viewBox: "0 0 18 18",
|
|
2769
|
+
fill: "none",
|
|
2770
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2771
|
+
children: [
|
|
2772
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "9", cy: "9", r: "7.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
2773
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2774
|
+
"path",
|
|
2775
|
+
{
|
|
2776
|
+
d: "M6.5 6.5l5 5M11.5 6.5l-5 5",
|
|
2777
|
+
stroke: "currentColor",
|
|
2778
|
+
strokeWidth: "1.75",
|
|
2779
|
+
strokeLinecap: "round"
|
|
2780
|
+
}
|
|
2781
|
+
)
|
|
2782
|
+
]
|
|
2783
|
+
}
|
|
2784
|
+
);
|
|
2785
|
+
}
|
|
2786
|
+
var variantIcon = {
|
|
2787
|
+
info: InfoIcon,
|
|
2788
|
+
success: SuccessIcon,
|
|
2789
|
+
warning: WarningIcon,
|
|
2790
|
+
error: ErrorIcon
|
|
2791
|
+
};
|
|
2792
|
+
function Alert({ variant = "info", title, children, onDismiss, className }) {
|
|
2793
|
+
const Icon = variantIcon[variant];
|
|
2794
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2795
|
+
"div",
|
|
2796
|
+
{
|
|
2797
|
+
role: "alert",
|
|
2798
|
+
className: cn(
|
|
2799
|
+
"flex items-start gap-3 rounded-xl bg-white/5 ring-1 ring-white/10",
|
|
2800
|
+
"border-l-4 pl-4 pr-3 py-3",
|
|
2801
|
+
variantBorderColor[variant],
|
|
2802
|
+
className
|
|
2803
|
+
),
|
|
2804
|
+
children: [
|
|
2805
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("mt-0.5 shrink-0", variantIconColor[variant]), children: /* @__PURE__ */ jsxRuntime.jsx(Icon, {}) }),
|
|
2806
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
2807
|
+
title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold text-white leading-snug mb-0.5", children: title }),
|
|
2808
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-white/70 leading-relaxed", children })
|
|
2809
|
+
] }),
|
|
2810
|
+
onDismiss && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2811
|
+
"button",
|
|
2812
|
+
{
|
|
2813
|
+
type: "button",
|
|
2814
|
+
"aria-label": "Dismiss",
|
|
2815
|
+
onClick: onDismiss,
|
|
2816
|
+
className: cn(
|
|
2817
|
+
"shrink-0 flex items-center justify-center h-6 w-6 rounded-lg mt-0.5",
|
|
2818
|
+
"text-white/40 transition-colors hover:bg-white/10 hover:text-white/80",
|
|
2819
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40"
|
|
2820
|
+
),
|
|
2821
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2822
|
+
"svg",
|
|
2823
|
+
{
|
|
2824
|
+
"aria-hidden": "true",
|
|
2825
|
+
width: "10",
|
|
2826
|
+
height: "10",
|
|
2827
|
+
viewBox: "0 0 10 10",
|
|
2828
|
+
fill: "none",
|
|
2829
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M1 1l8 8M9 1L1 9", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
2830
|
+
}
|
|
2831
|
+
)
|
|
2832
|
+
}
|
|
2833
|
+
)
|
|
2834
|
+
]
|
|
2835
|
+
}
|
|
2836
|
+
);
|
|
2837
|
+
}
|
|
2838
|
+
function CopyIcon() {
|
|
2839
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2840
|
+
"svg",
|
|
2841
|
+
{
|
|
2842
|
+
"aria-hidden": "true",
|
|
2843
|
+
width: "16",
|
|
2844
|
+
height: "16",
|
|
2845
|
+
viewBox: "0 0 16 16",
|
|
2846
|
+
fill: "none",
|
|
2847
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2848
|
+
children: [
|
|
2849
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "5", y: "5", width: "9", height: "9", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
|
|
2850
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2851
|
+
"path",
|
|
2852
|
+
{
|
|
2853
|
+
d: "M3.5 11H3a1.5 1.5 0 0 1-1.5-1.5V3A1.5 1.5 0 0 1 3 1.5h6.5A1.5 1.5 0 0 1 11 3v.5",
|
|
2854
|
+
stroke: "currentColor",
|
|
2855
|
+
strokeWidth: "1.5",
|
|
2856
|
+
strokeLinecap: "round"
|
|
2857
|
+
}
|
|
2858
|
+
)
|
|
2859
|
+
]
|
|
2860
|
+
}
|
|
2861
|
+
);
|
|
2862
|
+
}
|
|
2863
|
+
function CheckIcon() {
|
|
2864
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2865
|
+
"svg",
|
|
2866
|
+
{
|
|
2867
|
+
"aria-hidden": "true",
|
|
2868
|
+
width: "16",
|
|
2869
|
+
height: "16",
|
|
2870
|
+
viewBox: "0 0 16 16",
|
|
2871
|
+
fill: "none",
|
|
2872
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2873
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2874
|
+
"path",
|
|
2875
|
+
{
|
|
2876
|
+
d: "M3 8.5l3.5 3.5 6.5-7",
|
|
2877
|
+
stroke: "currentColor",
|
|
2878
|
+
strokeWidth: "1.75",
|
|
2879
|
+
strokeLinecap: "round",
|
|
2880
|
+
strokeLinejoin: "round"
|
|
2881
|
+
}
|
|
2882
|
+
)
|
|
2883
|
+
}
|
|
2884
|
+
);
|
|
2885
|
+
}
|
|
2886
|
+
function EyeIcon() {
|
|
2887
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2888
|
+
"svg",
|
|
2889
|
+
{
|
|
2890
|
+
"aria-hidden": "true",
|
|
2891
|
+
width: "16",
|
|
2892
|
+
height: "16",
|
|
2893
|
+
viewBox: "0 0 16 16",
|
|
2894
|
+
fill: "none",
|
|
2895
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2896
|
+
children: [
|
|
2897
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2898
|
+
"path",
|
|
2899
|
+
{
|
|
2900
|
+
d: "M1.5 8S3.5 3.5 8 3.5 14.5 8 14.5 8 12.5 12.5 8 12.5 1.5 8 1.5 8Z",
|
|
2901
|
+
stroke: "currentColor",
|
|
2902
|
+
strokeWidth: "1.5",
|
|
2903
|
+
strokeLinejoin: "round"
|
|
2904
|
+
}
|
|
2905
|
+
),
|
|
2906
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "8", r: "2", stroke: "currentColor", strokeWidth: "1.5" })
|
|
2907
|
+
]
|
|
2908
|
+
}
|
|
2909
|
+
);
|
|
2910
|
+
}
|
|
2911
|
+
function EyeOffIcon() {
|
|
2912
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2913
|
+
"svg",
|
|
2914
|
+
{
|
|
2915
|
+
"aria-hidden": "true",
|
|
2916
|
+
width: "16",
|
|
2917
|
+
height: "16",
|
|
2918
|
+
viewBox: "0 0 16 16",
|
|
2919
|
+
fill: "none",
|
|
2920
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2921
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2922
|
+
"path",
|
|
2923
|
+
{
|
|
2924
|
+
d: "M2 2l12 12M6.5 6.6A2 2 0 0 0 9.4 9.5M4.3 4.4C2.9 5.4 1.5 8 1.5 8S3.5 12.5 8 12.5c1.4 0 2.6-.4 3.7-1.1M6.7 3.6C7.1 3.5 7.5 3.5 8 3.5c4.5 0 6.5 4.5 6.5 4.5s-.5 1.2-1.5 2.3",
|
|
2925
|
+
stroke: "currentColor",
|
|
2926
|
+
strokeWidth: "1.5",
|
|
2927
|
+
strokeLinecap: "round",
|
|
2928
|
+
strokeLinejoin: "round"
|
|
2929
|
+
}
|
|
2930
|
+
)
|
|
2931
|
+
}
|
|
2932
|
+
);
|
|
2933
|
+
}
|
|
2934
|
+
var iconButtonBase = cn(
|
|
2935
|
+
"flex items-center justify-center h-7 w-7 rounded-lg shrink-0",
|
|
2936
|
+
"text-white/40 transition-colors hover:bg-white/10 hover:text-white/80",
|
|
2937
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40"
|
|
2938
|
+
);
|
|
2939
|
+
function CopyField({ value, label, masked = false, className, id: externalId }) {
|
|
2940
|
+
const generatedId = React.useId();
|
|
2941
|
+
const fieldId = externalId || generatedId;
|
|
2942
|
+
const { copy, copied } = useClipboard();
|
|
2943
|
+
const [revealed, setRevealed] = React.useState(false);
|
|
2944
|
+
const displayValue = masked && !revealed ? "\u2022".repeat(Math.min(value.length, 24)) : value;
|
|
2945
|
+
const field = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2946
|
+
"div",
|
|
2947
|
+
{
|
|
2948
|
+
className: cn(
|
|
2949
|
+
"flex items-center gap-1 w-full rounded-xl px-3 py-2.5",
|
|
2950
|
+
"bg-white/10 ring-1 ring-white/10",
|
|
2951
|
+
className
|
|
2952
|
+
),
|
|
2953
|
+
children: [
|
|
2954
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2955
|
+
"span",
|
|
2956
|
+
{
|
|
2957
|
+
id: fieldId,
|
|
2958
|
+
className: "flex-1 min-w-0 truncate text-sm text-white select-all font-mono",
|
|
2959
|
+
"aria-label": label,
|
|
2960
|
+
children: displayValue
|
|
2961
|
+
}
|
|
2962
|
+
),
|
|
2963
|
+
masked && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2964
|
+
"button",
|
|
2965
|
+
{
|
|
2966
|
+
type: "button",
|
|
2967
|
+
"aria-label": revealed ? "Hide value" : "Reveal value",
|
|
2968
|
+
onClick: () => setRevealed((v) => !v),
|
|
2969
|
+
className: iconButtonBase,
|
|
2970
|
+
children: revealed ? /* @__PURE__ */ jsxRuntime.jsx(EyeOffIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(EyeIcon, {})
|
|
2971
|
+
}
|
|
2972
|
+
),
|
|
2973
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2974
|
+
"button",
|
|
2975
|
+
{
|
|
2976
|
+
type: "button",
|
|
2977
|
+
"aria-label": copied ? "Copied!" : "Copy to clipboard",
|
|
2978
|
+
onClick: () => copy(value),
|
|
2979
|
+
className: cn(iconButtonBase, copied && "text-emerald-400 hover:text-emerald-400"),
|
|
2980
|
+
children: copied ? /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(CopyIcon, {})
|
|
2981
|
+
}
|
|
2982
|
+
)
|
|
2983
|
+
]
|
|
2984
|
+
}
|
|
2985
|
+
);
|
|
2986
|
+
if (!label) return field;
|
|
2987
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2988
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: fieldId, className: "block text-sm text-white/70 mb-1.5", children: label }),
|
|
2989
|
+
field
|
|
2990
|
+
] });
|
|
2991
|
+
}
|
|
2992
|
+
var ProgressButton = React.forwardRef(
|
|
1629
2993
|
function ProgressButton2({ isLoading, loadingText, children, disabled, className, ...props }, ref) {
|
|
1630
2994
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1631
2995
|
Button,
|
|
@@ -1664,7 +3028,7 @@ function reducer(state, action) {
|
|
|
1664
3028
|
return state;
|
|
1665
3029
|
}
|
|
1666
3030
|
}
|
|
1667
|
-
var ToastContext =
|
|
3031
|
+
var ToastContext = React.createContext(null);
|
|
1668
3032
|
var variantBarColor = {
|
|
1669
3033
|
success: "bg-emerald-500",
|
|
1670
3034
|
error: "bg-rose-500",
|
|
@@ -1683,7 +3047,7 @@ var variantIconLabel = {
|
|
|
1683
3047
|
warning: "\u26A0",
|
|
1684
3048
|
info: "i"
|
|
1685
3049
|
};
|
|
1686
|
-
var
|
|
3050
|
+
var variantIconColor2 = {
|
|
1687
3051
|
success: "text-emerald-400",
|
|
1688
3052
|
error: "text-rose-400",
|
|
1689
3053
|
warning: "text-amber-400",
|
|
@@ -1697,13 +3061,13 @@ var positionClass = {
|
|
|
1697
3061
|
};
|
|
1698
3062
|
function ToastCard({ toast, onDismiss }) {
|
|
1699
3063
|
const duration = toast.duration ?? 5e3;
|
|
1700
|
-
const [visible, setVisible] =
|
|
1701
|
-
const [exiting, setExiting] =
|
|
1702
|
-
const [started, setStarted] =
|
|
1703
|
-
const dismissedRef =
|
|
1704
|
-
const timerRef =
|
|
1705
|
-
const exitTimerRef =
|
|
1706
|
-
|
|
3064
|
+
const [visible, setVisible] = React.useState(false);
|
|
3065
|
+
const [exiting, setExiting] = React.useState(false);
|
|
3066
|
+
const [started, setStarted] = React.useState(false);
|
|
3067
|
+
const dismissedRef = React.useRef(false);
|
|
3068
|
+
const timerRef = React.useRef(null);
|
|
3069
|
+
const exitTimerRef = React.useRef(null);
|
|
3070
|
+
React.useEffect(() => {
|
|
1707
3071
|
let innerFrame;
|
|
1708
3072
|
const frame = requestAnimationFrame(() => {
|
|
1709
3073
|
setVisible(true);
|
|
@@ -1714,19 +3078,19 @@ function ToastCard({ toast, onDismiss }) {
|
|
|
1714
3078
|
cancelAnimationFrame(innerFrame);
|
|
1715
3079
|
};
|
|
1716
3080
|
}, []);
|
|
1717
|
-
|
|
3081
|
+
React.useEffect(() => {
|
|
1718
3082
|
return () => {
|
|
1719
3083
|
if (exitTimerRef.current !== null) clearTimeout(exitTimerRef.current);
|
|
1720
3084
|
};
|
|
1721
3085
|
}, []);
|
|
1722
|
-
const triggerDismiss =
|
|
3086
|
+
const triggerDismiss = React.useCallback(() => {
|
|
1723
3087
|
if (dismissedRef.current) return;
|
|
1724
3088
|
dismissedRef.current = true;
|
|
1725
3089
|
if (timerRef.current !== null) clearTimeout(timerRef.current);
|
|
1726
3090
|
setExiting(true);
|
|
1727
3091
|
exitTimerRef.current = setTimeout(() => onDismiss(toast.id), 280);
|
|
1728
3092
|
}, [onDismiss, toast.id]);
|
|
1729
|
-
|
|
3093
|
+
React.useEffect(() => {
|
|
1730
3094
|
if (duration <= 0) return;
|
|
1731
3095
|
timerRef.current = setTimeout(triggerDismiss, duration);
|
|
1732
3096
|
return () => {
|
|
@@ -1759,7 +3123,7 @@ function ToastCard({ toast, onDismiss }) {
|
|
|
1759
3123
|
"aria-hidden": "true",
|
|
1760
3124
|
className: cn(
|
|
1761
3125
|
"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-[11px] font-bold ring-1",
|
|
1762
|
-
|
|
3126
|
+
variantIconColor2[toast.variant],
|
|
1763
3127
|
"ring-current/30"
|
|
1764
3128
|
),
|
|
1765
3129
|
children: variantIconLabel[toast.variant]
|
|
@@ -1805,11 +3169,11 @@ function ToastCard({ toast, onDismiss }) {
|
|
|
1805
3169
|
);
|
|
1806
3170
|
}
|
|
1807
3171
|
function ToastProvider({ children, position = "top-right", maxToasts = 5 }) {
|
|
1808
|
-
const [toasts, dispatch] =
|
|
1809
|
-
const counterRef =
|
|
1810
|
-
const maxToastsRef =
|
|
3172
|
+
const [toasts, dispatch] = React.useReducer(reducer, []);
|
|
3173
|
+
const counterRef = React.useRef(0);
|
|
3174
|
+
const maxToastsRef = React.useRef(maxToasts);
|
|
1811
3175
|
maxToastsRef.current = maxToasts;
|
|
1812
|
-
const toast =
|
|
3176
|
+
const toast = React.useCallback(
|
|
1813
3177
|
(options) => {
|
|
1814
3178
|
const id = `toast-${++counterRef.current}`;
|
|
1815
3179
|
const newToast = {
|
|
@@ -1824,13 +3188,13 @@ function ToastProvider({ children, position = "top-right", maxToasts = 5 }) {
|
|
|
1824
3188
|
},
|
|
1825
3189
|
[]
|
|
1826
3190
|
);
|
|
1827
|
-
const dismiss =
|
|
3191
|
+
const dismiss = React.useCallback((id) => {
|
|
1828
3192
|
dispatch({ type: "REMOVE", id });
|
|
1829
3193
|
}, []);
|
|
1830
|
-
const dismissAll =
|
|
3194
|
+
const dismissAll = React.useCallback(() => {
|
|
1831
3195
|
dispatch({ type: "REMOVE_ALL" });
|
|
1832
3196
|
}, []);
|
|
1833
|
-
const value =
|
|
3197
|
+
const value = React.useMemo(() => ({ toast, dismiss, dismissAll }), [toast, dismiss, dismissAll]);
|
|
1834
3198
|
const container = typeof document !== "undefined" ? reactDom.createPortal(
|
|
1835
3199
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1836
3200
|
"div",
|
|
@@ -1848,20 +3212,140 @@ function ToastProvider({ children, position = "top-right", maxToasts = 5 }) {
|
|
|
1848
3212
|
] });
|
|
1849
3213
|
}
|
|
1850
3214
|
function useToast() {
|
|
1851
|
-
const ctx =
|
|
3215
|
+
const ctx = React.useContext(ToastContext);
|
|
1852
3216
|
if (!ctx) {
|
|
1853
3217
|
throw new Error("useToast must be used inside <ToastProvider>");
|
|
1854
3218
|
}
|
|
1855
3219
|
return ctx;
|
|
1856
3220
|
}
|
|
3221
|
+
function SavingIcon() {
|
|
3222
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3223
|
+
"svg",
|
|
3224
|
+
{
|
|
3225
|
+
className: "h-5 w-5 animate-spin text-white/70",
|
|
3226
|
+
viewBox: "0 0 24 24",
|
|
3227
|
+
fill: "none",
|
|
3228
|
+
"aria-hidden": "true",
|
|
3229
|
+
children: [
|
|
3230
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3231
|
+
"circle",
|
|
3232
|
+
{
|
|
3233
|
+
className: "opacity-25",
|
|
3234
|
+
cx: "12",
|
|
3235
|
+
cy: "12",
|
|
3236
|
+
r: "10",
|
|
3237
|
+
stroke: "currentColor",
|
|
3238
|
+
strokeWidth: "4"
|
|
3239
|
+
}
|
|
3240
|
+
),
|
|
3241
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3242
|
+
"path",
|
|
3243
|
+
{
|
|
3244
|
+
className: "opacity-75",
|
|
3245
|
+
fill: "currentColor",
|
|
3246
|
+
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
|
3247
|
+
}
|
|
3248
|
+
)
|
|
3249
|
+
]
|
|
3250
|
+
}
|
|
3251
|
+
);
|
|
3252
|
+
}
|
|
3253
|
+
function SavedIcon() {
|
|
3254
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3255
|
+
"svg",
|
|
3256
|
+
{
|
|
3257
|
+
className: "h-5 w-5 text-green-400",
|
|
3258
|
+
viewBox: "0 0 24 24",
|
|
3259
|
+
fill: "none",
|
|
3260
|
+
stroke: "currentColor",
|
|
3261
|
+
strokeWidth: 2,
|
|
3262
|
+
"aria-hidden": "true",
|
|
3263
|
+
children: [
|
|
3264
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10", strokeOpacity: 0.4 }),
|
|
3265
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 12l2 2 4-4" })
|
|
3266
|
+
]
|
|
3267
|
+
}
|
|
3268
|
+
);
|
|
3269
|
+
}
|
|
3270
|
+
function ErrorIcon2() {
|
|
3271
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3272
|
+
"svg",
|
|
3273
|
+
{
|
|
3274
|
+
className: "h-5 w-5 text-red-400",
|
|
3275
|
+
viewBox: "0 0 24 24",
|
|
3276
|
+
fill: "none",
|
|
3277
|
+
stroke: "currentColor",
|
|
3278
|
+
strokeWidth: 2,
|
|
3279
|
+
"aria-hidden": "true",
|
|
3280
|
+
children: [
|
|
3281
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10", strokeOpacity: 0.4 }),
|
|
3282
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 9l-6 6M9 9l6 6" })
|
|
3283
|
+
]
|
|
3284
|
+
}
|
|
3285
|
+
);
|
|
3286
|
+
}
|
|
3287
|
+
var statusConfig = {
|
|
3288
|
+
saving: {
|
|
3289
|
+
icon: SavingIcon,
|
|
3290
|
+
defaultText: "Saving...",
|
|
3291
|
+
textClass: "text-white/70"
|
|
3292
|
+
},
|
|
3293
|
+
saved: {
|
|
3294
|
+
icon: SavedIcon,
|
|
3295
|
+
defaultText: "Saved",
|
|
3296
|
+
textClass: "text-green-400"
|
|
3297
|
+
},
|
|
3298
|
+
error: {
|
|
3299
|
+
icon: ErrorIcon2,
|
|
3300
|
+
defaultText: "Error",
|
|
3301
|
+
textClass: "text-red-400"
|
|
3302
|
+
}
|
|
3303
|
+
};
|
|
3304
|
+
function MutationOverlay({
|
|
3305
|
+
status,
|
|
3306
|
+
savingText,
|
|
3307
|
+
savedText,
|
|
3308
|
+
errorText,
|
|
3309
|
+
className
|
|
3310
|
+
}) {
|
|
3311
|
+
if (status === "idle") return null;
|
|
3312
|
+
const config = statusConfig[status];
|
|
3313
|
+
const Icon = config.icon;
|
|
3314
|
+
const text = status === "saving" ? savingText ?? config.defaultText : status === "saved" ? savedText ?? config.defaultText : errorText ?? config.defaultText;
|
|
3315
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3316
|
+
"div",
|
|
3317
|
+
{
|
|
3318
|
+
className: cn(
|
|
3319
|
+
"absolute inset-0 z-10 flex items-center justify-center",
|
|
3320
|
+
"bg-surface-50/80 backdrop-blur-sm",
|
|
3321
|
+
"transition-opacity duration-200",
|
|
3322
|
+
className
|
|
3323
|
+
),
|
|
3324
|
+
role: "status",
|
|
3325
|
+
"aria-live": "polite",
|
|
3326
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3327
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon, {}),
|
|
3328
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-sm font-medium", config.textClass), children: text })
|
|
3329
|
+
] })
|
|
3330
|
+
}
|
|
3331
|
+
);
|
|
3332
|
+
}
|
|
1857
3333
|
|
|
3334
|
+
exports.ActiveFilterPills = ActiveFilterPills;
|
|
3335
|
+
exports.Alert = Alert;
|
|
3336
|
+
exports.Avatar = Avatar;
|
|
1858
3337
|
exports.Badge = Badge;
|
|
1859
3338
|
exports.Button = Button;
|
|
1860
3339
|
exports.Card = Card;
|
|
1861
3340
|
exports.Checkbox = Checkbox;
|
|
1862
3341
|
exports.CollapsibleSection = CollapsibleSection;
|
|
3342
|
+
exports.ColorInput = ColorInput;
|
|
1863
3343
|
exports.ConfirmDialog = ConfirmDialog;
|
|
3344
|
+
exports.CooldownRing = CooldownRing;
|
|
3345
|
+
exports.CopyField = CopyField;
|
|
1864
3346
|
exports.DashboardLayout = DashboardLayout;
|
|
3347
|
+
exports.Divider = Divider;
|
|
3348
|
+
exports.DotIndicator = DotIndicator;
|
|
1865
3349
|
exports.DropZone = DropZone;
|
|
1866
3350
|
exports.Dropdown = Dropdown;
|
|
1867
3351
|
exports.DropdownItem = DropdownItem;
|
|
@@ -1869,24 +3353,40 @@ exports.DropdownMenu = DropdownMenu;
|
|
|
1869
3353
|
exports.DropdownSeparator = DropdownSeparator;
|
|
1870
3354
|
exports.DropdownTrigger = DropdownTrigger;
|
|
1871
3355
|
exports.EmptyState = EmptyState;
|
|
3356
|
+
exports.FormField = FormField;
|
|
1872
3357
|
exports.IconButton = IconButton;
|
|
1873
3358
|
exports.Input = Input;
|
|
1874
3359
|
exports.Modal = Modal;
|
|
3360
|
+
exports.MutationOverlay = MutationOverlay;
|
|
1875
3361
|
exports.Navbar = Navbar;
|
|
1876
3362
|
exports.PageShell = PageShell;
|
|
3363
|
+
exports.Pagination = Pagination;
|
|
1877
3364
|
exports.Pill = Pill;
|
|
3365
|
+
exports.ProgressBar = ProgressBar;
|
|
1878
3366
|
exports.ProgressButton = ProgressButton;
|
|
1879
3367
|
exports.RadioGroup = RadioGroup;
|
|
1880
3368
|
exports.RadioItem = RadioItem;
|
|
1881
3369
|
exports.SearchInput = SearchInput;
|
|
3370
|
+
exports.SectionCard = SectionCard;
|
|
1882
3371
|
exports.Select = Select;
|
|
1883
3372
|
exports.Sidebar = Sidebar;
|
|
1884
3373
|
exports.Skeleton = Skeleton;
|
|
3374
|
+
exports.Slider = Slider;
|
|
1885
3375
|
exports.Spinner = Spinner;
|
|
3376
|
+
exports.StageProgress = StageProgress;
|
|
3377
|
+
exports.StatCard = StatCard;
|
|
3378
|
+
exports.Stepper = Stepper;
|
|
1886
3379
|
exports.Tab = Tab;
|
|
1887
3380
|
exports.TabList = TabList;
|
|
1888
3381
|
exports.TabPanel = TabPanel;
|
|
3382
|
+
exports.Table = Table;
|
|
3383
|
+
exports.TableBody = TableBody;
|
|
3384
|
+
exports.TableCell = TableCell;
|
|
3385
|
+
exports.TableHead = TableHead;
|
|
3386
|
+
exports.TableHeader = TableHeader;
|
|
3387
|
+
exports.TableRow = TableRow;
|
|
1889
3388
|
exports.Tabs = Tabs;
|
|
3389
|
+
exports.TagInput = TagInput;
|
|
1890
3390
|
exports.Textarea = Textarea;
|
|
1891
3391
|
exports.ToastProvider = ToastProvider;
|
|
1892
3392
|
exports.Toggle = Toggle;
|