@rdna/radiants 0.1.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.
Files changed (44) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +125 -0
  3. package/animations.css +68 -0
  4. package/assets/scrollbar-background.svg +9 -0
  5. package/base.css +144 -0
  6. package/dark.css +117 -0
  7. package/dist/chunk-SR2T7OEJ.mjs +46 -0
  8. package/dist/chunk-SR2T7OEJ.mjs.map +1 -0
  9. package/dist/components/core/index.d.mts +911 -0
  10. package/dist/components/core/index.mjs +2475 -0
  11. package/dist/components/core/index.mjs.map +1 -0
  12. package/dist/hooks/index.d.mts +22 -0
  13. package/dist/hooks/index.mjs +3 -0
  14. package/dist/hooks/index.mjs.map +1 -0
  15. package/dist/remotion/index.d.mts +252 -0
  16. package/dist/remotion/index.mjs +170 -0
  17. package/dist/remotion/index.mjs.map +1 -0
  18. package/dna.config.json +8 -0
  19. package/fonts/Joystix.woff2 +0 -0
  20. package/fonts/PixelCode-Black-Italic.woff2 +0 -0
  21. package/fonts/PixelCode-Black.woff2 +0 -0
  22. package/fonts/PixelCode-Bold-Italic.woff2 +0 -0
  23. package/fonts/PixelCode-Bold.woff2 +0 -0
  24. package/fonts/PixelCode-DemiBold-Italic.woff2 +0 -0
  25. package/fonts/PixelCode-DemiBold.woff2 +0 -0
  26. package/fonts/PixelCode-ExtraBlack-Italic.woff2 +0 -0
  27. package/fonts/PixelCode-ExtraBlack.woff2 +0 -0
  28. package/fonts/PixelCode-ExtraBold-Italic.woff2 +0 -0
  29. package/fonts/PixelCode-ExtraBold.woff2 +0 -0
  30. package/fonts/PixelCode-ExtraLight-Italic.woff2 +0 -0
  31. package/fonts/PixelCode-ExtraLight.woff2 +0 -0
  32. package/fonts/PixelCode-Italic.woff2 +0 -0
  33. package/fonts/PixelCode-Light-Italic.woff2 +0 -0
  34. package/fonts/PixelCode-Light.woff2 +0 -0
  35. package/fonts/PixelCode-Medium-Italic.woff2 +0 -0
  36. package/fonts/PixelCode-Medium.woff2 +0 -0
  37. package/fonts/PixelCode-Thin-Italic.woff2 +0 -0
  38. package/fonts/PixelCode-Thin.woff2 +0 -0
  39. package/fonts/PixelCode.woff2 +0 -0
  40. package/fonts.css +115 -0
  41. package/index.css +25 -0
  42. package/package.json +88 -0
  43. package/tokens.css +202 -0
  44. package/typography.css +175 -0
@@ -0,0 +1,2475 @@
1
+ import { useClickOutside, useEscapeKey, useLockBodyScroll } from '../../chunk-SR2T7OEJ.mjs';
2
+ import React14, { createContext, forwardRef, useState, useEffect, useCallback, useRef, useContext } from 'react';
3
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
+ import Link from 'next/link';
5
+ import { createPortal } from 'react-dom';
6
+
7
+ var AccordionContext = createContext(null);
8
+ var AccordionItemContext = createContext(null);
9
+ function useAccordionContext() {
10
+ const context = useContext(AccordionContext);
11
+ if (!context) {
12
+ throw new Error("Accordion components must be used within an Accordion");
13
+ }
14
+ return context;
15
+ }
16
+ function useAccordionItemContext() {
17
+ const context = useContext(AccordionItemContext);
18
+ if (!context) {
19
+ throw new Error("AccordionTrigger/AccordionContent must be used within an AccordionItem");
20
+ }
21
+ return context;
22
+ }
23
+ function Accordion({
24
+ type = "single",
25
+ defaultValue,
26
+ value: controlledValue,
27
+ onValueChange,
28
+ className = "",
29
+ children
30
+ }) {
31
+ const getInitialExpanded = () => {
32
+ const initial = controlledValue ?? defaultValue;
33
+ if (!initial) return /* @__PURE__ */ new Set();
34
+ return new Set(Array.isArray(initial) ? initial : [initial]);
35
+ };
36
+ const [expandedItems, setExpandedItems] = useState(getInitialExpanded);
37
+ useEffect(() => {
38
+ if (controlledValue !== void 0) {
39
+ setExpandedItems(new Set(Array.isArray(controlledValue) ? controlledValue : [controlledValue]));
40
+ }
41
+ }, [controlledValue]);
42
+ const toggleItem = useCallback((itemValue) => {
43
+ setExpandedItems((prev) => {
44
+ const next = new Set(prev);
45
+ if (next.has(itemValue)) {
46
+ next.delete(itemValue);
47
+ } else {
48
+ if (type === "single") {
49
+ next.clear();
50
+ }
51
+ next.add(itemValue);
52
+ }
53
+ if (onValueChange) {
54
+ const newValue = Array.from(next);
55
+ onValueChange(type === "single" ? newValue[0] ?? "" : newValue);
56
+ }
57
+ return next;
58
+ });
59
+ }, [type, onValueChange]);
60
+ return /* @__PURE__ */ jsx(AccordionContext.Provider, { value: { type, expandedItems, toggleItem }, children: /* @__PURE__ */ jsx("div", { className: `space-y-0 ${className}`, children }) });
61
+ }
62
+ function AccordionItem({ value, className = "", children }) {
63
+ const { expandedItems } = useAccordionContext();
64
+ const isExpanded = expandedItems.has(value);
65
+ return /* @__PURE__ */ jsx(AccordionItemContext.Provider, { value: { value, isExpanded }, children: /* @__PURE__ */ jsx(
66
+ "div",
67
+ {
68
+ className: `
69
+ border border-edge-primary
70
+ bg-surface-primary
71
+ -mt-px first:mt-0
72
+ ${className}
73
+ `.trim(),
74
+ "data-state": isExpanded ? "open" : "closed",
75
+ children
76
+ }
77
+ ) });
78
+ }
79
+ function AccordionTrigger({ className = "", children }) {
80
+ const { toggleItem } = useAccordionContext();
81
+ const { value, isExpanded } = useAccordionItemContext();
82
+ return /* @__PURE__ */ jsxs(
83
+ "button",
84
+ {
85
+ type: "button",
86
+ onClick: () => toggleItem(value),
87
+ className: `
88
+ w-full flex items-center justify-between
89
+ px-4 py-3
90
+ font-joystix text-sm uppercase text-content-primary
91
+ bg-transparent
92
+ hover:bg-content-primary/5
93
+ transition-colors
94
+ cursor-pointer
95
+ ${className}
96
+ `.trim(),
97
+ "aria-expanded": isExpanded,
98
+ children: [
99
+ /* @__PURE__ */ jsx("span", { children }),
100
+ /* @__PURE__ */ jsx(
101
+ "span",
102
+ {
103
+ className: "text-[1rem] font-mondwest select-none",
104
+ "aria-hidden": "true",
105
+ children: isExpanded ? "\u2212" : "+"
106
+ }
107
+ )
108
+ ]
109
+ }
110
+ );
111
+ }
112
+ function AccordionContent({ className = "", children }) {
113
+ const { isExpanded } = useAccordionItemContext();
114
+ const contentRef = useRef(null);
115
+ const [height, setHeight] = useState(void 0);
116
+ const [isAnimating, setIsAnimating] = useState(false);
117
+ useEffect(() => {
118
+ const content = contentRef.current;
119
+ if (!content) return;
120
+ if (isExpanded) {
121
+ const scrollHeight = content.scrollHeight;
122
+ setHeight(scrollHeight);
123
+ setIsAnimating(true);
124
+ const timer = setTimeout(() => {
125
+ setIsAnimating(false);
126
+ setHeight(void 0);
127
+ }, 200);
128
+ return () => clearTimeout(timer);
129
+ } else {
130
+ const scrollHeight = content.scrollHeight;
131
+ setHeight(scrollHeight);
132
+ setIsAnimating(true);
133
+ requestAnimationFrame(() => {
134
+ setHeight(0);
135
+ });
136
+ const timer = setTimeout(() => {
137
+ setIsAnimating(false);
138
+ }, 200);
139
+ return () => clearTimeout(timer);
140
+ }
141
+ }, [isExpanded]);
142
+ return /* @__PURE__ */ jsx(
143
+ "div",
144
+ {
145
+ ref: contentRef,
146
+ className: `
147
+ overflow-hidden
148
+ transition-[height] duration-200 ease-out
149
+ ${className}
150
+ `.trim(),
151
+ style: {
152
+ height: isAnimating ? height : isExpanded ? "auto" : 0
153
+ },
154
+ "aria-hidden": !isExpanded,
155
+ children: /* @__PURE__ */ jsx("div", { className: "px-4 pb-4", children })
156
+ }
157
+ );
158
+ }
159
+ var variantStyles = {
160
+ default: "bg-surface-primary border-edge-primary text-content-primary",
161
+ success: "bg-status-success/10 border-status-success text-content-primary",
162
+ warning: "bg-status-warning/10 border-status-warning text-content-primary",
163
+ error: "bg-status-error/10 border-status-error text-content-primary",
164
+ info: "bg-status-info/10 border-status-info text-content-primary"
165
+ };
166
+ function Alert({
167
+ variant = "default",
168
+ title,
169
+ children,
170
+ closable = false,
171
+ onClose,
172
+ icon,
173
+ closeIcon,
174
+ className = ""
175
+ }) {
176
+ return /* @__PURE__ */ jsx(
177
+ "div",
178
+ {
179
+ role: "alert",
180
+ className: `
181
+ p-4
182
+ border-2
183
+ rounded-sm
184
+ ${variantStyles[variant]}
185
+ ${className}
186
+ `.trim(),
187
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
188
+ icon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0 mt-0.5", children: icon }),
189
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
190
+ title && /* @__PURE__ */ jsx("p", { className: "font-joystix text-xs uppercase mb-1", children: title }),
191
+ /* @__PURE__ */ jsx("div", { className: "font-mondwest text-base text-content-primary/80", children })
192
+ ] }),
193
+ closable && /* @__PURE__ */ jsx(
194
+ "button",
195
+ {
196
+ onClick: onClose,
197
+ className: "text-content-primary/50 hover:text-content-primary flex-shrink-0 -mt-1",
198
+ "aria-label": "Close",
199
+ children: closeIcon || /* @__PURE__ */ jsx(
200
+ "svg",
201
+ {
202
+ width: "16",
203
+ height: "16",
204
+ viewBox: "0 0 16 16",
205
+ fill: "none",
206
+ xmlns: "http://www.w3.org/2000/svg",
207
+ children: /* @__PURE__ */ jsx(
208
+ "path",
209
+ {
210
+ d: "M12 4L4 12M4 4L12 12",
211
+ stroke: "currentColor",
212
+ strokeWidth: "2",
213
+ strokeLinecap: "round",
214
+ strokeLinejoin: "round"
215
+ }
216
+ )
217
+ }
218
+ )
219
+ }
220
+ )
221
+ ] })
222
+ }
223
+ );
224
+ }
225
+ var baseStyles = `
226
+ inline-flex items-center justify-center
227
+ font-joystix uppercase
228
+ rounded-sm
229
+ whitespace-nowrap
230
+ `;
231
+ var sizeStyles = {
232
+ sm: "px-2 py-0.5 text-2xs",
233
+ md: "px-2.5 py-1 text-xs"
234
+ };
235
+ var variantStyles2 = {
236
+ default: "bg-surface-primary text-content-primary border border-edge-primary",
237
+ success: "bg-status-success text-content-primary border border-edge-primary",
238
+ warning: "bg-status-warning text-content-primary border border-edge-primary",
239
+ error: "bg-status-error text-content-primary border border-edge-primary",
240
+ info: "bg-status-info text-content-primary border border-edge-primary"
241
+ };
242
+ function Badge({
243
+ variant = "default",
244
+ size = "md",
245
+ children,
246
+ className = ""
247
+ }) {
248
+ const classes = [
249
+ baseStyles,
250
+ sizeStyles[size],
251
+ variantStyles2[variant],
252
+ className
253
+ ].join(" ").replace(/\s+/g, " ").trim();
254
+ return /* @__PURE__ */ jsx("span", { className: classes, children });
255
+ }
256
+ function Breadcrumbs({
257
+ items,
258
+ separator = "/",
259
+ className = ""
260
+ }) {
261
+ if (items.length === 0) return null;
262
+ return /* @__PURE__ */ jsx(
263
+ "nav",
264
+ {
265
+ "aria-label": "Breadcrumb",
266
+ className: `flex items-center gap-2 ${className}`.trim(),
267
+ children: /* @__PURE__ */ jsx("ol", { className: "flex items-center gap-2", children: items.map((item, index) => {
268
+ const isLast = index === items.length - 1;
269
+ return /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-2", children: [
270
+ index > 0 && /* @__PURE__ */ jsx(
271
+ "span",
272
+ {
273
+ className: "font-mondwest text-base text-content-primary/40",
274
+ "aria-hidden": "true",
275
+ children: separator
276
+ }
277
+ ),
278
+ item.href && !isLast ? /* @__PURE__ */ jsx(
279
+ Link,
280
+ {
281
+ href: item.href,
282
+ className: "font-mondwest text-base text-content-primary/60 hover:text-content-primary hover:underline transition-colors",
283
+ children: item.label
284
+ }
285
+ ) : /* @__PURE__ */ jsx(
286
+ "span",
287
+ {
288
+ className: `
289
+ font-mondwest text-base
290
+ ${isLast ? "text-content-primary font-semibold" : "text-content-primary/60"}
291
+ `.trim(),
292
+ "aria-current": isLast ? "page" : void 0,
293
+ children: item.label
294
+ }
295
+ )
296
+ ] }, index);
297
+ }) })
298
+ }
299
+ );
300
+ }
301
+ var baseStyles2 = `
302
+ inline-flex items-center
303
+ font-heading uppercase
304
+ whitespace-nowrap
305
+ cursor-pointer select-none
306
+ border border-edge-primary
307
+ rounded-sm
308
+ shadow-btn
309
+ hover:-translate-y-0.5
310
+ hover:shadow-btn-hover
311
+ active:translate-y-0.5
312
+ active:shadow-none
313
+ disabled:opacity-50 disabled:cursor-not-allowed
314
+ disabled:hover:translate-y-0 disabled:hover:shadow-btn
315
+ focus:outline-none focus-visible:ring-2 focus-visible:ring-edge-focus focus-visible:ring-offset-1
316
+ `;
317
+ var sizeStyles2 = {
318
+ sm: "h-8 px-3 text-xs gap-3",
319
+ md: "h-8 px-3 text-xs gap-3",
320
+ lg: "h-8 px-3 text-sm gap-3"
321
+ };
322
+ var iconOnlySizeStyles = {
323
+ sm: "w-8 h-8 p-0",
324
+ md: "w-8 h-8 p-0",
325
+ lg: "w-8 h-8 p-0"
326
+ };
327
+ var variantStyles3 = {
328
+ primary: `
329
+ bg-action-primary text-content-primary
330
+ hover:bg-action-primary
331
+ active:bg-action-primary
332
+ `,
333
+ secondary: `
334
+ bg-surface-secondary text-content-inverted
335
+ hover:bg-surface-primary hover:text-content-primary
336
+ active:bg-action-primary active:text-content-primary
337
+ `,
338
+ outline: `
339
+ bg-transparent text-content-primary
340
+ shadow-none
341
+ hover:bg-content-primary/5 hover:!translate-y-0 hover:shadow-none
342
+ active:bg-action-primary active:!translate-y-0 active:shadow-none
343
+ `,
344
+ ghost: `
345
+ bg-transparent text-content-primary
346
+ border-transparent
347
+ shadow-none
348
+ hover:bg-transparent hover:border-edge-primary hover:text-content-primary hover:shadow-none hover:translate-y-0
349
+ active:bg-action-primary active:text-content-primary active:border-edge-primary active:translate-y-0
350
+ `
351
+ };
352
+ function getButtonClasses(variant, size, iconOnly, fullWidth, className, hasIcon) {
353
+ let justifyClass = "justify-start";
354
+ if (iconOnly) {
355
+ justifyClass = "justify-center";
356
+ } else if (fullWidth && hasIcon) {
357
+ justifyClass = "justify-between";
358
+ }
359
+ return [
360
+ baseStyles2,
361
+ iconOnly ? iconOnlySizeStyles[size] : sizeStyles2[size],
362
+ justifyClass,
363
+ variantStyles3[variant],
364
+ fullWidth ? "w-full" : "",
365
+ className
366
+ ].join(" ").replace(/\s+/g, " ").trim();
367
+ }
368
+ function Button(props) {
369
+ const {
370
+ variant = "primary",
371
+ size = "md",
372
+ fullWidth = false,
373
+ iconOnly = false,
374
+ icon,
375
+ loadingIndicator,
376
+ loading = false,
377
+ children,
378
+ className = "",
379
+ ...rest
380
+ } = props;
381
+ const hasIcon = Boolean(icon || iconOnly);
382
+ const showLoading = Boolean(loading && hasIcon && loadingIndicator);
383
+ const classes = getButtonClasses(variant, size, iconOnly, fullWidth, className, hasIcon);
384
+ const content = showLoading ? /* @__PURE__ */ jsxs(Fragment, { children: [
385
+ !iconOnly && children,
386
+ loadingIndicator
387
+ ] }) : icon ? /* @__PURE__ */ jsxs(Fragment, { children: [
388
+ !iconOnly && children,
389
+ icon
390
+ ] }) : children;
391
+ if ("href" in props && props.href) {
392
+ const { href, asLink = true, target, ...linkRest } = rest;
393
+ if (asLink) {
394
+ return /* @__PURE__ */ jsx(
395
+ "a",
396
+ {
397
+ href,
398
+ target,
399
+ className: classes,
400
+ ...linkRest,
401
+ children: content
402
+ }
403
+ );
404
+ }
405
+ const linkButtonDisabled = showLoading || Boolean(linkRest.disabled);
406
+ const { disabled: _2, ...linkButtonRest } = linkRest;
407
+ return /* @__PURE__ */ jsx(
408
+ "button",
409
+ {
410
+ type: "button",
411
+ className: classes,
412
+ onClick: () => window.open(href, target || "_self"),
413
+ disabled: linkButtonDisabled,
414
+ ...linkButtonRest,
415
+ children: content
416
+ }
417
+ );
418
+ }
419
+ const buttonProps = rest;
420
+ const disabled = showLoading || Boolean(buttonProps.disabled);
421
+ const { disabled: _, ...buttonPropsWithoutDisabled } = buttonProps;
422
+ return /* @__PURE__ */ jsx("button", { className: classes, ...buttonPropsWithoutDisabled, disabled, children: content });
423
+ }
424
+ var baseStyles3 = `
425
+ border border-edge-primary
426
+ rounded-md
427
+ overflow-hidden
428
+ `;
429
+ var variantStyles4 = {
430
+ default: `
431
+ bg-surface-primary text-content-primary
432
+ `,
433
+ dark: `
434
+ bg-surface-secondary text-content-inverted
435
+ `,
436
+ raised: `
437
+ bg-surface-primary text-content-primary
438
+ shadow-card
439
+ `
440
+ };
441
+ function Card({
442
+ variant = "default",
443
+ children,
444
+ className = "",
445
+ noPadding = false
446
+ }) {
447
+ const classes = [
448
+ baseStyles3,
449
+ variantStyles4[variant],
450
+ noPadding ? "" : "p-4",
451
+ className
452
+ ].join(" ").replace(/\s+/g, " ").trim();
453
+ return /* @__PURE__ */ jsx("div", { className: classes, children });
454
+ }
455
+ function CardHeader({ children, className = "" }) {
456
+ return /* @__PURE__ */ jsx("div", { className: `px-4 py-3 border-b border-edge-primary ${className}`, children });
457
+ }
458
+ function CardBody({ children, className = "" }) {
459
+ return /* @__PURE__ */ jsx("div", { className: `p-4 ${className}`, children });
460
+ }
461
+ function CardFooter({ children, className = "" }) {
462
+ return /* @__PURE__ */ jsx("div", { className: `px-4 py-3 border-t border-edge-primary ${className}`, children });
463
+ }
464
+ function CheckmarkIcon({ className = "" }) {
465
+ return /* @__PURE__ */ jsx(
466
+ "svg",
467
+ {
468
+ width: "14",
469
+ height: "14",
470
+ viewBox: "0 0 16 16",
471
+ fill: "none",
472
+ xmlns: "http://www.w3.org/2000/svg",
473
+ className,
474
+ children: /* @__PURE__ */ jsx(
475
+ "path",
476
+ {
477
+ d: "M13.5 4.5L6 12L2.5 8.5",
478
+ stroke: "currentColor",
479
+ strokeWidth: "2",
480
+ strokeLinecap: "round",
481
+ strokeLinejoin: "round"
482
+ }
483
+ )
484
+ }
485
+ );
486
+ }
487
+ var Checkbox = forwardRef(function Checkbox2({ label, className = "", disabled, ...props }, ref) {
488
+ return /* @__PURE__ */ jsxs(
489
+ "label",
490
+ {
491
+ className: `
492
+ inline-flex items-center gap-2 cursor-pointer
493
+ ${disabled ? "opacity-50 cursor-not-allowed" : ""}
494
+ ${className}
495
+ `,
496
+ children: [
497
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
498
+ /* @__PURE__ */ jsx(
499
+ "input",
500
+ {
501
+ ref,
502
+ type: "checkbox",
503
+ disabled,
504
+ className: "peer sr-only",
505
+ ...props
506
+ }
507
+ ),
508
+ /* @__PURE__ */ jsx(
509
+ "div",
510
+ {
511
+ className: `
512
+ w-5 h-5
513
+ bg-surface-primary
514
+ border border-edge-primary
515
+ rounded-xs
516
+ peer-checked:bg-action-primary
517
+ peer-focus:ring-2 peer-focus:ring-edge-focus peer-focus:ring-offset-1
518
+ flex items-center justify-center
519
+ `
520
+ }
521
+ ),
522
+ /* @__PURE__ */ jsx("div", { className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 opacity-0 peer-checked:opacity-100 transition-opacity pointer-events-none", children: /* @__PURE__ */ jsx(CheckmarkIcon, { className: "text-content-primary" }) })
523
+ ] }),
524
+ label && /* @__PURE__ */ jsx("span", { className: "font-mondwest text-base text-content-primary select-none", children: label })
525
+ ]
526
+ }
527
+ );
528
+ });
529
+ var Radio = forwardRef(function Radio2({ label, className = "", disabled, ...props }, ref) {
530
+ return /* @__PURE__ */ jsxs(
531
+ "label",
532
+ {
533
+ className: `
534
+ inline-flex items-center gap-2 cursor-pointer
535
+ ${disabled ? "opacity-50 cursor-not-allowed" : ""}
536
+ ${className}
537
+ `,
538
+ children: [
539
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
540
+ /* @__PURE__ */ jsx(
541
+ "input",
542
+ {
543
+ ref,
544
+ type: "radio",
545
+ disabled,
546
+ className: "peer sr-only",
547
+ ...props
548
+ }
549
+ ),
550
+ /* @__PURE__ */ jsx(
551
+ "div",
552
+ {
553
+ className: `
554
+ w-5 h-5
555
+ bg-surface-primary
556
+ border border-edge-primary
557
+ rounded-full
558
+ peer-checked:bg-action-primary
559
+ peer-focus:ring-2 peer-focus:ring-edge-focus peer-focus:ring-offset-1
560
+ flex items-center justify-center
561
+ `
562
+ }
563
+ ),
564
+ /* @__PURE__ */ jsx(
565
+ "div",
566
+ {
567
+ className: "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-2 h-2 bg-content-primary rounded-full opacity-0 peer-checked:opacity-100 pointer-events-none"
568
+ }
569
+ )
570
+ ] }),
571
+ label && /* @__PURE__ */ jsx("span", { className: "font-mondwest text-base text-content-primary select-none", children: label })
572
+ ]
573
+ }
574
+ );
575
+ });
576
+ var ContextMenuContext = createContext(null);
577
+ function useContextMenu() {
578
+ const context = useContext(ContextMenuContext);
579
+ if (!context) {
580
+ throw new Error("ContextMenu components must be used within a ContextMenu provider");
581
+ }
582
+ return context;
583
+ }
584
+ function ContextMenu({ children, className = "" }) {
585
+ const [isOpen, setIsOpen] = useState(false);
586
+ const [position, setPosition] = useState({ x: 0, y: 0 });
587
+ const containerRef = useRef(null);
588
+ const open = (pos) => {
589
+ setPosition(pos);
590
+ setIsOpen(true);
591
+ };
592
+ const close = () => {
593
+ setIsOpen(false);
594
+ };
595
+ const handleContextMenu = (e) => {
596
+ e.preventDefault();
597
+ open({ x: e.clientX, y: e.clientY });
598
+ };
599
+ useEffect(() => {
600
+ const handleClickOutside = (e) => {
601
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
602
+ close();
603
+ }
604
+ };
605
+ const handleEscape = (e) => {
606
+ if (e.key === "Escape") close();
607
+ };
608
+ if (isOpen) {
609
+ document.addEventListener("mousedown", handleClickOutside);
610
+ document.addEventListener("keydown", handleEscape);
611
+ }
612
+ return () => {
613
+ document.removeEventListener("mousedown", handleClickOutside);
614
+ document.removeEventListener("keydown", handleEscape);
615
+ };
616
+ }, [isOpen]);
617
+ return /* @__PURE__ */ jsx(ContextMenuContext.Provider, { value: { isOpen, position, open, close }, children: /* @__PURE__ */ jsx(
618
+ "div",
619
+ {
620
+ ref: containerRef,
621
+ onContextMenu: handleContextMenu,
622
+ className,
623
+ children
624
+ }
625
+ ) });
626
+ }
627
+ function ContextMenuContent({ children, className = "" }) {
628
+ const { isOpen, position, close } = useContextMenu();
629
+ if (!isOpen) return null;
630
+ return /* @__PURE__ */ jsx(
631
+ "div",
632
+ {
633
+ className: `
634
+ fixed z-[1000]
635
+ min-w-[160px]
636
+ bg-surface-primary
637
+ border border-edge-primary
638
+ rounded-sm
639
+ shadow-[2px_2px_0_0_var(--color-edge-primary)]
640
+ py-1
641
+ ${className}
642
+ `,
643
+ style: {
644
+ left: position.x,
645
+ top: position.y
646
+ },
647
+ onClick: close,
648
+ children
649
+ }
650
+ );
651
+ }
652
+ function ContextMenuItem({
653
+ onClick,
654
+ disabled = false,
655
+ destructive = false,
656
+ icon,
657
+ children,
658
+ className = ""
659
+ }) {
660
+ const { close } = useContextMenu();
661
+ const handleClick = () => {
662
+ if (!disabled && onClick) {
663
+ onClick();
664
+ close();
665
+ }
666
+ };
667
+ return /* @__PURE__ */ jsxs(
668
+ "button",
669
+ {
670
+ type: "button",
671
+ onClick: handleClick,
672
+ disabled,
673
+ className: `
674
+ w-full flex items-center gap-2
675
+ px-3 py-1.5
676
+ font-mondwest text-base text-left
677
+ ${destructive ? "text-status-error" : "text-content-primary"}
678
+ ${disabled ? "opacity-50 cursor-not-allowed" : "hover:bg-action-primary cursor-pointer"}
679
+ ${className}
680
+ `,
681
+ children: [
682
+ icon && /* @__PURE__ */ jsx("span", { className: "w-4 h-4 flex items-center justify-center", children: icon }),
683
+ /* @__PURE__ */ jsx("span", { children })
684
+ ]
685
+ }
686
+ );
687
+ }
688
+ function ContextMenuSeparator({ className = "" }) {
689
+ return /* @__PURE__ */ jsx(
690
+ "div",
691
+ {
692
+ className: `my-1 border-t border-edge-primary/20 ${className}`
693
+ }
694
+ );
695
+ }
696
+ function Divider({
697
+ orientation = "horizontal",
698
+ variant = "solid",
699
+ className = ""
700
+ }) {
701
+ if (variant === "decorated") {
702
+ return /* @__PURE__ */ jsxs("div", { className: `flex items-center gap-4 ${className}`, children: [
703
+ /* @__PURE__ */ jsx("div", { className: "flex-1 h-[2px] bg-edge-primary/20" }),
704
+ /* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-action-primary border border-edge-primary rotate-45" }),
705
+ /* @__PURE__ */ jsx("div", { className: "flex-1 h-[2px] bg-edge-primary/20" })
706
+ ] });
707
+ }
708
+ if (orientation === "horizontal") {
709
+ const borderStyle2 = variant === "dashed" ? "border-dashed" : "border-solid";
710
+ return /* @__PURE__ */ jsx(
711
+ "div",
712
+ {
713
+ className: `w-full border-t border-edge-primary/20 ${borderStyle2} ${className}`,
714
+ role: "separator",
715
+ "aria-orientation": "horizontal"
716
+ }
717
+ );
718
+ }
719
+ const borderStyle = variant === "dashed" ? "border-dashed" : "border-solid";
720
+ return /* @__PURE__ */ jsx(
721
+ "div",
722
+ {
723
+ className: `h-full border-l border-edge-primary/20 ${borderStyle} ${className}`,
724
+ role: "separator",
725
+ "aria-orientation": "vertical"
726
+ }
727
+ );
728
+ }
729
+ var DropdownContext = createContext(null);
730
+ function useDropdownContext() {
731
+ const context = useContext(DropdownContext);
732
+ if (!context) {
733
+ throw new Error("DropdownMenu components must be used within a DropdownMenu");
734
+ }
735
+ return context;
736
+ }
737
+ function DropdownMenu({
738
+ open: controlledOpen,
739
+ defaultOpen = false,
740
+ onOpenChange,
741
+ position = "bottom-start",
742
+ children
743
+ }) {
744
+ const [internalOpen, setInternalOpen] = useState(defaultOpen);
745
+ const isControlled = controlledOpen !== void 0;
746
+ const open = isControlled ? controlledOpen : internalOpen;
747
+ const triggerRef = useRef(null);
748
+ const setOpen = useCallback((newOpen) => {
749
+ if (!isControlled) {
750
+ setInternalOpen(newOpen);
751
+ }
752
+ onOpenChange?.(newOpen);
753
+ }, [isControlled, onOpenChange]);
754
+ return /* @__PURE__ */ jsx(DropdownContext.Provider, { value: { open, setOpen, triggerRef, position }, children: /* @__PURE__ */ jsx("div", { className: "relative inline-block", children }) });
755
+ }
756
+ function DropdownMenuTrigger({ children, asChild }) {
757
+ const { open, setOpen, triggerRef } = useDropdownContext();
758
+ const handleClick = () => {
759
+ setOpen(!open);
760
+ };
761
+ if (asChild && React14.isValidElement(children)) {
762
+ return React14.cloneElement(children, {
763
+ onClick: handleClick,
764
+ ref: triggerRef
765
+ });
766
+ }
767
+ return /* @__PURE__ */ jsx(
768
+ "button",
769
+ {
770
+ type: "button",
771
+ ref: triggerRef,
772
+ onClick: handleClick,
773
+ children
774
+ }
775
+ );
776
+ }
777
+ function DropdownMenuContent({ className = "", children }) {
778
+ const { open, setOpen, triggerRef, position } = useDropdownContext();
779
+ const contentRef = useRef(null);
780
+ const [mounted, setMounted] = useState(false);
781
+ const [coords, setCoords] = useState({ top: 0, left: 0 });
782
+ useEffect(() => {
783
+ setMounted(true);
784
+ }, []);
785
+ useEffect(() => {
786
+ if (!open || !triggerRef.current || !contentRef.current) return;
787
+ const trigger = triggerRef.current.getBoundingClientRect();
788
+ const content = contentRef.current.getBoundingClientRect();
789
+ const gap = 4;
790
+ let top = 0;
791
+ let left = 0;
792
+ switch (position) {
793
+ case "bottom-start":
794
+ top = trigger.bottom + gap;
795
+ left = trigger.left;
796
+ break;
797
+ case "bottom-end":
798
+ top = trigger.bottom + gap;
799
+ left = trigger.right - content.width;
800
+ break;
801
+ case "top-start":
802
+ top = trigger.top - content.height - gap;
803
+ left = trigger.left;
804
+ break;
805
+ case "top-end":
806
+ top = trigger.top - content.height - gap;
807
+ left = trigger.right - content.width;
808
+ break;
809
+ }
810
+ top = Math.max(8, Math.min(top, window.innerHeight - content.height - 8));
811
+ left = Math.max(8, Math.min(left, window.innerWidth - content.width - 8));
812
+ setCoords({ top, left });
813
+ }, [open, position, triggerRef]);
814
+ useClickOutside(open, [contentRef, triggerRef], () => setOpen(false));
815
+ useEscapeKey(open, () => setOpen(false));
816
+ if (!mounted || !open) return null;
817
+ return createPortal(
818
+ /* @__PURE__ */ jsx(
819
+ "div",
820
+ {
821
+ ref: contentRef,
822
+ role: "menu",
823
+ className: `
824
+ fixed z-50
825
+ min-w-[8rem]
826
+ bg-surface-primary
827
+ border-2 border-edge-primary
828
+ rounded-sm
829
+ shadow-[2px_2px_0_0_var(--color-edge-primary)]
830
+ py-1
831
+ animate-fadeIn
832
+ ${className}
833
+ `.trim(),
834
+ style: { top: coords.top, left: coords.left },
835
+ children
836
+ }
837
+ ),
838
+ document.body
839
+ );
840
+ }
841
+ function DropdownMenuItem({
842
+ children,
843
+ onClick,
844
+ disabled = false,
845
+ destructive = false,
846
+ className = ""
847
+ }) {
848
+ const { setOpen } = useDropdownContext();
849
+ const handleClick = () => {
850
+ if (disabled) return;
851
+ onClick?.();
852
+ setOpen(false);
853
+ };
854
+ return /* @__PURE__ */ jsx(
855
+ "button",
856
+ {
857
+ type: "button",
858
+ role: "menuitem",
859
+ onClick: handleClick,
860
+ disabled,
861
+ className: `
862
+ w-full px-4 py-2
863
+ text-left
864
+ font-mondwest text-base
865
+ ${destructive ? "text-status-error" : "text-content-primary"}
866
+ ${disabled ? "opacity-50 cursor-not-allowed" : "hover:bg-content-primary/5 cursor-pointer"}
867
+ transition-colors
868
+ ${className}
869
+ `.trim(),
870
+ children
871
+ }
872
+ );
873
+ }
874
+ function DropdownMenuSeparator({ className = "" }) {
875
+ return /* @__PURE__ */ jsx(
876
+ "div",
877
+ {
878
+ role: "separator",
879
+ className: `h-px bg-edge-primary/20 my-1 ${className}`.trim()
880
+ }
881
+ );
882
+ }
883
+ function DropdownMenuLabel({ children, className = "" }) {
884
+ return /* @__PURE__ */ jsx(
885
+ "div",
886
+ {
887
+ className: `
888
+ px-4 py-1
889
+ font-joystix text-2xs uppercase
890
+ text-content-primary/50
891
+ ${className}
892
+ `.trim(),
893
+ children
894
+ }
895
+ );
896
+ }
897
+ var baseStyles4 = `
898
+ font-sans
899
+ bg-surface-primary text-content-primary
900
+ border border-edge-primary
901
+ rounded-sm
902
+ placeholder:text-content-muted
903
+ focus:outline-none
904
+ focus:ring-2 focus:ring-edge-focus focus:ring-offset-0
905
+ disabled:opacity-50 disabled:cursor-not-allowed
906
+ `;
907
+ var sizeStyles3 = {
908
+ sm: "h-8 px-2 text-sm",
909
+ md: "h-10 px-3 text-base",
910
+ lg: "h-12 px-4 text-base"
911
+ };
912
+ var errorStyles = `
913
+ border-status-error
914
+ focus:ring-status-error
915
+ `;
916
+ var Input = forwardRef(function Input2({
917
+ size = "md",
918
+ error = false,
919
+ fullWidth = false,
920
+ iconName,
921
+ className = "",
922
+ ...props
923
+ }, ref) {
924
+ const paddingLeft = iconName ? size === "sm" ? "pl-8" : size === "lg" ? "pl-12" : "pl-10" : "";
925
+ const classes = [
926
+ baseStyles4,
927
+ sizeStyles3[size],
928
+ error ? errorStyles : "",
929
+ fullWidth ? "w-full" : "",
930
+ paddingLeft,
931
+ className
932
+ ].join(" ").replace(/\s+/g, " ").trim();
933
+ const input = /* @__PURE__ */ jsx("input", { ref, className: classes, ...props });
934
+ if (iconName) {
935
+ return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
936
+ /* @__PURE__ */ jsx("div", { className: "absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none", children: /* @__PURE__ */ jsx(
937
+ "div",
938
+ {
939
+ className: "text-content-muted",
940
+ "data-icon-slot": iconName,
941
+ style: {
942
+ width: size === "sm" ? 14 : size === "lg" ? 18 : 20,
943
+ height: size === "sm" ? 14 : size === "lg" ? 18 : 20
944
+ }
945
+ }
946
+ ) }),
947
+ input
948
+ ] });
949
+ }
950
+ return input;
951
+ });
952
+ var TextArea = forwardRef(function TextArea2({
953
+ error = false,
954
+ fullWidth = false,
955
+ className = "",
956
+ ...props
957
+ }, ref) {
958
+ const classes = [
959
+ baseStyles4,
960
+ "px-3 py-2 text-base",
961
+ "resize-y min-h-24",
962
+ error ? errorStyles : "",
963
+ fullWidth ? "w-full" : "",
964
+ className
965
+ ].join(" ").replace(/\s+/g, " ").trim();
966
+ return /* @__PURE__ */ jsx("textarea", { ref, className: classes, ...props });
967
+ });
968
+ function Label({ children, required, className = "", ...props }) {
969
+ return /* @__PURE__ */ jsxs(
970
+ "label",
971
+ {
972
+ className,
973
+ ...props,
974
+ children: [
975
+ children,
976
+ required && /* @__PURE__ */ jsx("span", { className: "text-status-error ml-1", children: "*" })
977
+ ]
978
+ }
979
+ );
980
+ }
981
+ var sizeStyles4 = {
982
+ sm: "h-2",
983
+ md: "h-4",
984
+ lg: "h-6"
985
+ };
986
+ var variantStyles5 = {
987
+ default: "bg-action-primary",
988
+ success: "bg-status-success",
989
+ warning: "bg-surface-tertiary",
990
+ error: "bg-status-error"
991
+ };
992
+ function Progress({
993
+ value,
994
+ max = 100,
995
+ variant = "default",
996
+ size = "md",
997
+ showLabel = false,
998
+ className = ""
999
+ }) {
1000
+ const percentage = Math.min(100, Math.max(0, value / max * 100));
1001
+ return /* @__PURE__ */ jsxs("div", { className: `w-full ${className}`, children: [
1002
+ /* @__PURE__ */ jsx(
1003
+ "div",
1004
+ {
1005
+ className: `
1006
+ w-full
1007
+ bg-surface-primary
1008
+ border border-edge-primary
1009
+ rounded-sm
1010
+ overflow-hidden
1011
+ ${sizeStyles4[size]}
1012
+ `,
1013
+ role: "progressbar",
1014
+ "aria-valuenow": value,
1015
+ "aria-valuemin": 0,
1016
+ "aria-valuemax": max,
1017
+ children: /* @__PURE__ */ jsx(
1018
+ "div",
1019
+ {
1020
+ className: `
1021
+ h-full
1022
+ ${variantStyles5[variant]}
1023
+ `,
1024
+ style: { width: `${percentage}%` }
1025
+ }
1026
+ )
1027
+ }
1028
+ ),
1029
+ showLabel && /* @__PURE__ */ jsxs("div", { className: "mt-1 font-joystix text-2xs text-content-primary text-right", children: [
1030
+ Math.round(percentage),
1031
+ "%"
1032
+ ] })
1033
+ ] });
1034
+ }
1035
+ var LOADER_FRAMES = ["\uEE06", "\uEE07", "\uEE08", "\uEE09", "\uEE0A", "\uEE0B"];
1036
+ function Spinner({ size = 24, className = "", completed = false }) {
1037
+ const [frameIndex, setFrameIndex] = React14.useState(0);
1038
+ React14.useEffect(() => {
1039
+ if (completed) {
1040
+ setFrameIndex(0);
1041
+ return;
1042
+ }
1043
+ const interval = setInterval(() => {
1044
+ setFrameIndex((prev) => (prev + 1) % LOADER_FRAMES.length);
1045
+ }, 150);
1046
+ return () => clearInterval(interval);
1047
+ }, [completed]);
1048
+ const fontSize = size;
1049
+ const displayChar = completed ? "\u2713" : LOADER_FRAMES[frameIndex];
1050
+ return /* @__PURE__ */ jsx(
1051
+ "div",
1052
+ {
1053
+ className: `inline-block flex items-center justify-center ${className}`,
1054
+ style: {
1055
+ width: size,
1056
+ height: size,
1057
+ fontSize,
1058
+ fontFamily: "PixelCode, monospace",
1059
+ lineHeight: 1
1060
+ },
1061
+ "aria-label": completed ? "Completed" : "Loading",
1062
+ role: "status",
1063
+ children: displayChar
1064
+ }
1065
+ );
1066
+ }
1067
+ function Select({
1068
+ options,
1069
+ value,
1070
+ placeholder = "Select...",
1071
+ onChange,
1072
+ disabled = false,
1073
+ error = false,
1074
+ fullWidth = false,
1075
+ className = ""
1076
+ }) {
1077
+ const [isOpen, setIsOpen] = useState(false);
1078
+ const containerRef = useRef(null);
1079
+ useEffect(() => {
1080
+ function handleClickOutside(event) {
1081
+ if (containerRef.current && !containerRef.current.contains(event.target)) {
1082
+ setIsOpen(false);
1083
+ }
1084
+ }
1085
+ document.addEventListener("mousedown", handleClickOutside);
1086
+ return () => document.removeEventListener("mousedown", handleClickOutside);
1087
+ }, []);
1088
+ const selectedOption = options.find((opt) => opt.value === value);
1089
+ const handleSelect = (optionValue) => {
1090
+ onChange?.(optionValue);
1091
+ setIsOpen(false);
1092
+ };
1093
+ return /* @__PURE__ */ jsxs(
1094
+ "div",
1095
+ {
1096
+ ref: containerRef,
1097
+ className: `relative ${fullWidth ? "w-full" : "w-fit"} ${className}`,
1098
+ children: [
1099
+ /* @__PURE__ */ jsxs(
1100
+ "button",
1101
+ {
1102
+ type: "button",
1103
+ onClick: () => !disabled && setIsOpen(!isOpen),
1104
+ disabled,
1105
+ className: `
1106
+ flex items-center justify-between gap-2
1107
+ w-full h-10 px-3
1108
+ font-mondwest text-base
1109
+ bg-surface-primary text-content-primary
1110
+ border rounded-sm
1111
+ ${error ? "border-status-error" : "border-edge-primary"}
1112
+ ${disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}
1113
+ ${isOpen ? "shadow-[0_3px_0_0_var(--color-edge-primary)] -translate-y-0.5" : "shadow-[0_1px_0_0_var(--color-edge-primary)]"}
1114
+ `,
1115
+ children: [
1116
+ /* @__PURE__ */ jsx("span", { className: selectedOption ? "text-content-primary" : "text-content-primary/40", children: selectedOption?.label || placeholder }),
1117
+ /* @__PURE__ */ jsx("span", { className: `text-content-primary ${isOpen ? "rotate-180" : ""}`, children: "\u25BC" })
1118
+ ]
1119
+ }
1120
+ ),
1121
+ isOpen && /* @__PURE__ */ jsx(
1122
+ "div",
1123
+ {
1124
+ className: `
1125
+ absolute z-50 top-full left-0 right-0 mt-1
1126
+ bg-surface-primary
1127
+ border border-edge-primary
1128
+ rounded-sm
1129
+ shadow-[2px_2px_0_0_var(--color-edge-primary)]
1130
+ overflow-hidden
1131
+ `,
1132
+ children: options.map((option) => /* @__PURE__ */ jsx(
1133
+ "button",
1134
+ {
1135
+ type: "button",
1136
+ onClick: () => !option.disabled && handleSelect(option.value),
1137
+ disabled: option.disabled,
1138
+ className: `
1139
+ w-full px-3 py-2
1140
+ font-mondwest text-base text-left
1141
+ ${option.value === value ? "bg-action-primary text-content-primary" : "text-content-primary"}
1142
+ ${option.disabled ? "opacity-50 cursor-not-allowed" : "hover:bg-action-primary cursor-pointer"}
1143
+ `,
1144
+ children: option.label
1145
+ },
1146
+ option.value
1147
+ ))
1148
+ }
1149
+ )
1150
+ ]
1151
+ }
1152
+ );
1153
+ }
1154
+ var sizeStyles5 = {
1155
+ sm: {
1156
+ track: "h-1",
1157
+ thumb: "w-3 h-3"
1158
+ },
1159
+ md: {
1160
+ track: "h-2",
1161
+ thumb: "w-4 h-4"
1162
+ },
1163
+ lg: {
1164
+ track: "h-3",
1165
+ thumb: "w-5 h-5"
1166
+ }
1167
+ };
1168
+ function Slider({
1169
+ value,
1170
+ onChange,
1171
+ min = 0,
1172
+ max = 100,
1173
+ step = 1,
1174
+ size = "md",
1175
+ disabled = false,
1176
+ showValue = false,
1177
+ label,
1178
+ className = ""
1179
+ }) {
1180
+ const trackRef = useRef(null);
1181
+ const [isDragging, setIsDragging] = useState(false);
1182
+ const styles = sizeStyles5[size];
1183
+ const percentage = (value - min) / (max - min) * 100;
1184
+ const snapToStep = useCallback((val) => {
1185
+ const stepped = Math.round((val - min) / step) * step + min;
1186
+ return Math.max(min, Math.min(max, stepped));
1187
+ }, [min, max, step]);
1188
+ const getValueFromPosition = useCallback((clientX) => {
1189
+ if (!trackRef.current) return value;
1190
+ const rect = trackRef.current.getBoundingClientRect();
1191
+ const percent = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
1192
+ const newValue = min + percent * (max - min);
1193
+ return snapToStep(newValue);
1194
+ }, [min, max, value, snapToStep]);
1195
+ const handlePointerDown = useCallback((e) => {
1196
+ if (disabled) return;
1197
+ e.preventDefault();
1198
+ setIsDragging(true);
1199
+ const newValue = getValueFromPosition(e.clientX);
1200
+ onChange(newValue);
1201
+ }, [disabled, getValueFromPosition, onChange]);
1202
+ useEffect(() => {
1203
+ if (!isDragging) return;
1204
+ const handlePointerMove = (e) => {
1205
+ const newValue = getValueFromPosition(e.clientX);
1206
+ onChange(newValue);
1207
+ };
1208
+ const handlePointerUp = () => {
1209
+ setIsDragging(false);
1210
+ };
1211
+ document.addEventListener("pointermove", handlePointerMove);
1212
+ document.addEventListener("pointerup", handlePointerUp);
1213
+ return () => {
1214
+ document.removeEventListener("pointermove", handlePointerMove);
1215
+ document.removeEventListener("pointerup", handlePointerUp);
1216
+ };
1217
+ }, [isDragging, getValueFromPosition, onChange]);
1218
+ const handleKeyDown = (e) => {
1219
+ if (disabled) return;
1220
+ let newValue = value;
1221
+ switch (e.key) {
1222
+ case "ArrowRight":
1223
+ case "ArrowUp":
1224
+ newValue = Math.min(max, value + step);
1225
+ break;
1226
+ case "ArrowLeft":
1227
+ case "ArrowDown":
1228
+ newValue = Math.max(min, value - step);
1229
+ break;
1230
+ case "Home":
1231
+ newValue = min;
1232
+ break;
1233
+ case "End":
1234
+ newValue = max;
1235
+ break;
1236
+ default:
1237
+ return;
1238
+ }
1239
+ e.preventDefault();
1240
+ onChange(newValue);
1241
+ };
1242
+ return /* @__PURE__ */ jsxs("div", { className: `space-y-2 ${className}`.trim(), children: [
1243
+ (label || showValue) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
1244
+ label && /* @__PURE__ */ jsx("span", { className: "font-mondwest text-base text-content-primary", children: label }),
1245
+ showValue && /* @__PURE__ */ jsx("span", { className: "font-mondwest text-sm text-content-primary/60", children: value })
1246
+ ] }),
1247
+ /* @__PURE__ */ jsxs(
1248
+ "div",
1249
+ {
1250
+ ref: trackRef,
1251
+ role: "slider",
1252
+ tabIndex: disabled ? -1 : 0,
1253
+ "aria-valuemin": min,
1254
+ "aria-valuemax": max,
1255
+ "aria-valuenow": value,
1256
+ "aria-disabled": disabled,
1257
+ onPointerDown: handlePointerDown,
1258
+ onKeyDown: handleKeyDown,
1259
+ className: `
1260
+ relative w-full
1261
+ flex items-center
1262
+ ${styles.track}
1263
+ bg-edge-primary/10
1264
+ border border-edge-primary
1265
+ rounded-sm
1266
+ ${disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}
1267
+ focus:outline-none focus:ring-2 focus:ring-edge-focus focus:ring-offset-2
1268
+ `.trim(),
1269
+ children: [
1270
+ /* @__PURE__ */ jsx(
1271
+ "div",
1272
+ {
1273
+ className: `
1274
+ absolute top-0 left-0 h-full
1275
+ bg-action-primary
1276
+ rounded-sm
1277
+ pointer-events-none
1278
+ `.trim(),
1279
+ style: { width: `${percentage}%` }
1280
+ }
1281
+ ),
1282
+ /* @__PURE__ */ jsx(
1283
+ "div",
1284
+ {
1285
+ className: "absolute top-0 bottom-0 flex items-center pointer-events-none",
1286
+ style: { left: `calc(${percentage}% - ${parseInt(styles.thumb.split(" ")[0].replace("w-", "")) * 2}px)` },
1287
+ children: /* @__PURE__ */ jsx(
1288
+ "div",
1289
+ {
1290
+ className: `
1291
+ ${styles.thumb}
1292
+ bg-surface-muted
1293
+ border border-edge-primary
1294
+ rounded
1295
+ ${isDragging ? "scale-110" : ""}
1296
+ transition-transform
1297
+ pointer-events-auto
1298
+ `.trim()
1299
+ }
1300
+ )
1301
+ }
1302
+ )
1303
+ ]
1304
+ }
1305
+ )
1306
+ ] });
1307
+ }
1308
+ var sizeStyles6 = {
1309
+ sm: {
1310
+ track: "w-8 h-4",
1311
+ thumb: "w-3 h-3",
1312
+ translate: "translate-x-4"
1313
+ },
1314
+ md: {
1315
+ track: "w-10 h-5",
1316
+ thumb: "w-4 h-4",
1317
+ translate: "translate-x-5"
1318
+ },
1319
+ lg: {
1320
+ track: "w-12 h-6",
1321
+ thumb: "w-5 h-5",
1322
+ translate: "translate-x-6"
1323
+ }
1324
+ };
1325
+ function Switch({
1326
+ checked,
1327
+ onChange,
1328
+ size = "md",
1329
+ disabled = false,
1330
+ label,
1331
+ labelPosition = "right",
1332
+ className = "",
1333
+ id
1334
+ }) {
1335
+ const styles = sizeStyles6[size];
1336
+ const switchId = id || `switch-${Math.random().toString(36).slice(2)}`;
1337
+ const handleClick = () => {
1338
+ if (!disabled) {
1339
+ onChange(!checked);
1340
+ }
1341
+ };
1342
+ const handleKeyDown = (e) => {
1343
+ if (e.key === " " || e.key === "Enter") {
1344
+ e.preventDefault();
1345
+ handleClick();
1346
+ }
1347
+ };
1348
+ const switchElement = /* @__PURE__ */ jsx(
1349
+ "button",
1350
+ {
1351
+ type: "button",
1352
+ role: "switch",
1353
+ id: switchId,
1354
+ "aria-checked": checked,
1355
+ disabled,
1356
+ onClick: handleClick,
1357
+ onKeyDown: handleKeyDown,
1358
+ className: `
1359
+ relative inline-flex items-center
1360
+ ${styles.track}
1361
+ rounded-full
1362
+ border border-edge-primary
1363
+ transition-colors
1364
+ ${checked ? "bg-action-primary" : "bg-edge-primary/10"}
1365
+ ${disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}
1366
+ focus:outline-none focus:ring-2 focus:ring-edge-focus focus:ring-offset-2
1367
+ `.trim(),
1368
+ children: /* @__PURE__ */ jsx(
1369
+ "span",
1370
+ {
1371
+ className: `
1372
+ ${styles.thumb}
1373
+ rounded-full
1374
+ bg-surface-secondary
1375
+ border border-edge-primary
1376
+ transform transition-transform
1377
+ ${checked ? styles.translate : "translate-x-0.5"}
1378
+ `.trim(),
1379
+ "aria-hidden": "true"
1380
+ }
1381
+ )
1382
+ }
1383
+ );
1384
+ if (!label) {
1385
+ return /* @__PURE__ */ jsx("div", { className, children: switchElement });
1386
+ }
1387
+ return /* @__PURE__ */ jsxs("div", { className: `inline-flex items-center gap-2 ${className}`.trim(), children: [
1388
+ labelPosition === "left" && /* @__PURE__ */ jsx(
1389
+ "label",
1390
+ {
1391
+ htmlFor: switchId,
1392
+ className: `
1393
+ font-mondwest text-base text-content-primary
1394
+ ${disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}
1395
+ `.trim(),
1396
+ children: label
1397
+ }
1398
+ ),
1399
+ switchElement,
1400
+ labelPosition === "right" && /* @__PURE__ */ jsx(
1401
+ "label",
1402
+ {
1403
+ htmlFor: switchId,
1404
+ className: `
1405
+ font-mondwest text-base text-content-primary
1406
+ ${disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}
1407
+ `.trim(),
1408
+ children: label
1409
+ }
1410
+ )
1411
+ ] });
1412
+ }
1413
+ var TabsContext = createContext(null);
1414
+ function useTabsContext() {
1415
+ const context = useContext(TabsContext);
1416
+ if (!context) {
1417
+ throw new Error("Tab components must be used within a Tabs provider");
1418
+ }
1419
+ return context;
1420
+ }
1421
+ var triggerBaseStyles = `
1422
+ flex items-center justify-center gap-2
1423
+ px-4 py-2
1424
+ font-joystix text-xs uppercase
1425
+ cursor-pointer select-none
1426
+ text-content-primary
1427
+ transition-all duration-200 ease-out
1428
+ relative
1429
+ border border-edge-primary
1430
+ rounded-sm
1431
+ flex-1
1432
+ shadow-none
1433
+ `;
1434
+ var pillStyles = {
1435
+ inactive: `
1436
+ bg-transparent text-content-primary
1437
+ hover:bg-surface-secondary/5
1438
+ hover:translate-y-0
1439
+ hover:shadow-none
1440
+ `,
1441
+ active: `
1442
+ bg-action-primary text-content-primary
1443
+ hover:bg-action-primary
1444
+ hover:translate-y-0
1445
+ hover:shadow-none
1446
+ `
1447
+ };
1448
+ var lineStyles = {
1449
+ inactive: `
1450
+ bg-transparent
1451
+ hover:bg-surface-primary/50
1452
+ `,
1453
+ active: `
1454
+ border-b-0
1455
+ bg-surface-primary
1456
+ border-t border-l border-r border-edge-primary
1457
+ rounded-t-md
1458
+ mb-0
1459
+ relative
1460
+ z-10
1461
+ `
1462
+ };
1463
+ function Tabs({
1464
+ defaultValue,
1465
+ value,
1466
+ onValueChange,
1467
+ variant = "pill",
1468
+ layout = "bottom-tabs",
1469
+ children,
1470
+ className = ""
1471
+ }) {
1472
+ const [internalValue, setInternalValue] = useState(defaultValue || "");
1473
+ const isControlled = value !== void 0;
1474
+ const activeTab = isControlled ? value : internalValue;
1475
+ const setActiveTab = (newValue) => {
1476
+ if (isControlled) {
1477
+ onValueChange?.(newValue);
1478
+ } else {
1479
+ setInternalValue(newValue);
1480
+ }
1481
+ };
1482
+ return /* @__PURE__ */ jsx(TabsContext.Provider, { value: { activeTab, setActiveTab, variant, layout }, children: /* @__PURE__ */ jsx("div", { className, children }) });
1483
+ }
1484
+ function TabList({ children, className = "" }) {
1485
+ const { layout } = useTabsContext();
1486
+ const shrinkClass = layout === "bottom-tabs" ? "shrink-0" : "";
1487
+ return /* @__PURE__ */ jsx("div", { className: `flex items-center justify-between gap-4 px-2 py-2 bg-surface-primary border-t border-edge-primary ${shrinkClass} ${className}`, children: /* @__PURE__ */ jsx("div", { className: "flex gap-2 items-center overflow-x-auto w-full", children }) });
1488
+ }
1489
+ function TabTrigger({
1490
+ value,
1491
+ children,
1492
+ icon,
1493
+ className = ""
1494
+ }) {
1495
+ const { activeTab, setActiveTab, variant } = useTabsContext();
1496
+ const isActive = activeTab === value;
1497
+ const variantStyle = variant === "pill" ? isActive ? pillStyles.active : pillStyles.inactive : isActive ? lineStyles.active : lineStyles.inactive;
1498
+ const classes = [
1499
+ triggerBaseStyles,
1500
+ variantStyle,
1501
+ className
1502
+ ].join(" ").replace(/\s+/g, " ").trim();
1503
+ return /* @__PURE__ */ jsxs(
1504
+ "button",
1505
+ {
1506
+ type: "button",
1507
+ role: "tab",
1508
+ "aria-selected": isActive,
1509
+ onClick: () => setActiveTab(value),
1510
+ className: classes,
1511
+ children: [
1512
+ icon,
1513
+ children
1514
+ ]
1515
+ }
1516
+ );
1517
+ }
1518
+ function TabContent({
1519
+ value,
1520
+ children,
1521
+ className = ""
1522
+ }) {
1523
+ const { activeTab, variant } = useTabsContext();
1524
+ if (activeTab !== value) {
1525
+ return null;
1526
+ }
1527
+ const contentClasses = variant === "line" ? `bg-surface-primary border-r border-edge-primary ${className}` : className;
1528
+ return /* @__PURE__ */ jsx(
1529
+ "div",
1530
+ {
1531
+ role: "tabpanel",
1532
+ className: contentClasses,
1533
+ style: { height: "auto" },
1534
+ children
1535
+ }
1536
+ );
1537
+ }
1538
+ var positionStyles = {
1539
+ top: "bottom-full left-1/2 -translate-x-1/2 mb-2",
1540
+ bottom: "top-full left-1/2 -translate-x-1/2 mt-2",
1541
+ left: "right-full top-1/2 -translate-y-1/2 mr-2",
1542
+ right: "left-full top-1/2 -translate-y-1/2 ml-2"
1543
+ };
1544
+ var arrowStyles = {
1545
+ top: "top-full left-1/2 -translate-x-1/2 border-l-transparent border-r-transparent border-b-transparent border-t-surface-secondary",
1546
+ bottom: "bottom-full left-1/2 -translate-x-1/2 border-l-transparent border-r-transparent border-t-transparent border-b-surface-secondary",
1547
+ left: "left-full top-1/2 -translate-y-1/2 border-t-transparent border-b-transparent border-r-transparent border-l-surface-secondary",
1548
+ right: "right-full top-1/2 -translate-y-1/2 border-t-transparent border-b-transparent border-l-transparent border-r-surface-secondary"
1549
+ };
1550
+ var sizeStyles7 = {
1551
+ sm: "text-xs",
1552
+ md: "text-xs",
1553
+ lg: "text-sm"
1554
+ };
1555
+ function Tooltip({
1556
+ content,
1557
+ position = "top",
1558
+ delay = 0,
1559
+ size = "md",
1560
+ children,
1561
+ className = ""
1562
+ }) {
1563
+ const [isVisible, setIsVisible] = useState(false);
1564
+ const timeoutRef = useRef(null);
1565
+ const showTooltip = () => {
1566
+ if (delay > 0) {
1567
+ timeoutRef.current = setTimeout(() => setIsVisible(true), delay);
1568
+ } else {
1569
+ setIsVisible(true);
1570
+ }
1571
+ };
1572
+ const hideTooltip = () => {
1573
+ if (timeoutRef.current) {
1574
+ clearTimeout(timeoutRef.current);
1575
+ }
1576
+ setIsVisible(false);
1577
+ };
1578
+ return /* @__PURE__ */ jsxs(
1579
+ "div",
1580
+ {
1581
+ className: `relative inline-flex ${className}`,
1582
+ onMouseEnter: showTooltip,
1583
+ onMouseLeave: hideTooltip,
1584
+ onFocus: showTooltip,
1585
+ onBlur: hideTooltip,
1586
+ children: [
1587
+ children,
1588
+ isVisible && /* @__PURE__ */ jsxs(
1589
+ "div",
1590
+ {
1591
+ className: `
1592
+ absolute z-[1000]
1593
+ px-2 py-1
1594
+ bg-surface-secondary text-content-inverted
1595
+ font-joystix uppercase
1596
+ rounded-sm
1597
+ whitespace-nowrap
1598
+ pointer-events-none
1599
+ ${sizeStyles7[size]}
1600
+ ${positionStyles[position]}
1601
+ `,
1602
+ role: "tooltip",
1603
+ children: [
1604
+ content,
1605
+ /* @__PURE__ */ jsx(
1606
+ "div",
1607
+ {
1608
+ className: `
1609
+ absolute
1610
+ border-4 border-solid
1611
+ ${arrowStyles[position]}
1612
+ `
1613
+ }
1614
+ )
1615
+ ]
1616
+ }
1617
+ )
1618
+ ]
1619
+ }
1620
+ );
1621
+ }
1622
+ var ToastContext = createContext(null);
1623
+ function useToast() {
1624
+ const context = useContext(ToastContext);
1625
+ if (!context) {
1626
+ throw new Error("useToast must be used within a ToastProvider");
1627
+ }
1628
+ return context;
1629
+ }
1630
+ function ToastProvider({
1631
+ children,
1632
+ defaultDuration = 5e3,
1633
+ renderIcon,
1634
+ renderCloseIcon
1635
+ }) {
1636
+ const [toasts, setToasts] = useState([]);
1637
+ const [mounted, setMounted] = useState(false);
1638
+ useEffect(() => {
1639
+ setMounted(true);
1640
+ }, []);
1641
+ const addToast = useCallback((toast) => {
1642
+ const id = `toast-${Date.now()}-${Math.random().toString(36).slice(2)}`;
1643
+ const duration = toast.duration ?? defaultDuration;
1644
+ setToasts((prev) => [...prev, { ...toast, id }]);
1645
+ if (duration > 0) {
1646
+ setTimeout(() => {
1647
+ setToasts((prev) => prev.filter((t) => t.id !== id));
1648
+ }, duration);
1649
+ }
1650
+ return id;
1651
+ }, [defaultDuration]);
1652
+ const removeToast = useCallback((id) => {
1653
+ setToasts((prev) => prev.filter((t) => t.id !== id));
1654
+ }, []);
1655
+ return /* @__PURE__ */ jsxs(ToastContext.Provider, { value: { toasts, addToast, removeToast }, children: [
1656
+ children,
1657
+ mounted && createPortal(
1658
+ /* @__PURE__ */ jsx(
1659
+ ToastViewport,
1660
+ {
1661
+ toasts,
1662
+ removeToast,
1663
+ renderIcon,
1664
+ renderCloseIcon
1665
+ }
1666
+ ),
1667
+ document.body
1668
+ )
1669
+ ] });
1670
+ }
1671
+ function ToastViewport({ toasts, removeToast, renderIcon, renderCloseIcon }) {
1672
+ if (toasts.length === 0) return null;
1673
+ return /* @__PURE__ */ jsx(
1674
+ "div",
1675
+ {
1676
+ className: "fixed bottom-4 right-4 z-[100] flex flex-col gap-2 max-w-sm w-full pointer-events-none",
1677
+ "aria-live": "polite",
1678
+ children: toasts.map((toast) => /* @__PURE__ */ jsx(
1679
+ Toast,
1680
+ {
1681
+ toast,
1682
+ onClose: () => removeToast(toast.id),
1683
+ renderIcon,
1684
+ renderCloseIcon
1685
+ },
1686
+ toast.id
1687
+ ))
1688
+ }
1689
+ );
1690
+ }
1691
+ var variantStyles6 = {
1692
+ default: "bg-surface-primary border-edge-primary",
1693
+ success: "bg-status-success border-status-success",
1694
+ warning: "bg-status-warning border-surface-tertiary",
1695
+ error: "bg-status-error border-status-error",
1696
+ info: "bg-status-info border-status-info"
1697
+ };
1698
+ function Toast({ toast, onClose, renderIcon, renderCloseIcon }) {
1699
+ const variant = toast.variant || "default";
1700
+ const displayIcon = toast.icon ?? (renderIcon ? renderIcon(variant) : null);
1701
+ return /* @__PURE__ */ jsx(
1702
+ "div",
1703
+ {
1704
+ className: `
1705
+ pointer-events-auto
1706
+ p-4
1707
+ border-2
1708
+ rounded-sm
1709
+ shadow-[2px_2px_0_0_var(--color-edge-primary)]
1710
+ animate-slideIn
1711
+ ${variantStyles6[variant]}
1712
+ `.trim(),
1713
+ role: "alert",
1714
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
1715
+ displayIcon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: displayIcon }),
1716
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
1717
+ /* @__PURE__ */ jsx("p", { className: "font-joystix text-xs uppercase text-content-primary", children: toast.title }),
1718
+ toast.description && /* @__PURE__ */ jsx("p", { className: "font-mondwest text-base text-content-primary/70 mt-1", children: toast.description })
1719
+ ] }),
1720
+ /* @__PURE__ */ jsx(
1721
+ "button",
1722
+ {
1723
+ onClick: onClose,
1724
+ className: "text-content-primary/50 hover:text-content-primary flex-shrink-0 -mt-1",
1725
+ "aria-label": "Close",
1726
+ children: renderCloseIcon ? renderCloseIcon() : /* @__PURE__ */ jsx(
1727
+ "svg",
1728
+ {
1729
+ width: "16",
1730
+ height: "16",
1731
+ viewBox: "0 0 16 16",
1732
+ fill: "none",
1733
+ xmlns: "http://www.w3.org/2000/svg",
1734
+ children: /* @__PURE__ */ jsx(
1735
+ "path",
1736
+ {
1737
+ d: "M12 4L4 12M4 4L12 12",
1738
+ stroke: "currentColor",
1739
+ strokeWidth: "2",
1740
+ strokeLinecap: "round",
1741
+ strokeLinejoin: "round"
1742
+ }
1743
+ )
1744
+ }
1745
+ )
1746
+ }
1747
+ )
1748
+ ] })
1749
+ }
1750
+ );
1751
+ }
1752
+ function HelpPanel({
1753
+ isOpen,
1754
+ onClose,
1755
+ children,
1756
+ title = "Help",
1757
+ closeButton,
1758
+ className = ""
1759
+ }) {
1760
+ const panelRef = useRef(null);
1761
+ useEffect(() => {
1762
+ const handleEscape = (e) => {
1763
+ if (e.key === "Escape" && isOpen) {
1764
+ onClose();
1765
+ }
1766
+ };
1767
+ document.addEventListener("keydown", handleEscape);
1768
+ return () => document.removeEventListener("keydown", handleEscape);
1769
+ }, [isOpen, onClose]);
1770
+ useEffect(() => {
1771
+ const handleClickOutside = (e) => {
1772
+ if (panelRef.current && !panelRef.current.contains(e.target) && isOpen) {
1773
+ onClose();
1774
+ }
1775
+ };
1776
+ const timeoutId = setTimeout(() => {
1777
+ document.addEventListener("mousedown", handleClickOutside);
1778
+ }, 100);
1779
+ return () => {
1780
+ clearTimeout(timeoutId);
1781
+ document.removeEventListener("mousedown", handleClickOutside);
1782
+ };
1783
+ }, [isOpen, onClose]);
1784
+ if (!isOpen) return null;
1785
+ return /* @__PURE__ */ jsx(
1786
+ "div",
1787
+ {
1788
+ className: `
1789
+ absolute inset-0 z-50
1790
+ bg-surface-secondary/20
1791
+ flex justify-center items-center
1792
+ `,
1793
+ children: /* @__PURE__ */ jsxs(
1794
+ "div",
1795
+ {
1796
+ ref: panelRef,
1797
+ className: `
1798
+ h-full w-full max-w-4xl
1799
+ bg-surface-primary
1800
+ border border-edge-primary
1801
+ shadow-card-lg
1802
+ flex flex-col
1803
+ animate-slide-in-right
1804
+ ${className}
1805
+ `,
1806
+ children: [
1807
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-edge-primary", children: [
1808
+ /* @__PURE__ */ jsx("span", { className: "font-joystix text-xs text-content-primary uppercase", children: title }),
1809
+ closeButton ? /* @__PURE__ */ jsx("span", { onClick: onClose, className: "cursor-pointer", children: closeButton }) : /* @__PURE__ */ jsx(
1810
+ "button",
1811
+ {
1812
+ onClick: onClose,
1813
+ className: "text-content-primary/50 hover:text-content-primary p-1",
1814
+ "aria-label": "Close help panel",
1815
+ children: /* @__PURE__ */ jsx(
1816
+ "svg",
1817
+ {
1818
+ width: "16",
1819
+ height: "16",
1820
+ viewBox: "0 0 16 16",
1821
+ fill: "none",
1822
+ xmlns: "http://www.w3.org/2000/svg",
1823
+ children: /* @__PURE__ */ jsx(
1824
+ "path",
1825
+ {
1826
+ d: "M12 4L4 12M4 4L12 12",
1827
+ stroke: "currentColor",
1828
+ strokeWidth: "2",
1829
+ strokeLinecap: "round",
1830
+ strokeLinejoin: "round"
1831
+ }
1832
+ )
1833
+ }
1834
+ )
1835
+ }
1836
+ )
1837
+ ] }),
1838
+ /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-auto p-4", children: /* @__PURE__ */ jsx("div", { className: "font-mondwest text-base text-content-primary space-y-4", children }) })
1839
+ ]
1840
+ }
1841
+ )
1842
+ }
1843
+ );
1844
+ }
1845
+ var PopoverContext = createContext(null);
1846
+ function usePopoverContext() {
1847
+ const context = useContext(PopoverContext);
1848
+ if (!context) {
1849
+ throw new Error("Popover components must be used within a Popover");
1850
+ }
1851
+ return context;
1852
+ }
1853
+ function Popover({
1854
+ open: controlledOpen,
1855
+ defaultOpen = false,
1856
+ onOpenChange,
1857
+ position = "bottom",
1858
+ children
1859
+ }) {
1860
+ const [internalOpen, setInternalOpen] = useState(defaultOpen);
1861
+ const isControlled = controlledOpen !== void 0;
1862
+ const open = isControlled ? controlledOpen : internalOpen;
1863
+ const triggerRef = useRef(null);
1864
+ const setOpen = useCallback((newOpen) => {
1865
+ if (!isControlled) {
1866
+ setInternalOpen(newOpen);
1867
+ }
1868
+ onOpenChange?.(newOpen);
1869
+ }, [isControlled, onOpenChange]);
1870
+ return /* @__PURE__ */ jsx(PopoverContext.Provider, { value: { open, setOpen, triggerRef, position }, children });
1871
+ }
1872
+ function PopoverTrigger({ children, asChild }) {
1873
+ const { open, setOpen, triggerRef } = usePopoverContext();
1874
+ const handleClick = () => {
1875
+ setOpen(!open);
1876
+ };
1877
+ if (asChild && React14.isValidElement(children)) {
1878
+ return React14.cloneElement(children, {
1879
+ onClick: handleClick,
1880
+ ref: triggerRef
1881
+ });
1882
+ }
1883
+ return /* @__PURE__ */ jsx(
1884
+ "button",
1885
+ {
1886
+ type: "button",
1887
+ ref: triggerRef,
1888
+ onClick: handleClick,
1889
+ children
1890
+ }
1891
+ );
1892
+ }
1893
+ function PopoverContent({ className = "", children, align = "center" }) {
1894
+ const { open, setOpen, triggerRef, position } = usePopoverContext();
1895
+ const contentRef = useRef(null);
1896
+ const [mounted, setMounted] = useState(false);
1897
+ const [coords, setCoords] = useState({ top: 0, left: 0 });
1898
+ useEffect(() => {
1899
+ setMounted(true);
1900
+ }, []);
1901
+ useEffect(() => {
1902
+ if (!open || !triggerRef.current || !contentRef.current) return;
1903
+ const trigger = triggerRef.current.getBoundingClientRect();
1904
+ const content = contentRef.current.getBoundingClientRect();
1905
+ const gap = 8;
1906
+ let top = 0;
1907
+ let left = 0;
1908
+ switch (position) {
1909
+ case "top":
1910
+ top = trigger.top - content.height - gap;
1911
+ left = trigger.left + (trigger.width - content.width) / 2;
1912
+ break;
1913
+ case "bottom":
1914
+ top = trigger.bottom + gap;
1915
+ left = trigger.left + (trigger.width - content.width) / 2;
1916
+ break;
1917
+ case "left":
1918
+ top = trigger.top + (trigger.height - content.height) / 2;
1919
+ left = trigger.left - content.width - gap;
1920
+ break;
1921
+ case "right":
1922
+ top = trigger.top + (trigger.height - content.height) / 2;
1923
+ left = trigger.right + gap;
1924
+ break;
1925
+ }
1926
+ if (position === "top" || position === "bottom") {
1927
+ if (align === "start") {
1928
+ left = trigger.left;
1929
+ } else if (align === "end") {
1930
+ left = trigger.right - content.width;
1931
+ }
1932
+ }
1933
+ top = Math.max(8, Math.min(top, window.innerHeight - content.height - 8));
1934
+ left = Math.max(8, Math.min(left, window.innerWidth - content.width - 8));
1935
+ setCoords({ top, left });
1936
+ }, [open, position, align, triggerRef]);
1937
+ useClickOutside(open, [contentRef, triggerRef], () => setOpen(false));
1938
+ useEscapeKey(open, () => setOpen(false));
1939
+ if (!mounted || !open) return null;
1940
+ return createPortal(
1941
+ /* @__PURE__ */ jsx(
1942
+ "div",
1943
+ {
1944
+ ref: contentRef,
1945
+ className: `
1946
+ fixed z-50
1947
+ bg-surface-primary
1948
+ border-2 border-edge-primary
1949
+ rounded-sm
1950
+ shadow-[2px_2px_0_0_var(--color-edge-primary)]
1951
+ p-4
1952
+ animate-fadeIn
1953
+ ${className}
1954
+ `.trim(),
1955
+ style: { top: coords.top, left: coords.left },
1956
+ children
1957
+ }
1958
+ ),
1959
+ document.body
1960
+ );
1961
+ }
1962
+ var SheetContext = createContext(null);
1963
+ function useSheetContext() {
1964
+ const context = useContext(SheetContext);
1965
+ if (!context) {
1966
+ throw new Error("Sheet components must be used within a Sheet");
1967
+ }
1968
+ return context;
1969
+ }
1970
+ function Sheet({
1971
+ open: controlledOpen,
1972
+ defaultOpen = false,
1973
+ onOpenChange,
1974
+ side = "right",
1975
+ children
1976
+ }) {
1977
+ const [internalOpen, setInternalOpen] = useState(defaultOpen);
1978
+ const isControlled = controlledOpen !== void 0;
1979
+ const open = isControlled ? controlledOpen : internalOpen;
1980
+ const setOpen = useCallback((newOpen) => {
1981
+ if (!isControlled) {
1982
+ setInternalOpen(newOpen);
1983
+ }
1984
+ onOpenChange?.(newOpen);
1985
+ }, [isControlled, onOpenChange]);
1986
+ return /* @__PURE__ */ jsx(SheetContext.Provider, { value: { open, setOpen, side }, children });
1987
+ }
1988
+ function SheetTrigger({ children, asChild }) {
1989
+ const { setOpen } = useSheetContext();
1990
+ if (asChild && React14.isValidElement(children)) {
1991
+ return React14.cloneElement(children, {
1992
+ onClick: () => setOpen(true)
1993
+ });
1994
+ }
1995
+ return /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setOpen(true), children });
1996
+ }
1997
+ var sideStyles = {
1998
+ left: {
1999
+ container: "inset-y-0 left-0 h-full w-80 max-w-[90vw]",
2000
+ open: "translate-x-0",
2001
+ closed: "-translate-x-full"
2002
+ },
2003
+ right: {
2004
+ container: "inset-y-0 right-0 h-full w-80 max-w-[90vw]",
2005
+ open: "translate-x-0",
2006
+ closed: "translate-x-full"
2007
+ },
2008
+ top: {
2009
+ container: "inset-x-0 top-0 w-full h-80 max-h-[90vh]",
2010
+ open: "translate-y-0",
2011
+ closed: "-translate-y-full"
2012
+ },
2013
+ bottom: {
2014
+ container: "inset-x-0 bottom-0 w-full h-80 max-h-[90vh]",
2015
+ open: "translate-y-0",
2016
+ closed: "translate-y-full"
2017
+ }
2018
+ };
2019
+ function SheetContent({ className = "", children }) {
2020
+ const { open, setOpen, side } = useSheetContext();
2021
+ const [mounted, setMounted] = useState(false);
2022
+ const [isVisible, setIsVisible] = useState(false);
2023
+ const styles = sideStyles[side];
2024
+ useEffect(() => {
2025
+ setMounted(true);
2026
+ }, []);
2027
+ useEffect(() => {
2028
+ if (open) {
2029
+ setIsVisible(true);
2030
+ } else {
2031
+ const timer = setTimeout(() => {
2032
+ setIsVisible(false);
2033
+ }, 200);
2034
+ return () => clearTimeout(timer);
2035
+ }
2036
+ }, [open]);
2037
+ useEscapeKey(open, () => setOpen(false));
2038
+ useLockBodyScroll(open);
2039
+ if (!mounted || !isVisible) return null;
2040
+ return createPortal(
2041
+ /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50", children: [
2042
+ /* @__PURE__ */ jsx(
2043
+ "div",
2044
+ {
2045
+ className: `
2046
+ absolute inset-0 bg-surface-secondary/50
2047
+ transition-opacity duration-200
2048
+ ${open ? "opacity-100" : "opacity-0"}
2049
+ `.trim(),
2050
+ onClick: () => setOpen(false),
2051
+ "aria-hidden": "true"
2052
+ }
2053
+ ),
2054
+ /* @__PURE__ */ jsx(
2055
+ "div",
2056
+ {
2057
+ role: "dialog",
2058
+ "aria-modal": "true",
2059
+ className: `
2060
+ fixed
2061
+ ${styles.container}
2062
+ bg-surface-primary
2063
+ border-edge-primary
2064
+ ${side === "left" ? "border-r-2" : ""}
2065
+ ${side === "right" ? "border-l-2" : ""}
2066
+ ${side === "top" ? "border-b-2" : ""}
2067
+ ${side === "bottom" ? "border-t-2" : ""}
2068
+ shadow-[4px_4px_0_0_var(--color-edge-primary)]
2069
+ transform transition-transform duration-200 ease-out
2070
+ ${open ? styles.open : styles.closed}
2071
+ ${className}
2072
+ `.trim(),
2073
+ children
2074
+ }
2075
+ )
2076
+ ] }),
2077
+ document.body
2078
+ );
2079
+ }
2080
+ function SheetHeader({ className = "", children }) {
2081
+ return /* @__PURE__ */ jsx("div", { className: `px-6 pt-6 pb-4 border-b border-edge-primary/20 ${className}`.trim(), children });
2082
+ }
2083
+ function SheetTitle({ className = "", children }) {
2084
+ return /* @__PURE__ */ jsx("h2", { className: `font-joystix text-base uppercase text-content-primary ${className}`.trim(), children });
2085
+ }
2086
+ function SheetDescription({ className = "", children }) {
2087
+ return /* @__PURE__ */ jsx("p", { className: `font-mondwest text-base text-content-primary/70 mt-2 ${className}`.trim(), children });
2088
+ }
2089
+ function SheetBody({ className = "", children }) {
2090
+ return /* @__PURE__ */ jsx("div", { className: `px-6 py-4 flex-1 overflow-auto ${className}`.trim(), children });
2091
+ }
2092
+ function SheetFooter({ className = "", children }) {
2093
+ return /* @__PURE__ */ jsx("div", { className: `px-6 pb-6 pt-4 border-t border-edge-primary/20 flex justify-end gap-2 ${className}`.trim(), children });
2094
+ }
2095
+ function SheetClose({ children, asChild }) {
2096
+ const { setOpen } = useSheetContext();
2097
+ if (asChild && React14.isValidElement(children)) {
2098
+ return React14.cloneElement(children, {
2099
+ onClick: () => setOpen(false)
2100
+ });
2101
+ }
2102
+ return /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setOpen(false), children });
2103
+ }
2104
+ var popoverStyles = `
2105
+ absolute top-12 right-2 z-50 w-72
2106
+ bg-surface-primary border-2 border-edge-primary rounded-sm shadow-lg
2107
+ `;
2108
+ var headerStyles = `
2109
+ flex items-center justify-between px-3 py-2 border-b border-edge-primary/20
2110
+ `;
2111
+ var contentStyles = `
2112
+ p-2 space-y-3 max-h-80 overflow-y-auto
2113
+ `;
2114
+ var categoryLabelStyles = `
2115
+ font-heading text-xs uppercase text-content-secondary px-2 mb-1
2116
+ `;
2117
+ var footerStyles = `
2118
+ px-3 py-2 border-t border-edge-primary/20 bg-content-primary/5
2119
+ `;
2120
+ function MockStatesPopover({
2121
+ isOpen,
2122
+ onClose,
2123
+ mockStates,
2124
+ activeMockState,
2125
+ onSelectState,
2126
+ categories,
2127
+ title = "Mock States",
2128
+ footerText = "Dev mode only",
2129
+ className = ""
2130
+ }) {
2131
+ if (!isOpen) return null;
2132
+ const derivedCategories = categories ?? [...new Set(mockStates.map((s) => s.category))].map((cat) => ({
2133
+ id: cat,
2134
+ label: cat.charAt(0).toUpperCase() + cat.slice(1)
2135
+ }));
2136
+ const statesByCategory = derivedCategories.map((cat) => ({
2137
+ category: cat,
2138
+ states: mockStates.filter((s) => s.category === cat.id)
2139
+ })).filter((group) => group.states.length > 0);
2140
+ const renderStateButton = (def) => {
2141
+ const isActive = activeMockState === def.id;
2142
+ return /* @__PURE__ */ jsxs(
2143
+ "button",
2144
+ {
2145
+ onClick: () => onSelectState(def.id),
2146
+ className: `
2147
+ w-full text-left px-3 py-2 rounded-sm
2148
+ flex items-center gap-2
2149
+ transition-colors duration-150
2150
+ ${isActive ? "bg-action-primary text-content-primary" : "hover:bg-content-primary/5 text-content-primary"}
2151
+ `,
2152
+ children: [
2153
+ def.icon && /* @__PURE__ */ jsx("span", { className: "text-sm", children: def.icon }),
2154
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
2155
+ /* @__PURE__ */ jsx("div", { className: "font-heading text-xs uppercase truncate", children: def.name }),
2156
+ /* @__PURE__ */ jsx("div", { className: "font-body text-xs text-content-secondary truncate", children: def.description })
2157
+ ] }),
2158
+ isActive && /* @__PURE__ */ jsx("span", { className: "text-xs", children: "\u2713" })
2159
+ ]
2160
+ },
2161
+ def.id
2162
+ );
2163
+ };
2164
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2165
+ /* @__PURE__ */ jsx(
2166
+ "div",
2167
+ {
2168
+ className: "fixed inset-0 z-40",
2169
+ onClick: onClose
2170
+ }
2171
+ ),
2172
+ /* @__PURE__ */ jsxs("div", { className: `${popoverStyles} ${className}`.trim(), children: [
2173
+ /* @__PURE__ */ jsxs("div", { className: headerStyles, children: [
2174
+ /* @__PURE__ */ jsx("span", { className: "font-heading text-xs uppercase", children: title }),
2175
+ /* @__PURE__ */ jsx(
2176
+ Button,
2177
+ {
2178
+ variant: "ghost",
2179
+ size: "sm",
2180
+ iconOnly: true,
2181
+ onClick: onClose,
2182
+ "aria-label": "Close",
2183
+ children: "\u2715"
2184
+ }
2185
+ )
2186
+ ] }),
2187
+ /* @__PURE__ */ jsx("div", { className: contentStyles, children: statesByCategory.map(({ category, states }) => /* @__PURE__ */ jsxs("div", { children: [
2188
+ /* @__PURE__ */ jsx("div", { className: categoryLabelStyles, children: category.label }),
2189
+ /* @__PURE__ */ jsx("div", { className: "space-y-1", children: states.map(renderStateButton) })
2190
+ ] }, category.id)) }),
2191
+ footerText && /* @__PURE__ */ jsx("div", { className: footerStyles, children: /* @__PURE__ */ jsx("div", { className: "font-body text-xs text-content-secondary text-center", children: footerText }) })
2192
+ ] })
2193
+ ] });
2194
+ }
2195
+ var baseStyles5 = `
2196
+ text-center
2197
+ `;
2198
+ var variantStyles7 = {
2199
+ default: {
2200
+ container: "p-4 bg-surface-primary border border-edge-primary rounded-md",
2201
+ label: "font-mono text-xs text-content-primary/60 mb-2",
2202
+ timer: "flex items-center justify-center gap-1",
2203
+ segment: "flex flex-col items-center min-w-[3rem]",
2204
+ value: "font-joystix text-2xl text-content-primary tabular-nums",
2205
+ unit: "font-mono text-2xs text-content-primary/50 uppercase mt-0.5",
2206
+ separator: "font-joystix text-xl text-content-primary/40 self-start mt-1"
2207
+ },
2208
+ compact: {
2209
+ container: "px-3 py-2 bg-surface-primary border border-edge-primary rounded-sm",
2210
+ label: "font-mono text-2xs text-content-primary/60 mb-1",
2211
+ timer: "flex items-center justify-center gap-0.5",
2212
+ segment: "flex flex-col items-center min-w-[2rem]",
2213
+ value: "font-joystix text-sm text-content-primary tabular-nums",
2214
+ unit: "font-mono text-2xs text-content-primary/50 uppercase",
2215
+ separator: "font-joystix text-sm text-content-primary/40 self-start"
2216
+ },
2217
+ large: {
2218
+ container: "p-6 bg-surface-primary border border-edge-primary rounded-md shadow-card",
2219
+ label: "font-mono text-sm text-content-primary/60 mb-3",
2220
+ timer: "flex items-center justify-center gap-2",
2221
+ segment: "flex flex-col items-center min-w-[4rem] bg-surface-muted border border-edge-primary rounded-sm px-3 py-2",
2222
+ value: "font-joystix text-3xl text-content-primary tabular-nums",
2223
+ unit: "font-mono text-xs text-content-primary/50 uppercase mt-1",
2224
+ separator: "font-joystix text-2xl text-content-primary/40 self-center"
2225
+ }
2226
+ };
2227
+ function getTimeRemaining(endTime) {
2228
+ const end = typeof endTime === "number" ? endTime : endTime.getTime();
2229
+ const total = Math.max(0, end - Date.now());
2230
+ const seconds = Math.floor(total / 1e3 % 60);
2231
+ const minutes = Math.floor(total / 1e3 / 60 % 60);
2232
+ const hours = Math.floor(total / (1e3 * 60 * 60) % 24);
2233
+ const days = Math.floor(total / (1e3 * 60 * 60 * 24));
2234
+ return { days, hours, minutes, seconds, total };
2235
+ }
2236
+ function getStatus(endTime, startTime) {
2237
+ const now = Date.now();
2238
+ const end = typeof endTime === "number" ? endTime : endTime.getTime();
2239
+ const start = startTime ? typeof startTime === "number" ? startTime : startTime.getTime() : now;
2240
+ if (now < start) return "upcoming";
2241
+ if (now >= end) return "ended";
2242
+ return "active";
2243
+ }
2244
+ function padZero(num) {
2245
+ return num.toString().padStart(2, "0");
2246
+ }
2247
+ function CountdownTimer({
2248
+ endTime,
2249
+ startTime,
2250
+ variant = "default",
2251
+ label,
2252
+ onComplete,
2253
+ endedMessage = "Ended",
2254
+ upcomingMessage = "Starting soon",
2255
+ showDays = true,
2256
+ className = ""
2257
+ }) {
2258
+ const [timeRemaining, setTimeRemaining] = useState(
2259
+ () => getTimeRemaining(endTime)
2260
+ );
2261
+ const [status, setStatus] = useState(
2262
+ () => getStatus(endTime, startTime)
2263
+ );
2264
+ const updateTime = useCallback(() => {
2265
+ const newTime = getTimeRemaining(endTime);
2266
+ const newStatus = getStatus(endTime, startTime);
2267
+ setTimeRemaining(newTime);
2268
+ setStatus(newStatus);
2269
+ if (newStatus === "ended" && onComplete) {
2270
+ onComplete();
2271
+ }
2272
+ }, [endTime, startTime, onComplete]);
2273
+ useEffect(() => {
2274
+ updateTime();
2275
+ if (status === "ended") return;
2276
+ const interval = setInterval(updateTime, 1e3);
2277
+ return () => clearInterval(interval);
2278
+ }, [updateTime, status]);
2279
+ const styles = variantStyles7[variant];
2280
+ if (status === "ended") {
2281
+ return /* @__PURE__ */ jsxs("div", { className: `${baseStyles5} ${styles.container} ${className}`, children: [
2282
+ label && /* @__PURE__ */ jsx("p", { className: styles.label, children: label }),
2283
+ /* @__PURE__ */ jsx("p", { className: `font-joystix ${variant === "large" ? "text-xl" : variant === "compact" ? "text-sm" : "text-lg"} text-content-primary/60`, children: endedMessage })
2284
+ ] });
2285
+ }
2286
+ if (status === "upcoming" && startTime) {
2287
+ const startRemaining = getTimeRemaining(startTime);
2288
+ return /* @__PURE__ */ jsxs("div", { className: `${baseStyles5} ${styles.container} ${className}`, children: [
2289
+ /* @__PURE__ */ jsx("p", { className: styles.label, children: "Starts in" }),
2290
+ /* @__PURE__ */ jsxs("div", { className: styles.timer, children: [
2291
+ showDays && startRemaining.days > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
2292
+ /* @__PURE__ */ jsxs("div", { className: styles.segment, children: [
2293
+ /* @__PURE__ */ jsx("span", { className: styles.value, children: startRemaining.days }),
2294
+ /* @__PURE__ */ jsx("span", { className: styles.unit, children: "days" })
2295
+ ] }),
2296
+ /* @__PURE__ */ jsx("span", { className: styles.separator, children: ":" })
2297
+ ] }),
2298
+ /* @__PURE__ */ jsxs("div", { className: styles.segment, children: [
2299
+ /* @__PURE__ */ jsx("span", { className: styles.value, children: padZero(startRemaining.hours) }),
2300
+ /* @__PURE__ */ jsx("span", { className: styles.unit, children: "hrs" })
2301
+ ] }),
2302
+ /* @__PURE__ */ jsx("span", { className: styles.separator, children: ":" }),
2303
+ /* @__PURE__ */ jsxs("div", { className: styles.segment, children: [
2304
+ /* @__PURE__ */ jsx("span", { className: styles.value, children: padZero(startRemaining.minutes) }),
2305
+ /* @__PURE__ */ jsx("span", { className: styles.unit, children: "min" })
2306
+ ] }),
2307
+ /* @__PURE__ */ jsx("span", { className: styles.separator, children: ":" }),
2308
+ /* @__PURE__ */ jsxs("div", { className: styles.segment, children: [
2309
+ /* @__PURE__ */ jsx("span", { className: styles.value, children: padZero(startRemaining.seconds) }),
2310
+ /* @__PURE__ */ jsx("span", { className: styles.unit, children: "sec" })
2311
+ ] })
2312
+ ] })
2313
+ ] });
2314
+ }
2315
+ return /* @__PURE__ */ jsxs("div", { className: `${baseStyles5} ${styles.container} ${className}`, children: [
2316
+ label && /* @__PURE__ */ jsx("p", { className: styles.label, children: label }),
2317
+ /* @__PURE__ */ jsxs("div", { className: styles.timer, children: [
2318
+ showDays && timeRemaining.days > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
2319
+ /* @__PURE__ */ jsxs("div", { className: styles.segment, children: [
2320
+ /* @__PURE__ */ jsx("span", { className: styles.value, children: timeRemaining.days }),
2321
+ /* @__PURE__ */ jsx("span", { className: styles.unit, children: "days" })
2322
+ ] }),
2323
+ /* @__PURE__ */ jsx("span", { className: styles.separator, children: ":" })
2324
+ ] }),
2325
+ /* @__PURE__ */ jsxs("div", { className: styles.segment, children: [
2326
+ /* @__PURE__ */ jsx("span", { className: styles.value, children: padZero(timeRemaining.hours) }),
2327
+ /* @__PURE__ */ jsx("span", { className: styles.unit, children: "hrs" })
2328
+ ] }),
2329
+ /* @__PURE__ */ jsx("span", { className: styles.separator, children: ":" }),
2330
+ /* @__PURE__ */ jsxs("div", { className: styles.segment, children: [
2331
+ /* @__PURE__ */ jsx("span", { className: styles.value, children: padZero(timeRemaining.minutes) }),
2332
+ /* @__PURE__ */ jsx("span", { className: styles.unit, children: "min" })
2333
+ ] }),
2334
+ /* @__PURE__ */ jsx("span", { className: styles.separator, children: ":" }),
2335
+ /* @__PURE__ */ jsxs("div", { className: styles.segment, children: [
2336
+ /* @__PURE__ */ jsx("span", { className: styles.value, children: padZero(timeRemaining.seconds) }),
2337
+ /* @__PURE__ */ jsx("span", { className: styles.unit, children: "sec" })
2338
+ ] })
2339
+ ] })
2340
+ ] });
2341
+ }
2342
+ function formatAddress(address) {
2343
+ if (!address) return "";
2344
+ if (address.length <= 10) return address;
2345
+ return `${address.slice(0, 4)}...${address.slice(-4)}`;
2346
+ }
2347
+ function Web3ActionBar({
2348
+ isConnected,
2349
+ walletAddress,
2350
+ onConnect,
2351
+ onDisconnect,
2352
+ disconnectIcon,
2353
+ children,
2354
+ className = ""
2355
+ }) {
2356
+ return /* @__PURE__ */ jsxs("div", { className: `flex items-center justify-between gap-4 px-2 py-2 bg-surface-primary border-t border-edge-primary shrink-0 ${className}`.trim(), children: [
2357
+ /* @__PURE__ */ jsx("div", { className: "flex gap-2 items-center", children: !isConnected ? /* @__PURE__ */ jsx(Button, { onClick: onConnect, children: "Connect" }) : /* @__PURE__ */ jsxs(Fragment, { children: [
2358
+ walletAddress && /* @__PURE__ */ jsx("span", { className: "font-mono text-xs text-content-primary", children: formatAddress(walletAddress) }),
2359
+ onDisconnect && /* @__PURE__ */ jsx(
2360
+ Button,
2361
+ {
2362
+ variant: "ghost",
2363
+ iconOnly: true,
2364
+ icon: disconnectIcon,
2365
+ onClick: onDisconnect,
2366
+ title: "Disconnect wallet"
2367
+ }
2368
+ )
2369
+ ] }) }),
2370
+ isConnected && children && /* @__PURE__ */ jsx("div", { className: "flex gap-2 items-center", children })
2371
+ ] });
2372
+ }
2373
+ var DialogContext = createContext(null);
2374
+ function useDialogContext() {
2375
+ const context = useContext(DialogContext);
2376
+ if (!context) {
2377
+ throw new Error("Dialog components must be used within a Dialog");
2378
+ }
2379
+ return context;
2380
+ }
2381
+ function Dialog({
2382
+ open: controlledOpen,
2383
+ defaultOpen = false,
2384
+ onOpenChange,
2385
+ children
2386
+ }) {
2387
+ const [internalOpen, setInternalOpen] = useState(defaultOpen);
2388
+ const isControlled = controlledOpen !== void 0;
2389
+ const open = isControlled ? controlledOpen : internalOpen;
2390
+ const setOpen = useCallback((newOpen) => {
2391
+ if (!isControlled) {
2392
+ setInternalOpen(newOpen);
2393
+ }
2394
+ onOpenChange?.(newOpen);
2395
+ }, [isControlled, onOpenChange]);
2396
+ return /* @__PURE__ */ jsx(DialogContext.Provider, { value: { open, setOpen }, children });
2397
+ }
2398
+ function DialogTrigger({ children, asChild }) {
2399
+ const { setOpen } = useDialogContext();
2400
+ if (asChild && React14.isValidElement(children)) {
2401
+ return React14.cloneElement(children, {
2402
+ onClick: () => setOpen(true)
2403
+ });
2404
+ }
2405
+ return /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setOpen(true), children });
2406
+ }
2407
+ function DialogContent({ className = "", children }) {
2408
+ const { open, setOpen } = useDialogContext();
2409
+ const [mounted, setMounted] = useState(false);
2410
+ useEffect(() => {
2411
+ setMounted(true);
2412
+ }, []);
2413
+ useEscapeKey(open, () => setOpen(false));
2414
+ useLockBodyScroll(open);
2415
+ if (!mounted || !open) return null;
2416
+ return createPortal(
2417
+ /* @__PURE__ */ jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [
2418
+ /* @__PURE__ */ jsx(
2419
+ "div",
2420
+ {
2421
+ className: "absolute inset-0 bg-surface-secondary/50 animate-fadeIn",
2422
+ onClick: () => setOpen(false),
2423
+ "aria-hidden": "true"
2424
+ }
2425
+ ),
2426
+ /* @__PURE__ */ jsx(
2427
+ "div",
2428
+ {
2429
+ role: "dialog",
2430
+ "aria-modal": "true",
2431
+ className: `
2432
+ relative z-10
2433
+ w-full max-w-lg mx-4
2434
+ bg-surface-primary
2435
+ border-2 border-edge-primary
2436
+ rounded-sm
2437
+ shadow-[4px_4px_0_0_var(--color-edge-primary)]
2438
+ animate-scaleIn
2439
+ ${className}
2440
+ `.trim(),
2441
+ children
2442
+ }
2443
+ )
2444
+ ] }),
2445
+ document.body
2446
+ );
2447
+ }
2448
+ function DialogHeader({ className = "", children }) {
2449
+ return /* @__PURE__ */ jsx("div", { className: `px-6 pt-6 pb-4 border-b border-edge-primary/20 ${className}`.trim(), children });
2450
+ }
2451
+ function DialogTitle({ className = "", children }) {
2452
+ return /* @__PURE__ */ jsx("h2", { className: `font-joystix text-base uppercase text-content-primary ${className}`.trim(), children });
2453
+ }
2454
+ function DialogDescription({ className = "", children }) {
2455
+ return /* @__PURE__ */ jsx("p", { className: `font-mondwest text-base text-content-primary/70 mt-2 ${className}`.trim(), children });
2456
+ }
2457
+ function DialogBody({ className = "", children }) {
2458
+ return /* @__PURE__ */ jsx("div", { className: `px-6 py-4 ${className}`.trim(), children });
2459
+ }
2460
+ function DialogFooter({ className = "", children }) {
2461
+ return /* @__PURE__ */ jsx("div", { className: `px-6 pb-6 pt-4 border-t border-edge-primary/20 flex justify-end gap-2 ${className}`.trim(), children });
2462
+ }
2463
+ function DialogClose({ children, asChild }) {
2464
+ const { setOpen } = useDialogContext();
2465
+ if (asChild && React14.isValidElement(children)) {
2466
+ return React14.cloneElement(children, {
2467
+ onClick: () => setOpen(false)
2468
+ });
2469
+ }
2470
+ return /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setOpen(false), children });
2471
+ }
2472
+
2473
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, Badge, Breadcrumbs, Button, Card, CardBody, CardFooter, CardHeader, Checkbox, ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, CountdownTimer, Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, Divider, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, HelpPanel, Input, Label, MockStatesPopover, Popover, PopoverContent, PopoverTrigger, Progress, Radio, Select, Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Slider, Spinner, Switch, TabContent, TabList, TabTrigger, Tabs, TextArea, ToastProvider, Tooltip, Web3ActionBar, useToast };
2474
+ //# sourceMappingURL=index.mjs.map
2475
+ //# sourceMappingURL=index.mjs.map