@melony/ui-shadcn 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +96 -970
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -1,90 +1,28 @@
|
|
|
1
1
|
import { clsx } from 'clsx';
|
|
2
2
|
import { twMerge } from 'tailwind-merge';
|
|
3
|
-
import { jsx, jsxs
|
|
4
|
-
import { Separator as Separator$1 } from '@base-ui/react/separator';
|
|
3
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
4
|
import { useMelony } from '@melony/react';
|
|
6
|
-
import
|
|
7
|
-
import { createContext, useState, useRef, useEffect, useMemo, useContext } from 'react';
|
|
8
|
-
import { Dialog as Dialog$1 } from '@base-ui/react/dialog';
|
|
5
|
+
import { Separator as Separator$1 } from '@base-ui/react/separator';
|
|
9
6
|
import * as LucideIcons from 'lucide-react';
|
|
10
|
-
import
|
|
11
|
-
import
|
|
7
|
+
import '@base-ui/react/merge-props';
|
|
8
|
+
import '@base-ui/react/use-render';
|
|
12
9
|
import { cva } from 'class-variance-authority';
|
|
10
|
+
import * as React2 from 'react';
|
|
11
|
+
import { createContext, useState, useRef, useEffect, useContext } from 'react';
|
|
13
12
|
import { Input as Input$1 } from '@base-ui/react/input';
|
|
14
13
|
import { Select as Select$1 } from '@base-ui/react/select';
|
|
15
14
|
import { createPortal } from 'react-dom';
|
|
16
15
|
import { Button as Button$1 } from '@base-ui/react/button';
|
|
17
16
|
import { MelonyRenderer } from '@melony/ui-kit';
|
|
18
|
-
import
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
import
|
|
17
|
+
import '@base-ui/react/menu';
|
|
18
|
+
import 'react-markdown';
|
|
19
|
+
import 'remark-gfm';
|
|
20
|
+
import 'remark-breaks';
|
|
22
21
|
|
|
23
22
|
// src/lib/utils.ts
|
|
24
23
|
function cn(...inputs) {
|
|
25
24
|
return twMerge(clsx(inputs));
|
|
26
25
|
}
|
|
27
|
-
function Card({
|
|
28
|
-
className,
|
|
29
|
-
size = "default",
|
|
30
|
-
...props
|
|
31
|
-
}) {
|
|
32
|
-
return /* @__PURE__ */ jsx(
|
|
33
|
-
"div",
|
|
34
|
-
{
|
|
35
|
-
"data-slot": "card",
|
|
36
|
-
"data-size": size,
|
|
37
|
-
className: cn(
|
|
38
|
-
"ring-foreground/10 bg-card text-card-foreground gap-2 overflow-hidden rounded-2xl py-2 text-sm ring-1 has-[>img:first-child]:pt-0 data-[size=sm]:gap-4 data-[size=sm]:py-4 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col",
|
|
39
|
-
className
|
|
40
|
-
),
|
|
41
|
-
...props
|
|
42
|
-
}
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
function CardHeader({ className, ...props }) {
|
|
46
|
-
return /* @__PURE__ */ jsx(
|
|
47
|
-
"div",
|
|
48
|
-
{
|
|
49
|
-
"data-slot": "card-header",
|
|
50
|
-
className: cn(
|
|
51
|
-
"gap-2 rounded-t-xl px-4 group-data-[size=sm]/card:px-4 [.border-b]:pb-2 group-data-[size=sm]/card:[.border-b]:pb-4 group/card-header @container/card-header grid auto-rows-min items-start has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]",
|
|
52
|
-
className
|
|
53
|
-
),
|
|
54
|
-
...props
|
|
55
|
-
}
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
function CardTitle({ className, ...props }) {
|
|
59
|
-
return /* @__PURE__ */ jsx(
|
|
60
|
-
"div",
|
|
61
|
-
{
|
|
62
|
-
"data-slot": "card-title",
|
|
63
|
-
className: cn("text-base font-medium", className),
|
|
64
|
-
...props
|
|
65
|
-
}
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
function CardDescription({ className, ...props }) {
|
|
69
|
-
return /* @__PURE__ */ jsx(
|
|
70
|
-
"div",
|
|
71
|
-
{
|
|
72
|
-
"data-slot": "card-description",
|
|
73
|
-
className: cn("text-muted-foreground text-sm", className),
|
|
74
|
-
...props
|
|
75
|
-
}
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
function CardContent({ className, ...props }) {
|
|
79
|
-
return /* @__PURE__ */ jsx(
|
|
80
|
-
"div",
|
|
81
|
-
{
|
|
82
|
-
"data-slot": "card-content",
|
|
83
|
-
className: cn("px-6 group-data-[size=sm]/card:px-4", className),
|
|
84
|
-
...props
|
|
85
|
-
}
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
26
|
|
|
89
27
|
// src/lib/theme-utils.ts
|
|
90
28
|
var paddingMap = {
|
|
@@ -114,15 +52,6 @@ var paddingHorizontalMap = {
|
|
|
114
52
|
xl: "px-8",
|
|
115
53
|
xxl: "px-12"
|
|
116
54
|
};
|
|
117
|
-
var interactivePaddingMap = {
|
|
118
|
-
none: "p-0",
|
|
119
|
-
xs: "py-1 px-2",
|
|
120
|
-
sm: "py-1.5 px-3",
|
|
121
|
-
md: "py-2 px-4",
|
|
122
|
-
lg: "py-3 px-6",
|
|
123
|
-
xl: "py-4 px-8",
|
|
124
|
-
xxl: "py-6 px-10"
|
|
125
|
-
};
|
|
126
55
|
var marginMap = {
|
|
127
56
|
none: "m-0",
|
|
128
57
|
xs: "m-1",
|
|
@@ -281,35 +210,6 @@ var resolveUIStyle = (property, value) => {
|
|
|
281
210
|
[property]: `color-mix(in oklch, ${variable}, transparent ${100 - opacity * 100}%)`
|
|
282
211
|
};
|
|
283
212
|
};
|
|
284
|
-
var Card2 = ({
|
|
285
|
-
children,
|
|
286
|
-
title,
|
|
287
|
-
subtitle,
|
|
288
|
-
background,
|
|
289
|
-
padding = "md",
|
|
290
|
-
radius = "md",
|
|
291
|
-
shadow = "md"
|
|
292
|
-
}) => {
|
|
293
|
-
return /* @__PURE__ */ jsxs(
|
|
294
|
-
Card,
|
|
295
|
-
{
|
|
296
|
-
className: cn(
|
|
297
|
-
"w-full max-w-full relative overflow-hidden transition-all duration-200",
|
|
298
|
-
background && colorBgMap[background],
|
|
299
|
-
radius && radiusMap[radius],
|
|
300
|
-
shadow && shadowMap[shadow],
|
|
301
|
-
!shadow && "shadow-sm border border-border/40"
|
|
302
|
-
),
|
|
303
|
-
children: [
|
|
304
|
-
(title || subtitle) && /* @__PURE__ */ jsxs(CardHeader, { className: "py-2.5 px-3 space-y-0.5 border-b border-border/40 bg-muted/5", children: [
|
|
305
|
-
title && /* @__PURE__ */ jsx(CardTitle, { className: "text-sm font-semibold tracking-tight leading-none", children: title }),
|
|
306
|
-
subtitle && /* @__PURE__ */ jsx(CardDescription, { className: "text-xs leading-tight text-muted-foreground/80", children: subtitle })
|
|
307
|
-
] }),
|
|
308
|
-
/* @__PURE__ */ jsx(CardContent, { className: cn("flex flex-col gap-2", paddingMap[padding]), children })
|
|
309
|
-
]
|
|
310
|
-
}
|
|
311
|
-
);
|
|
312
|
-
};
|
|
313
213
|
var Row = (props) => {
|
|
314
214
|
const {
|
|
315
215
|
children,
|
|
@@ -392,14 +292,22 @@ var Box = (props) => {
|
|
|
392
292
|
shadow = "none",
|
|
393
293
|
group = false,
|
|
394
294
|
flex = void 0,
|
|
395
|
-
overflow = "hidden"
|
|
295
|
+
overflow = "hidden",
|
|
296
|
+
onClickAction
|
|
396
297
|
} = props;
|
|
298
|
+
const { send } = useMelony();
|
|
397
299
|
const [baseBgColor] = (background || "").split("/");
|
|
398
300
|
const [baseBorderColor] = (borderColor || "").split("/");
|
|
399
301
|
const dynamicStyles = {
|
|
400
302
|
...resolveUIStyle("backgroundColor", background),
|
|
401
303
|
...resolveUIStyle("borderColor", borderColor)
|
|
402
304
|
};
|
|
305
|
+
const isInteractive = !!onClickAction;
|
|
306
|
+
const handleClick = () => {
|
|
307
|
+
if (onClickAction) {
|
|
308
|
+
send(onClickAction);
|
|
309
|
+
}
|
|
310
|
+
};
|
|
403
311
|
return /* @__PURE__ */ jsx(
|
|
404
312
|
"div",
|
|
405
313
|
{
|
|
@@ -418,7 +326,8 @@ var Box = (props) => {
|
|
|
418
326
|
widthMap[width],
|
|
419
327
|
height === "full" && "h-full",
|
|
420
328
|
shadowMap[shadow],
|
|
421
|
-
group && "group"
|
|
329
|
+
group && "group",
|
|
330
|
+
isInteractive && "cursor-pointer"
|
|
422
331
|
),
|
|
423
332
|
style: {
|
|
424
333
|
...dynamicStyles,
|
|
@@ -426,6 +335,7 @@ var Box = (props) => {
|
|
|
426
335
|
width: width && typeof width === "number" ? `${width}px` : void 0,
|
|
427
336
|
overflow
|
|
428
337
|
},
|
|
338
|
+
onClick: isInteractive ? handleClick : void 0,
|
|
429
339
|
children
|
|
430
340
|
}
|
|
431
341
|
);
|
|
@@ -509,278 +419,41 @@ var Divider = ({
|
|
|
509
419
|
}
|
|
510
420
|
);
|
|
511
421
|
};
|
|
512
|
-
var
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
gapMap[gap],
|
|
520
|
-
widthMap[width]
|
|
521
|
-
),
|
|
522
|
-
style: { flex, overflow, width: width && typeof width === "number" ? `${width}px` : void 0 },
|
|
523
|
-
children
|
|
524
|
-
}
|
|
525
|
-
);
|
|
526
|
-
};
|
|
527
|
-
var ListItem = ({
|
|
528
|
-
children,
|
|
529
|
-
onClickAction,
|
|
530
|
-
gap = "sm",
|
|
531
|
-
padding = "sm",
|
|
532
|
-
background,
|
|
533
|
-
radius = "md",
|
|
534
|
-
align = "center"
|
|
422
|
+
var Image = ({
|
|
423
|
+
src,
|
|
424
|
+
alt,
|
|
425
|
+
width = "auto",
|
|
426
|
+
height,
|
|
427
|
+
radius = "none",
|
|
428
|
+
objectFit = "cover"
|
|
535
429
|
}) => {
|
|
536
|
-
const { send } = useMelony();
|
|
537
|
-
const isInteractive = !!onClickAction;
|
|
538
|
-
const handleClick = () => {
|
|
539
|
-
if (onClickAction) {
|
|
540
|
-
send(onClickAction);
|
|
541
|
-
}
|
|
542
|
-
};
|
|
543
|
-
return /* @__PURE__ */ jsx(
|
|
544
|
-
"div",
|
|
545
|
-
{
|
|
546
|
-
onClick: isInteractive ? handleClick : void 0,
|
|
547
|
-
className: cn(
|
|
548
|
-
"flex flex-row transition-colors text-sm",
|
|
549
|
-
interactivePaddingMap[padding],
|
|
550
|
-
background ? colorBgMap[background] : isInteractive && "hover:bg-muted",
|
|
551
|
-
radiusMap[radius],
|
|
552
|
-
isInteractive ? "cursor-pointer" : "cursor-default"
|
|
553
|
-
),
|
|
554
|
-
children: /* @__PURE__ */ jsx(Row, { align, gap, children })
|
|
555
|
-
}
|
|
556
|
-
);
|
|
557
|
-
};
|
|
558
|
-
function Dialog({ ...props }) {
|
|
559
|
-
return /* @__PURE__ */ jsx(Dialog$1.Root, { "data-slot": "dialog", ...props });
|
|
560
|
-
}
|
|
561
|
-
function DialogTrigger({ ...props }) {
|
|
562
|
-
return /* @__PURE__ */ jsx(Dialog$1.Trigger, { "data-slot": "dialog-trigger", ...props });
|
|
563
|
-
}
|
|
564
|
-
function DialogPortal({ ...props }) {
|
|
565
|
-
return /* @__PURE__ */ jsx(Dialog$1.Portal, { "data-slot": "dialog-portal", ...props });
|
|
566
|
-
}
|
|
567
|
-
function DialogOverlay({
|
|
568
|
-
className,
|
|
569
|
-
...props
|
|
570
|
-
}) {
|
|
571
|
-
return /* @__PURE__ */ jsx(
|
|
572
|
-
Dialog$1.Backdrop,
|
|
573
|
-
{
|
|
574
|
-
"data-slot": "dialog-overlay",
|
|
575
|
-
className: cn(
|
|
576
|
-
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 bg-black/80 duration-200 supports-backdrop-filter:backdrop-blur-sm fixed inset-0 isolate z-50",
|
|
577
|
-
className
|
|
578
|
-
),
|
|
579
|
-
...props
|
|
580
|
-
}
|
|
581
|
-
);
|
|
582
|
-
}
|
|
583
|
-
function DialogContent({ className, ...props }) {
|
|
584
|
-
return /* @__PURE__ */ jsxs(DialogPortal, { children: [
|
|
585
|
-
/* @__PURE__ */ jsx(DialogOverlay, {}),
|
|
586
|
-
/* @__PURE__ */ jsx(
|
|
587
|
-
Dialog$1.Popup,
|
|
588
|
-
{
|
|
589
|
-
"data-slot": "dialog-content",
|
|
590
|
-
className: cn(
|
|
591
|
-
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 sm:rounded-lg outline-none",
|
|
592
|
-
className
|
|
593
|
-
),
|
|
594
|
-
...props
|
|
595
|
-
}
|
|
596
|
-
)
|
|
597
|
-
] });
|
|
598
|
-
}
|
|
599
|
-
function DialogClose({ className, ...props }) {
|
|
600
|
-
return /* @__PURE__ */ jsx(
|
|
601
|
-
Dialog$1.Close,
|
|
602
|
-
{
|
|
603
|
-
"data-slot": "dialog-close",
|
|
604
|
-
className: cn(
|
|
605
|
-
"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",
|
|
606
|
-
className
|
|
607
|
-
),
|
|
608
|
-
...props
|
|
609
|
-
}
|
|
610
|
-
);
|
|
611
|
-
}
|
|
612
|
-
var Icon = (props) => {
|
|
613
|
-
const {
|
|
614
|
-
name,
|
|
615
|
-
size = "md",
|
|
616
|
-
color,
|
|
617
|
-
className
|
|
618
|
-
} = props;
|
|
619
|
-
const sizeMap = {
|
|
620
|
-
sm: "14px",
|
|
621
|
-
md: "18px",
|
|
622
|
-
lg: "24px"
|
|
623
|
-
};
|
|
624
|
-
const resolvedSize = typeof size === "number" ? `${size}px` : sizeMap[size] || "18px";
|
|
625
|
-
const LucideIcon = LucideIcons[name];
|
|
626
430
|
return /* @__PURE__ */ jsx(
|
|
627
431
|
"div",
|
|
628
432
|
{
|
|
629
433
|
className: cn(
|
|
630
|
-
"
|
|
631
|
-
|
|
632
|
-
|
|
434
|
+
"overflow-hidden",
|
|
435
|
+
typeof width === "string" && widthMap[width],
|
|
436
|
+
radiusMap[radius]
|
|
633
437
|
),
|
|
634
438
|
style: {
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
height: resolvedSize,
|
|
638
|
-
display: "inline-flex",
|
|
639
|
-
alignItems: "center",
|
|
640
|
-
justifyContent: "center"
|
|
439
|
+
width: typeof width === "number" ? `${width}px` : void 0,
|
|
440
|
+
height: typeof height === "number" ? `${height}px` : height
|
|
641
441
|
},
|
|
642
|
-
children:
|
|
442
|
+
children: /* @__PURE__ */ jsx(
|
|
443
|
+
"img",
|
|
444
|
+
{
|
|
445
|
+
src,
|
|
446
|
+
alt,
|
|
447
|
+
className: cn(
|
|
448
|
+
"block w-full",
|
|
449
|
+
height ? "h-full" : "h-auto",
|
|
450
|
+
objectFit === "cover" ? "object-cover" : objectFit === "contain" ? "object-contain" : "object-fill"
|
|
451
|
+
)
|
|
452
|
+
}
|
|
453
|
+
)
|
|
643
454
|
}
|
|
644
455
|
);
|
|
645
456
|
};
|
|
646
|
-
var Image = ({
|
|
647
|
-
src,
|
|
648
|
-
alt,
|
|
649
|
-
width = "auto",
|
|
650
|
-
height,
|
|
651
|
-
radius = "md",
|
|
652
|
-
objectFit = "cover"
|
|
653
|
-
}) => {
|
|
654
|
-
const [hasError, setHasError] = useState(false);
|
|
655
|
-
const [isLoading, setIsLoading] = useState(true);
|
|
656
|
-
const [open, setOpen] = useState(false);
|
|
657
|
-
const [currentIndex, setCurrentIndex] = useState(0);
|
|
658
|
-
const [gallery, setGallery] = useState([]);
|
|
659
|
-
const triggerRef = useRef(null);
|
|
660
|
-
useEffect(() => {
|
|
661
|
-
if (open && triggerRef.current) {
|
|
662
|
-
let parent = triggerRef.current.parentElement;
|
|
663
|
-
while (parent && parent.parentElement && parent.parentElement.children.length === 1) {
|
|
664
|
-
parent = parent.parentElement;
|
|
665
|
-
}
|
|
666
|
-
const container = parent?.parentElement;
|
|
667
|
-
if (container) {
|
|
668
|
-
const foundImgs = Array.from(container.querySelectorAll("img")).map((img) => ({
|
|
669
|
-
src: img.getAttribute("src") || "",
|
|
670
|
-
alt: img.getAttribute("alt") || ""
|
|
671
|
-
})).filter((v, i, a) => a.findIndex((t) => t.src === v.src) === i);
|
|
672
|
-
setGallery(foundImgs);
|
|
673
|
-
const idx = foundImgs.findIndex((img) => img.src === src);
|
|
674
|
-
setCurrentIndex(idx >= 0 ? idx : 0);
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
}, [open, src]);
|
|
678
|
-
const navigate = (dir) => {
|
|
679
|
-
setCurrentIndex((prev) => (prev + dir + gallery.length) % gallery.length);
|
|
680
|
-
};
|
|
681
|
-
const currentImage = gallery[currentIndex] || { src, alt };
|
|
682
|
-
const hasMultiple = gallery.length > 1;
|
|
683
|
-
const handleError = () => {
|
|
684
|
-
setHasError(true);
|
|
685
|
-
setIsLoading(false);
|
|
686
|
-
};
|
|
687
|
-
const handleLoad = () => {
|
|
688
|
-
setIsLoading(false);
|
|
689
|
-
};
|
|
690
|
-
if (hasError) {
|
|
691
|
-
return /* @__PURE__ */ jsx(
|
|
692
|
-
"div",
|
|
693
|
-
{
|
|
694
|
-
className: cn(
|
|
695
|
-
"flex items-center justify-center bg-muted text-muted-foreground",
|
|
696
|
-
widthMap[width],
|
|
697
|
-
radiusMap[radius]
|
|
698
|
-
),
|
|
699
|
-
style: { height: height || "100px" },
|
|
700
|
-
children: /* @__PURE__ */ jsx("span", { className: "text-[10px]", children: "Error" })
|
|
701
|
-
}
|
|
702
|
-
);
|
|
703
|
-
}
|
|
704
|
-
return /* @__PURE__ */ jsxs(Dialog, { open, onOpenChange: setOpen, children: [
|
|
705
|
-
/* @__PURE__ */ jsx(DialogTrigger, { children: /* @__PURE__ */ jsxs(
|
|
706
|
-
"div",
|
|
707
|
-
{
|
|
708
|
-
ref: triggerRef,
|
|
709
|
-
className: cn(
|
|
710
|
-
"relative overflow-hidden cursor-pointer",
|
|
711
|
-
widthMap[width],
|
|
712
|
-
radiusMap[radius]
|
|
713
|
-
),
|
|
714
|
-
style: { height },
|
|
715
|
-
children: [
|
|
716
|
-
/* @__PURE__ */ jsx(
|
|
717
|
-
"img",
|
|
718
|
-
{
|
|
719
|
-
src,
|
|
720
|
-
alt,
|
|
721
|
-
onError: handleError,
|
|
722
|
-
onLoad: handleLoad,
|
|
723
|
-
className: cn(
|
|
724
|
-
"block w-full transition-opacity duration-200 hover:opacity-90",
|
|
725
|
-
isLoading ? "opacity-0" : "opacity-100",
|
|
726
|
-
objectFit === "cover" ? "object-cover" : objectFit === "contain" ? "object-contain" : "object-fill",
|
|
727
|
-
height ? "h-full" : "h-auto"
|
|
728
|
-
)
|
|
729
|
-
}
|
|
730
|
-
),
|
|
731
|
-
isLoading && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-muted animate-pulse" })
|
|
732
|
-
]
|
|
733
|
-
}
|
|
734
|
-
) }),
|
|
735
|
-
/* @__PURE__ */ jsx(
|
|
736
|
-
DialogContent,
|
|
737
|
-
{
|
|
738
|
-
className: "max-w-[90vw] max-h-[90vh] p-0 bg-transparent border-none shadow-none outline-none",
|
|
739
|
-
onClick: (e) => e.stopPropagation(),
|
|
740
|
-
children: /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center group/lightbox", children: [
|
|
741
|
-
/* @__PURE__ */ jsx(DialogClose, { className: "absolute -top-12 right-0 text-white hover:text-gray-300 transition-colors z-50 bg-black/50 rounded-full p-2", children: /* @__PURE__ */ jsx(Icon, { name: "\u274C", size: 20 }) }),
|
|
742
|
-
hasMultiple && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
743
|
-
/* @__PURE__ */ jsx(
|
|
744
|
-
"button",
|
|
745
|
-
{
|
|
746
|
-
onClick: (e) => {
|
|
747
|
-
e.stopPropagation();
|
|
748
|
-
navigate(-1);
|
|
749
|
-
},
|
|
750
|
-
className: "absolute left-4 z-50 p-3 bg-black/40 hover:bg-black/60 text-white rounded-full transition-all opacity-0 group-hover/lightbox:opacity-100",
|
|
751
|
-
children: /* @__PURE__ */ jsx(Icon, { name: "\u25C0\uFE0F", size: 28 })
|
|
752
|
-
}
|
|
753
|
-
),
|
|
754
|
-
/* @__PURE__ */ jsx(
|
|
755
|
-
"button",
|
|
756
|
-
{
|
|
757
|
-
onClick: (e) => {
|
|
758
|
-
e.stopPropagation();
|
|
759
|
-
navigate(1);
|
|
760
|
-
},
|
|
761
|
-
className: "absolute right-4 z-50 p-3 bg-black/40 hover:bg-black/60 text-white rounded-full transition-all opacity-0 group-hover/lightbox:opacity-100",
|
|
762
|
-
children: /* @__PURE__ */ jsx(Icon, { name: "\u25B6\uFE0F", size: 28 })
|
|
763
|
-
}
|
|
764
|
-
)
|
|
765
|
-
] }),
|
|
766
|
-
/* @__PURE__ */ jsx(
|
|
767
|
-
"img",
|
|
768
|
-
{
|
|
769
|
-
src: currentImage.src,
|
|
770
|
-
alt: currentImage.alt || alt || "Enlarged image",
|
|
771
|
-
className: "max-w-full max-h-[85vh] object-contain rounded-lg shadow-2xl"
|
|
772
|
-
}
|
|
773
|
-
),
|
|
774
|
-
hasMultiple && /* @__PURE__ */ jsxs("div", { className: "absolute -bottom-10 left-1/2 -translate-x-1/2 text-white bg-black/50 px-3 py-1 rounded-full text-sm font-medium", children: [
|
|
775
|
-
currentIndex + 1,
|
|
776
|
-
" / ",
|
|
777
|
-
gallery.length
|
|
778
|
-
] })
|
|
779
|
-
] })
|
|
780
|
-
}
|
|
781
|
-
)
|
|
782
|
-
] });
|
|
783
|
-
};
|
|
784
457
|
var Video = ({
|
|
785
458
|
src,
|
|
786
459
|
poster,
|
|
@@ -825,7 +498,41 @@ var Video = ({
|
|
|
825
498
|
}
|
|
826
499
|
);
|
|
827
500
|
};
|
|
828
|
-
var
|
|
501
|
+
var Icon = (props) => {
|
|
502
|
+
const {
|
|
503
|
+
name,
|
|
504
|
+
size = "md",
|
|
505
|
+
color,
|
|
506
|
+
className
|
|
507
|
+
} = props;
|
|
508
|
+
const sizeMap = {
|
|
509
|
+
sm: "14px",
|
|
510
|
+
md: "18px",
|
|
511
|
+
lg: "24px"
|
|
512
|
+
};
|
|
513
|
+
const resolvedSize = typeof size === "number" ? `${size}px` : sizeMap[size] || "18px";
|
|
514
|
+
const LucideIcon = LucideIcons[name];
|
|
515
|
+
return /* @__PURE__ */ jsx(
|
|
516
|
+
"div",
|
|
517
|
+
{
|
|
518
|
+
className: cn(
|
|
519
|
+
"inline-flex items-center justify-center leading-none",
|
|
520
|
+
color && colorTextMap[color],
|
|
521
|
+
className
|
|
522
|
+
),
|
|
523
|
+
style: {
|
|
524
|
+
fontSize: resolvedSize,
|
|
525
|
+
width: resolvedSize,
|
|
526
|
+
height: resolvedSize,
|
|
527
|
+
display: "inline-flex",
|
|
528
|
+
alignItems: "center",
|
|
529
|
+
justifyContent: "center"
|
|
530
|
+
},
|
|
531
|
+
children: LucideIcon ? /* @__PURE__ */ jsx(LucideIcon, { size: resolvedSize }) : name
|
|
532
|
+
}
|
|
533
|
+
);
|
|
534
|
+
};
|
|
535
|
+
cva(
|
|
829
536
|
"h-5 gap-1 rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium transition-all has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-3! inline-flex items-center justify-center w-fit whitespace-nowrap shrink-0 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-colors overflow-hidden group/badge",
|
|
830
537
|
{
|
|
831
538
|
variants: {
|
|
@@ -843,273 +550,6 @@ var badgeVariants = cva(
|
|
|
843
550
|
}
|
|
844
551
|
}
|
|
845
552
|
);
|
|
846
|
-
function Badge({
|
|
847
|
-
className,
|
|
848
|
-
variant = "default",
|
|
849
|
-
render,
|
|
850
|
-
...props
|
|
851
|
-
}) {
|
|
852
|
-
return useRender({
|
|
853
|
-
defaultTagName: "span",
|
|
854
|
-
props: mergeProps(
|
|
855
|
-
{
|
|
856
|
-
className: cn(badgeVariants({ className, variant }))
|
|
857
|
-
},
|
|
858
|
-
props
|
|
859
|
-
),
|
|
860
|
-
render,
|
|
861
|
-
state: {
|
|
862
|
-
slot: "badge",
|
|
863
|
-
variant
|
|
864
|
-
}
|
|
865
|
-
});
|
|
866
|
-
}
|
|
867
|
-
var Badge2 = ({
|
|
868
|
-
label,
|
|
869
|
-
variant = "primary",
|
|
870
|
-
size = "md"
|
|
871
|
-
}) => {
|
|
872
|
-
const variantMap = {
|
|
873
|
-
primary: "default",
|
|
874
|
-
secondary: "secondary",
|
|
875
|
-
danger: "destructive",
|
|
876
|
-
success: "default",
|
|
877
|
-
warning: "secondary",
|
|
878
|
-
outline: "outline"
|
|
879
|
-
};
|
|
880
|
-
const sizeClasses = {
|
|
881
|
-
sm: "text-[10px] px-1.5 py-0",
|
|
882
|
-
md: "text-xs px-2.5 py-0.5",
|
|
883
|
-
lg: "text-sm px-3 py-1"
|
|
884
|
-
};
|
|
885
|
-
return /* @__PURE__ */ jsx(
|
|
886
|
-
Badge,
|
|
887
|
-
{
|
|
888
|
-
variant: variantMap[variant] || "default",
|
|
889
|
-
className: sizeClasses[size],
|
|
890
|
-
children: label
|
|
891
|
-
}
|
|
892
|
-
);
|
|
893
|
-
};
|
|
894
|
-
var Chart = ({
|
|
895
|
-
data,
|
|
896
|
-
chartType = "bar",
|
|
897
|
-
title,
|
|
898
|
-
height = 250,
|
|
899
|
-
showValues = false,
|
|
900
|
-
showGrid = false,
|
|
901
|
-
showTooltips = true
|
|
902
|
-
}) => {
|
|
903
|
-
const [tooltip, setTooltip] = useState(null);
|
|
904
|
-
if (!Array.isArray(data)) {
|
|
905
|
-
return /* @__PURE__ */ jsx("div", { className: "p-4 text-destructive border border-destructive/20 rounded-md bg-destructive/5 text-sm", children: "Error: Chart data must be an array" });
|
|
906
|
-
}
|
|
907
|
-
const maxValue = Math.max(...data.map((d) => d.value), 1);
|
|
908
|
-
const padding = { top: 40, right: 20, bottom: 40, left: 20 };
|
|
909
|
-
const chartHeight = height;
|
|
910
|
-
const chartWidth = 600;
|
|
911
|
-
const defaultColors = [
|
|
912
|
-
"hsl(var(--primary))",
|
|
913
|
-
"hsl(var(--chart-1, 217 91% 60%))",
|
|
914
|
-
"hsl(var(--chart-2, 142 71% 45%))",
|
|
915
|
-
"hsl(var(--chart-3, 31 92% 55%))",
|
|
916
|
-
"hsl(var(--chart-4, 346 84% 61%))",
|
|
917
|
-
"hsl(var(--chart-5, 271 81% 56%))"
|
|
918
|
-
];
|
|
919
|
-
const getColor = (index, color) => {
|
|
920
|
-
if (color) return color;
|
|
921
|
-
return defaultColors[index % defaultColors.length];
|
|
922
|
-
};
|
|
923
|
-
const renderGrid = () => {
|
|
924
|
-
if (!showGrid) return null;
|
|
925
|
-
return [0, 0.25, 0.5, 0.75, 1].map((fraction, i) => /* @__PURE__ */ jsx(
|
|
926
|
-
"line",
|
|
927
|
-
{
|
|
928
|
-
x1: padding.left,
|
|
929
|
-
y1: padding.top + chartHeight * (1 - fraction),
|
|
930
|
-
x2: chartWidth - padding.right,
|
|
931
|
-
y2: padding.top + chartHeight * (1 - fraction),
|
|
932
|
-
stroke: "currentColor",
|
|
933
|
-
className: "text-border",
|
|
934
|
-
strokeDasharray: "4,4",
|
|
935
|
-
strokeOpacity: 0.5
|
|
936
|
-
},
|
|
937
|
-
i
|
|
938
|
-
));
|
|
939
|
-
};
|
|
940
|
-
const renderTooltip = () => {
|
|
941
|
-
if (!tooltip || !tooltip.visible) return null;
|
|
942
|
-
return /* @__PURE__ */ jsxs("g", { className: "pointer-events-none", children: [
|
|
943
|
-
/* @__PURE__ */ jsx(
|
|
944
|
-
"rect",
|
|
945
|
-
{
|
|
946
|
-
x: tooltip.x - 40,
|
|
947
|
-
y: tooltip.y - 45,
|
|
948
|
-
width: 80,
|
|
949
|
-
height: 40,
|
|
950
|
-
fill: "hsl(var(--popover))",
|
|
951
|
-
stroke: "hsl(var(--border))",
|
|
952
|
-
strokeWidth: 1,
|
|
953
|
-
rx: 6,
|
|
954
|
-
className: "shadow-md"
|
|
955
|
-
}
|
|
956
|
-
),
|
|
957
|
-
/* @__PURE__ */ jsx(
|
|
958
|
-
"text",
|
|
959
|
-
{
|
|
960
|
-
x: tooltip.x,
|
|
961
|
-
y: tooltip.y - 28,
|
|
962
|
-
textAnchor: "middle",
|
|
963
|
-
className: "fill-popover-foreground text-[10px] font-semibold",
|
|
964
|
-
children: tooltip.value
|
|
965
|
-
}
|
|
966
|
-
),
|
|
967
|
-
/* @__PURE__ */ jsx(
|
|
968
|
-
"text",
|
|
969
|
-
{
|
|
970
|
-
x: tooltip.x,
|
|
971
|
-
y: tooltip.y - 14,
|
|
972
|
-
textAnchor: "middle",
|
|
973
|
-
className: "fill-muted-foreground text-[9px]",
|
|
974
|
-
children: tooltip.label
|
|
975
|
-
}
|
|
976
|
-
)
|
|
977
|
-
] });
|
|
978
|
-
};
|
|
979
|
-
const renderBarChart = () => {
|
|
980
|
-
const totalBarSpace = chartWidth - padding.left - padding.right;
|
|
981
|
-
const barSpacing = data.length > 1 ? totalBarSpace * 0.1 / data.length : 0;
|
|
982
|
-
const actualBarWidth = (totalBarSpace - barSpacing * (data.length + 1)) / data.length;
|
|
983
|
-
return /* @__PURE__ */ jsxs(
|
|
984
|
-
"svg",
|
|
985
|
-
{
|
|
986
|
-
viewBox: `0 0 ${chartWidth} ${chartHeight + padding.bottom}`,
|
|
987
|
-
className: "w-full h-auto overflow-visible",
|
|
988
|
-
children: [
|
|
989
|
-
renderGrid(),
|
|
990
|
-
data.map((item, index) => {
|
|
991
|
-
const barHeight = item.value / maxValue * chartHeight;
|
|
992
|
-
const x = padding.left + barSpacing + index * (actualBarWidth + barSpacing);
|
|
993
|
-
const y = padding.top + chartHeight - barHeight;
|
|
994
|
-
return /* @__PURE__ */ jsxs("g", { children: [
|
|
995
|
-
/* @__PURE__ */ jsx(
|
|
996
|
-
"rect",
|
|
997
|
-
{
|
|
998
|
-
x,
|
|
999
|
-
y,
|
|
1000
|
-
width: actualBarWidth,
|
|
1001
|
-
height: barHeight,
|
|
1002
|
-
fill: getColor(index, item.color),
|
|
1003
|
-
rx: 4,
|
|
1004
|
-
onMouseEnter: () => showTooltips && setTooltip({
|
|
1005
|
-
visible: true,
|
|
1006
|
-
x: x + actualBarWidth / 2,
|
|
1007
|
-
y: y - 5,
|
|
1008
|
-
label: item.label,
|
|
1009
|
-
value: item.value
|
|
1010
|
-
}),
|
|
1011
|
-
onMouseLeave: () => setTooltip({
|
|
1012
|
-
visible: false,
|
|
1013
|
-
x: 0,
|
|
1014
|
-
y: 0,
|
|
1015
|
-
label: "",
|
|
1016
|
-
value: 0
|
|
1017
|
-
}),
|
|
1018
|
-
className: "transition-all hover:opacity-80 cursor-pointer"
|
|
1019
|
-
}
|
|
1020
|
-
),
|
|
1021
|
-
/* @__PURE__ */ jsx(
|
|
1022
|
-
"text",
|
|
1023
|
-
{
|
|
1024
|
-
x: x + actualBarWidth / 2,
|
|
1025
|
-
y: padding.top + chartHeight + 20,
|
|
1026
|
-
textAnchor: "middle",
|
|
1027
|
-
className: "fill-muted-foreground text-[10px]",
|
|
1028
|
-
children: item.label
|
|
1029
|
-
}
|
|
1030
|
-
)
|
|
1031
|
-
] }, index);
|
|
1032
|
-
}),
|
|
1033
|
-
showTooltips && renderTooltip()
|
|
1034
|
-
]
|
|
1035
|
-
}
|
|
1036
|
-
);
|
|
1037
|
-
};
|
|
1038
|
-
const renderLineChart = () => {
|
|
1039
|
-
const points = data.map((item, index) => ({
|
|
1040
|
-
x: padding.left + index / Math.max(data.length - 1, 1) * (chartWidth - padding.left - padding.right),
|
|
1041
|
-
y: padding.top + chartHeight - item.value / maxValue * chartHeight,
|
|
1042
|
-
...item
|
|
1043
|
-
}));
|
|
1044
|
-
const pathData = points.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");
|
|
1045
|
-
return /* @__PURE__ */ jsxs(
|
|
1046
|
-
"svg",
|
|
1047
|
-
{
|
|
1048
|
-
viewBox: `0 0 ${chartWidth} ${chartHeight + padding.bottom}`,
|
|
1049
|
-
className: "w-full h-auto overflow-visible",
|
|
1050
|
-
children: [
|
|
1051
|
-
renderGrid(),
|
|
1052
|
-
/* @__PURE__ */ jsx(
|
|
1053
|
-
"path",
|
|
1054
|
-
{
|
|
1055
|
-
d: pathData,
|
|
1056
|
-
fill: "none",
|
|
1057
|
-
stroke: getColor(0),
|
|
1058
|
-
strokeWidth: 3,
|
|
1059
|
-
className: "transition-all"
|
|
1060
|
-
}
|
|
1061
|
-
),
|
|
1062
|
-
points.map((point, index) => /* @__PURE__ */ jsxs("g", { children: [
|
|
1063
|
-
/* @__PURE__ */ jsx(
|
|
1064
|
-
"circle",
|
|
1065
|
-
{
|
|
1066
|
-
cx: point.x,
|
|
1067
|
-
cy: point.y,
|
|
1068
|
-
r: 5,
|
|
1069
|
-
fill: getColor(index, point.color),
|
|
1070
|
-
stroke: "hsl(var(--background))",
|
|
1071
|
-
strokeWidth: 2,
|
|
1072
|
-
onMouseEnter: () => showTooltips && setTooltip({
|
|
1073
|
-
visible: true,
|
|
1074
|
-
x: point.x,
|
|
1075
|
-
y: point.y - 5,
|
|
1076
|
-
label: point.label,
|
|
1077
|
-
value: point.value
|
|
1078
|
-
}),
|
|
1079
|
-
onMouseLeave: () => setTooltip({ visible: false, x: 0, y: 0, label: "", value: 0 }),
|
|
1080
|
-
className: "hover:r-6 transition-all cursor-pointer"
|
|
1081
|
-
}
|
|
1082
|
-
),
|
|
1083
|
-
/* @__PURE__ */ jsx(
|
|
1084
|
-
"text",
|
|
1085
|
-
{
|
|
1086
|
-
x: point.x,
|
|
1087
|
-
y: padding.top + chartHeight + 20,
|
|
1088
|
-
textAnchor: "middle",
|
|
1089
|
-
className: "fill-muted-foreground text-[10px]",
|
|
1090
|
-
children: point.label
|
|
1091
|
-
}
|
|
1092
|
-
)
|
|
1093
|
-
] }, index)),
|
|
1094
|
-
showTooltips && renderTooltip()
|
|
1095
|
-
]
|
|
1096
|
-
}
|
|
1097
|
-
);
|
|
1098
|
-
};
|
|
1099
|
-
const renderChart = () => {
|
|
1100
|
-
switch (chartType) {
|
|
1101
|
-
case "line":
|
|
1102
|
-
return renderLineChart();
|
|
1103
|
-
case "bar":
|
|
1104
|
-
default:
|
|
1105
|
-
return renderBarChart();
|
|
1106
|
-
}
|
|
1107
|
-
};
|
|
1108
|
-
return /* @__PURE__ */ jsxs("div", { className: "py-4 w-full", children: [
|
|
1109
|
-
title && /* @__PURE__ */ jsx("div", { className: "text-sm font-semibold mb-4 text-center", children: title }),
|
|
1110
|
-
renderChart()
|
|
1111
|
-
] });
|
|
1112
|
-
};
|
|
1113
553
|
var Text = (props) => {
|
|
1114
554
|
const {
|
|
1115
555
|
value,
|
|
@@ -1580,11 +1020,11 @@ var Checkbox = ({
|
|
|
1580
1020
|
var Hidden = ({ name, value }) => {
|
|
1581
1021
|
return /* @__PURE__ */ jsx("input", { type: "hidden", name, value });
|
|
1582
1022
|
};
|
|
1583
|
-
var PopoverContext =
|
|
1023
|
+
var PopoverContext = React2.createContext(
|
|
1584
1024
|
void 0
|
|
1585
1025
|
);
|
|
1586
1026
|
function usePopoverContext() {
|
|
1587
|
-
const context =
|
|
1027
|
+
const context = React2.useContext(PopoverContext);
|
|
1588
1028
|
if (!context) {
|
|
1589
1029
|
throw new Error("Popover components must be used within a Popover");
|
|
1590
1030
|
}
|
|
@@ -1596,10 +1036,10 @@ function Popover({
|
|
|
1596
1036
|
open: controlledOpen,
|
|
1597
1037
|
onOpenChange
|
|
1598
1038
|
}) {
|
|
1599
|
-
const [internalOpen, setInternalOpen] =
|
|
1600
|
-
const triggerRef =
|
|
1039
|
+
const [internalOpen, setInternalOpen] = React2.useState(defaultOpen);
|
|
1040
|
+
const triggerRef = React2.useRef(null);
|
|
1601
1041
|
const open = controlledOpen ?? internalOpen;
|
|
1602
|
-
const setOpen =
|
|
1042
|
+
const setOpen = React2.useCallback(
|
|
1603
1043
|
(newOpen) => {
|
|
1604
1044
|
if (controlledOpen === void 0) {
|
|
1605
1045
|
setInternalOpen(newOpen);
|
|
@@ -1608,7 +1048,7 @@ function Popover({
|
|
|
1608
1048
|
},
|
|
1609
1049
|
[controlledOpen, onOpenChange]
|
|
1610
1050
|
);
|
|
1611
|
-
const value =
|
|
1051
|
+
const value = React2.useMemo(
|
|
1612
1052
|
() => ({
|
|
1613
1053
|
open,
|
|
1614
1054
|
setOpen,
|
|
@@ -1618,15 +1058,15 @@ function Popover({
|
|
|
1618
1058
|
);
|
|
1619
1059
|
return /* @__PURE__ */ jsx(PopoverContext.Provider, { value, children });
|
|
1620
1060
|
}
|
|
1621
|
-
var PopoverTrigger =
|
|
1061
|
+
var PopoverTrigger = React2.forwardRef(
|
|
1622
1062
|
({ asChild, className, children, ...props }, ref) => {
|
|
1623
1063
|
const { setOpen, triggerRef } = usePopoverContext();
|
|
1624
1064
|
const handleClick = (e) => {
|
|
1625
1065
|
setOpen(true);
|
|
1626
1066
|
props.onClick?.(e);
|
|
1627
1067
|
};
|
|
1628
|
-
if (asChild &&
|
|
1629
|
-
return
|
|
1068
|
+
if (asChild && React2.isValidElement(children)) {
|
|
1069
|
+
return React2.cloneElement(children, {
|
|
1630
1070
|
ref: (node) => {
|
|
1631
1071
|
triggerRef.current = node;
|
|
1632
1072
|
if (typeof children.ref === "function") {
|
|
@@ -1658,7 +1098,7 @@ var PopoverTrigger = React3.forwardRef(
|
|
|
1658
1098
|
}
|
|
1659
1099
|
);
|
|
1660
1100
|
PopoverTrigger.displayName = "PopoverTrigger";
|
|
1661
|
-
var PopoverContent =
|
|
1101
|
+
var PopoverContent = React2.forwardRef(
|
|
1662
1102
|
({
|
|
1663
1103
|
className,
|
|
1664
1104
|
side = "bottom",
|
|
@@ -1669,9 +1109,9 @@ var PopoverContent = React3.forwardRef(
|
|
|
1669
1109
|
...props
|
|
1670
1110
|
}, ref) => {
|
|
1671
1111
|
const { open, setOpen, triggerRef } = usePopoverContext();
|
|
1672
|
-
const [position, setPosition] =
|
|
1673
|
-
const contentRef =
|
|
1674
|
-
|
|
1112
|
+
const [position, setPosition] = React2.useState({ top: 0, left: 0 });
|
|
1113
|
+
const contentRef = React2.useRef(null);
|
|
1114
|
+
React2.useEffect(() => {
|
|
1675
1115
|
if (!open || !triggerRef.current) return;
|
|
1676
1116
|
const updatePosition = () => {
|
|
1677
1117
|
if (!triggerRef.current || !contentRef.current) return;
|
|
@@ -1732,7 +1172,7 @@ var PopoverContent = React3.forwardRef(
|
|
|
1732
1172
|
window.removeEventListener("scroll", updatePosition, true);
|
|
1733
1173
|
};
|
|
1734
1174
|
}, [open, side, align, sideOffset, alignOffset, triggerRef]);
|
|
1735
|
-
|
|
1175
|
+
React2.useEffect(() => {
|
|
1736
1176
|
if (!open) return;
|
|
1737
1177
|
const handleClickOutside = (event) => {
|
|
1738
1178
|
if (contentRef.current && !contentRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
|
|
@@ -2191,287 +1631,6 @@ var Form = ({ children, onSubmitAction, gap = "md" }) => {
|
|
|
2191
1631
|
}
|
|
2192
1632
|
) }) });
|
|
2193
1633
|
};
|
|
2194
|
-
function DropdownMenu({ ...props }) {
|
|
2195
|
-
return /* @__PURE__ */ jsx(Menu.Root, { "data-slot": "dropdown-menu", ...props });
|
|
2196
|
-
}
|
|
2197
|
-
function DropdownMenuTrigger({ ...props }) {
|
|
2198
|
-
return /* @__PURE__ */ jsx(Menu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
2199
|
-
}
|
|
2200
|
-
function DropdownMenuContent({
|
|
2201
|
-
align = "start",
|
|
2202
|
-
alignOffset = 0,
|
|
2203
|
-
side = "bottom",
|
|
2204
|
-
sideOffset = 4,
|
|
2205
|
-
className,
|
|
2206
|
-
...props
|
|
2207
|
-
}) {
|
|
2208
|
-
return /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(
|
|
2209
|
-
Menu.Positioner,
|
|
2210
|
-
{
|
|
2211
|
-
className: "isolate z-50 outline-none",
|
|
2212
|
-
align,
|
|
2213
|
-
alignOffset,
|
|
2214
|
-
side,
|
|
2215
|
-
sideOffset,
|
|
2216
|
-
children: /* @__PURE__ */ jsx(
|
|
2217
|
-
Menu.Popup,
|
|
2218
|
-
{
|
|
2219
|
-
"data-slot": "dropdown-menu-content",
|
|
2220
|
-
className: cn(
|
|
2221
|
-
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/5 bg-popover text-popover-foreground min-w-48 rounded-2xl p-1 shadow-2xl ring-1 duration-100 z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto outline-none data-closed:overflow-hidden",
|
|
2222
|
-
className
|
|
2223
|
-
),
|
|
2224
|
-
...props
|
|
2225
|
-
}
|
|
2226
|
-
)
|
|
2227
|
-
}
|
|
2228
|
-
) });
|
|
2229
|
-
}
|
|
2230
|
-
function DropdownMenuItem({
|
|
2231
|
-
className,
|
|
2232
|
-
inset,
|
|
2233
|
-
variant = "default",
|
|
2234
|
-
...props
|
|
2235
|
-
}) {
|
|
2236
|
-
return /* @__PURE__ */ jsx(
|
|
2237
|
-
Menu.Item,
|
|
2238
|
-
{
|
|
2239
|
-
"data-slot": "dropdown-menu-item",
|
|
2240
|
-
"data-inset": inset,
|
|
2241
|
-
"data-variant": variant,
|
|
2242
|
-
className: cn(
|
|
2243
|
-
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2.5 rounded-xl px-3 py-2 text-sm [&_svg:not([class*='size-'])]:size-4 group/dropdown-menu-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
2244
|
-
className
|
|
2245
|
-
),
|
|
2246
|
-
...props
|
|
2247
|
-
}
|
|
2248
|
-
);
|
|
2249
|
-
}
|
|
2250
|
-
var Dropdown = ({ items = [], children }) => {
|
|
2251
|
-
const { send } = useMelony();
|
|
2252
|
-
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
2253
|
-
/* @__PURE__ */ jsx(
|
|
2254
|
-
DropdownMenuTrigger,
|
|
2255
|
-
{
|
|
2256
|
-
render: (props) => /* @__PURE__ */ jsx(
|
|
2257
|
-
Button,
|
|
2258
|
-
{
|
|
2259
|
-
variant: "outline",
|
|
2260
|
-
size: "icon-sm",
|
|
2261
|
-
...props,
|
|
2262
|
-
onClick: (e) => {
|
|
2263
|
-
e.stopPropagation();
|
|
2264
|
-
props.onClick?.(e);
|
|
2265
|
-
},
|
|
2266
|
-
children: children || /* @__PURE__ */ jsx(Icon, { name: "\u22EE", size: "sm" })
|
|
2267
|
-
}
|
|
2268
|
-
)
|
|
2269
|
-
}
|
|
2270
|
-
),
|
|
2271
|
-
/* @__PURE__ */ jsx(DropdownMenuContent, { align: "start", className: cn("w-32"), children: items.map((item, i) => /* @__PURE__ */ jsxs(
|
|
2272
|
-
DropdownMenuItem,
|
|
2273
|
-
{
|
|
2274
|
-
onClick: (e) => {
|
|
2275
|
-
e.stopPropagation();
|
|
2276
|
-
if (item.onClickAction) {
|
|
2277
|
-
send(item.onClickAction);
|
|
2278
|
-
}
|
|
2279
|
-
},
|
|
2280
|
-
children: [
|
|
2281
|
-
item.icon && /* @__PURE__ */ jsx(Icon, { name: item.icon, size: "sm" }),
|
|
2282
|
-
/* @__PURE__ */ jsx("span", { className: item.icon ? "ml-2" : "", children: item.label })
|
|
2283
|
-
]
|
|
2284
|
-
},
|
|
2285
|
-
`${item.label}-${i}`
|
|
2286
|
-
)) })
|
|
2287
|
-
] });
|
|
2288
|
-
};
|
|
2289
|
-
function Composer({
|
|
2290
|
-
value,
|
|
2291
|
-
onChange,
|
|
2292
|
-
onSubmit,
|
|
2293
|
-
onStop,
|
|
2294
|
-
placeholder = "Type a message...",
|
|
2295
|
-
streaming,
|
|
2296
|
-
className,
|
|
2297
|
-
autoFocus = false
|
|
2298
|
-
}) {
|
|
2299
|
-
const handleKeyDown = (e) => {
|
|
2300
|
-
if (e.key === "Enter" && !e.shiftKey) {
|
|
2301
|
-
e.preventDefault();
|
|
2302
|
-
onSubmit();
|
|
2303
|
-
}
|
|
2304
|
-
};
|
|
2305
|
-
return /* @__PURE__ */ jsx("div", { className: cn("relative flex flex-col w-full", className), children: /* @__PURE__ */ jsxs("div", { className: "relative flex flex-col w-full border-border/60 border rounded-[26px] bg-muted/30 focus-within:bg-background focus-within:border-border focus-within:ring-[3px] focus-within:ring-primary/5 transition-all p-1.5 px-2", children: [
|
|
2306
|
-
/* @__PURE__ */ jsx(
|
|
2307
|
-
Textarea,
|
|
2308
|
-
{
|
|
2309
|
-
value,
|
|
2310
|
-
onChange: (e) => onChange(e.target.value),
|
|
2311
|
-
onKeyDown: handleKeyDown,
|
|
2312
|
-
placeholder,
|
|
2313
|
-
className: "min-h-[44px] max-h-[200px] border-none bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 px-3 py-2 text-[15px] resize-none leading-relaxed",
|
|
2314
|
-
autoFocus
|
|
2315
|
-
}
|
|
2316
|
-
),
|
|
2317
|
-
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center pb-1", children: [
|
|
2318
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1 px-2" }),
|
|
2319
|
-
streaming ? /* @__PURE__ */ jsx(
|
|
2320
|
-
Button,
|
|
2321
|
-
{
|
|
2322
|
-
type: "button",
|
|
2323
|
-
variant: "ghost",
|
|
2324
|
-
size: "icon",
|
|
2325
|
-
className: "h-8 w-8 rounded-full border border-border/40 hover:bg-muted",
|
|
2326
|
-
onClick: () => onStop?.(),
|
|
2327
|
-
children: /* @__PURE__ */ jsx("div", { className: "w-2.5 h-2.5 bg-foreground rounded-[1px]" })
|
|
2328
|
-
}
|
|
2329
|
-
) : /* @__PURE__ */ jsx(
|
|
2330
|
-
Button,
|
|
2331
|
-
{
|
|
2332
|
-
type: "submit",
|
|
2333
|
-
disabled: !value.trim(),
|
|
2334
|
-
size: "icon",
|
|
2335
|
-
className: cn(
|
|
2336
|
-
"h-8 w-8 rounded-full transition-all duration-300",
|
|
2337
|
-
value.trim() ? "bg-foreground text-background hover:opacity-90" : "bg-muted text-muted-foreground opacity-50"
|
|
2338
|
-
),
|
|
2339
|
-
onClick: () => onSubmit(),
|
|
2340
|
-
children: /* @__PURE__ */ jsx(Icon, { name: "ArrowUp", size: 18 })
|
|
2341
|
-
}
|
|
2342
|
-
)
|
|
2343
|
-
] })
|
|
2344
|
-
] }) });
|
|
2345
|
-
}
|
|
2346
|
-
function MessageContent({ content }) {
|
|
2347
|
-
const elements = [];
|
|
2348
|
-
let currentTextBlock = [];
|
|
2349
|
-
const flushText = (key) => {
|
|
2350
|
-
if (currentTextBlock.length > 0) {
|
|
2351
|
-
elements.push(
|
|
2352
|
-
/* @__PURE__ */ jsx("div", { className: "prose prose-sm dark:prose-invert max-w-none break-words [&>p]:mb-2 [&>p:last-child]:mb-0 [&>ul]:list-disc [&>ul]:pl-4 [&>ol]:list-decimal [&>ol]:pl-4 [&>li]:mb-1 [&>h1]:text-xl [&>h1]:font-bold [&>h1]:mb-2 [&>h2]:text-lg [&>h2]:font-bold [&>h2]:mb-2 [&>h3]:text-base [&>h3]:font-bold [&>h3]:mb-2 [&>pre]:bg-muted [&>pre]:p-2 [&>pre]:rounded [&>pre]:overflow-x-auto [&>pre]:mb-2 [&>code]:bg-muted [&>code]:px-1 [&>code]:py-0.5 [&>code]:rounded [&>code]:font-mono [&>code]:text-sm", children: /* @__PURE__ */ jsx(ReactMarkdown, { remarkPlugins: [remarkGfm, remarkBreaks], children: currentTextBlock.join("") }) }, `text-${key}`)
|
|
2353
|
-
);
|
|
2354
|
-
currentTextBlock = [];
|
|
2355
|
-
}
|
|
2356
|
-
};
|
|
2357
|
-
content.forEach((event, index) => {
|
|
2358
|
-
const key = event.id || index;
|
|
2359
|
-
if (event.type === "ui") {
|
|
2360
|
-
flushText(index);
|
|
2361
|
-
elements.push(/* @__PURE__ */ jsx(MelonyRenderer, { node: event.data }, key));
|
|
2362
|
-
} else if (event.type === "assistant:text-delta") {
|
|
2363
|
-
currentTextBlock.push(event.data.delta || "");
|
|
2364
|
-
} else if (event.type === "assistant:text" || event.type === "user:text") {
|
|
2365
|
-
const text = event.data.content || event.data.text || "";
|
|
2366
|
-
if (text) {
|
|
2367
|
-
currentTextBlock.push(text);
|
|
2368
|
-
}
|
|
2369
|
-
}
|
|
2370
|
-
});
|
|
2371
|
-
flushText(content.length);
|
|
2372
|
-
return /* @__PURE__ */ jsx("div", { className: "flex flex-col space-y-2.5", children: elements });
|
|
2373
|
-
}
|
|
2374
|
-
function MessageBubble({ message }) {
|
|
2375
|
-
const isUser = message.role === "user";
|
|
2376
|
-
return /* @__PURE__ */ jsx("div", { className: cn("flex flex-col w-full", isUser ? "items-end" : "items-start"), children: /* @__PURE__ */ jsx(
|
|
2377
|
-
"div",
|
|
2378
|
-
{
|
|
2379
|
-
className: cn(
|
|
2380
|
-
"flex flex-col items-start max-w-[85%] transition-all duration-200",
|
|
2381
|
-
isUser ? "bg-muted/80 text-foreground px-3 py-1.5 rounded-lg" : "px-0 py-0 text-foreground w-full"
|
|
2382
|
-
),
|
|
2383
|
-
children: /* @__PURE__ */ jsx(MessageContent, { content: message.content })
|
|
2384
|
-
}
|
|
2385
|
-
) });
|
|
2386
|
-
}
|
|
2387
|
-
function MessageList({
|
|
2388
|
-
messages,
|
|
2389
|
-
streaming,
|
|
2390
|
-
error,
|
|
2391
|
-
loadingStatus
|
|
2392
|
-
}) {
|
|
2393
|
-
if (messages.length === 0) {
|
|
2394
|
-
return null;
|
|
2395
|
-
}
|
|
2396
|
-
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
2397
|
-
messages.map((message, index) => /* @__PURE__ */ jsx(MessageBubble, { message }, index)),
|
|
2398
|
-
streaming && /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: loadingStatus?.message || "Processing..." }),
|
|
2399
|
-
error && /* @__PURE__ */ jsx("div", { className: "text-sm text-destructive", children: error.message })
|
|
2400
|
-
] });
|
|
2401
|
-
}
|
|
2402
|
-
function Thread({
|
|
2403
|
-
placeholder = "Type a message...",
|
|
2404
|
-
messages: propMessages,
|
|
2405
|
-
autoFocus = false,
|
|
2406
|
-
children
|
|
2407
|
-
}) {
|
|
2408
|
-
const {
|
|
2409
|
-
streaming,
|
|
2410
|
-
error,
|
|
2411
|
-
send,
|
|
2412
|
-
stop,
|
|
2413
|
-
messages: melonyMessages
|
|
2414
|
-
} = useMelony();
|
|
2415
|
-
const messages = useMemo(() => {
|
|
2416
|
-
return (propMessages || melonyMessages || []).filter(
|
|
2417
|
-
(msg) => ["user", "assistant"].includes(msg.role)
|
|
2418
|
-
);
|
|
2419
|
-
}, [propMessages, melonyMessages]);
|
|
2420
|
-
const [input, setInput] = useState("");
|
|
2421
|
-
const messagesEndRef = useRef(null);
|
|
2422
|
-
useEffect(() => {
|
|
2423
|
-
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
2424
|
-
}, [messages]);
|
|
2425
|
-
const handleSubmit = async (state, overrideInput) => {
|
|
2426
|
-
const text = (overrideInput ?? input).trim();
|
|
2427
|
-
const hasFiles = state?.files && Array.isArray(state.files) && state.files.length > 0;
|
|
2428
|
-
if (!text && !hasFiles || streaming) return;
|
|
2429
|
-
if (!overrideInput) setInput("");
|
|
2430
|
-
await send({
|
|
2431
|
-
type: "user:text",
|
|
2432
|
-
data: { content: text || "" }
|
|
2433
|
-
});
|
|
2434
|
-
};
|
|
2435
|
-
return /* @__PURE__ */ jsxs("div", { className: "relative flex flex-col h-full flex-1 overflow-hidden", children: [
|
|
2436
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto p-4 pb-36", children: [
|
|
2437
|
-
/* @__PURE__ */ jsx(
|
|
2438
|
-
"div",
|
|
2439
|
-
{
|
|
2440
|
-
className: cn(
|
|
2441
|
-
"max-w-3xl mx-auto w-full p-4"
|
|
2442
|
-
),
|
|
2443
|
-
children: messages.length === 0 && !streaming && children ? /* @__PURE__ */ jsx("div", { className: "flex flex-col items-start justify-center min-h-[50vh] space-y-6 animate-in fade-in slide-in-from-bottom-4 duration-1000", children }) : /* @__PURE__ */ jsx(
|
|
2444
|
-
MessageList,
|
|
2445
|
-
{
|
|
2446
|
-
messages,
|
|
2447
|
-
streaming,
|
|
2448
|
-
error,
|
|
2449
|
-
loadingStatus: {
|
|
2450
|
-
message: "Processing..."
|
|
2451
|
-
}
|
|
2452
|
-
}
|
|
2453
|
-
)
|
|
2454
|
-
}
|
|
2455
|
-
),
|
|
2456
|
-
/* @__PURE__ */ jsx("div", { ref: messagesEndRef })
|
|
2457
|
-
] }),
|
|
2458
|
-
/* @__PURE__ */ jsx("div", { className: "absolute bottom-0 p-4 w-full bg-gradient-to-t from-background via-background/90 to-transparent", children: /* @__PURE__ */ jsxs("div", { className: "max-w-3xl mx-auto", children: [
|
|
2459
|
-
/* @__PURE__ */ jsx(
|
|
2460
|
-
Composer,
|
|
2461
|
-
{
|
|
2462
|
-
value: input,
|
|
2463
|
-
onChange: setInput,
|
|
2464
|
-
onSubmit: handleSubmit,
|
|
2465
|
-
onStop: stop,
|
|
2466
|
-
placeholder,
|
|
2467
|
-
streaming,
|
|
2468
|
-
autoFocus
|
|
2469
|
-
}
|
|
2470
|
-
),
|
|
2471
|
-
/* @__PURE__ */ jsx("div", { className: "mt-2 text-center", children: /* @__PURE__ */ jsx("p", { className: "text-[10px] text-muted-foreground/60", children: "Melony can make mistakes. Check important info." }) })
|
|
2472
|
-
] }) })
|
|
2473
|
-
] });
|
|
2474
|
-
}
|
|
2475
1634
|
var ThemeContext = createContext(void 0);
|
|
2476
1635
|
function ThemeProvider({ children }) {
|
|
2477
1636
|
const [theme, setThemeState] = useState("system");
|
|
@@ -2524,41 +1683,14 @@ function useTheme() {
|
|
|
2524
1683
|
}
|
|
2525
1684
|
return context;
|
|
2526
1685
|
}
|
|
2527
|
-
function ThemeToggle() {
|
|
2528
|
-
const { theme, setTheme } = useTheme();
|
|
2529
|
-
const themes = [
|
|
2530
|
-
{ name: "light", icon: "Sun", label: "Light" },
|
|
2531
|
-
{ name: "dark", icon: "Moon", label: "Dark" },
|
|
2532
|
-
{ name: "system", icon: "Monitor", label: "System" }
|
|
2533
|
-
];
|
|
2534
|
-
return /* @__PURE__ */ jsx("div", { className: "inline-flex items-center gap-1 rounded-full border bg-muted/50 p-1", children: themes.map((t) => /* @__PURE__ */ jsxs(
|
|
2535
|
-
Button,
|
|
2536
|
-
{
|
|
2537
|
-
variant: theme === t.name ? "secondary" : "ghost",
|
|
2538
|
-
size: "icon-xs",
|
|
2539
|
-
onClick: () => setTheme(t.name),
|
|
2540
|
-
className: cn(
|
|
2541
|
-
"rounded-full transition-all",
|
|
2542
|
-
theme === t.name && "shadow-xs bg-background hover:bg-background"
|
|
2543
|
-
),
|
|
2544
|
-
children: [
|
|
2545
|
-
/* @__PURE__ */ jsx(Icon, { name: t.icon, size: "sm" }),
|
|
2546
|
-
/* @__PURE__ */ jsx("span", { className: "sr-only", children: t.label })
|
|
2547
|
-
]
|
|
2548
|
-
},
|
|
2549
|
-
t.name
|
|
2550
|
-
)) });
|
|
2551
|
-
}
|
|
2552
1686
|
|
|
2553
1687
|
// src/index.ts
|
|
2554
1688
|
var shadcnElements = {
|
|
2555
|
-
card: Card2,
|
|
2556
1689
|
button: Button2,
|
|
2557
1690
|
row: Row,
|
|
2558
1691
|
col: Col,
|
|
2559
1692
|
text: Text,
|
|
2560
1693
|
heading: Heading,
|
|
2561
|
-
badge: Badge2,
|
|
2562
1694
|
input: Input2,
|
|
2563
1695
|
hidden: Hidden,
|
|
2564
1696
|
textarea: Textarea2,
|
|
@@ -2573,15 +1705,9 @@ var shadcnElements = {
|
|
|
2573
1705
|
image: Image,
|
|
2574
1706
|
video: Video,
|
|
2575
1707
|
icon: Icon,
|
|
2576
|
-
list: List,
|
|
2577
|
-
listItem: ListItem,
|
|
2578
1708
|
form: Form,
|
|
2579
|
-
chart: Chart,
|
|
2580
1709
|
label: Label2,
|
|
2581
|
-
upload: Upload
|
|
2582
|
-
dropdown: Dropdown,
|
|
2583
|
-
thread: Thread,
|
|
2584
|
-
themeToggle: ThemeToggle
|
|
1710
|
+
upload: Upload
|
|
2585
1711
|
};
|
|
2586
1712
|
var ThemeProvider2 = ThemeProvider;
|
|
2587
1713
|
var useTheme2 = useTheme;
|