@melony/react 0.1.24 → 0.1.25
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.cjs +623 -464
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +167 -42
- package/dist/index.d.ts +167 -42
- package/dist/index.js +554 -420
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React11 from 'react';
|
|
2
|
+
import React11__default, { createContext, useState, useCallback, useEffect, useMemo, useContext, useRef } from 'react';
|
|
3
3
|
import { NuqsAdapter } from 'nuqs/adapters/react';
|
|
4
4
|
import { QueryClient, QueryClientProvider, useQueryClient, useQuery, useMutation } from '@tanstack/react-query';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -9,13 +9,13 @@ import { clsx } from 'clsx';
|
|
|
9
9
|
import { twMerge } from 'tailwind-merge';
|
|
10
10
|
import { Button as Button$1 } from '@base-ui/react/button';
|
|
11
11
|
import { cva } from 'class-variance-authority';
|
|
12
|
+
import { mergeProps } from '@base-ui/react/merge-props';
|
|
13
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
12
14
|
import * as ICONS from '@tabler/icons-react';
|
|
13
|
-
import { IconX,
|
|
15
|
+
import { IconPaperclip, IconX, IconPlus, IconChevronDown, IconLoader2, IconArrowUp, IconMessage, IconTrash, IconHistory, IconArrowLeft, IconLayoutSidebarLeftExpand, IconLayoutSidebarLeftCollapse, IconLayoutSidebarRightExpand, IconLayoutSidebarRightCollapse, IconUser, IconLogout, IconBrandGoogle, IconDeviceDesktop, IconMoon, IconSun, IconCheck, IconSelector, IconChevronUp } from '@tabler/icons-react';
|
|
14
16
|
import { Menu } from '@base-ui/react/menu';
|
|
15
17
|
import { Separator as Separator$1 } from '@base-ui/react/separator';
|
|
16
18
|
import { Dialog as Dialog$1 } from '@base-ui/react/dialog';
|
|
17
|
-
import { mergeProps } from '@base-ui/react/merge-props';
|
|
18
|
-
import { useRender } from '@base-ui/react/use-render';
|
|
19
19
|
import { Input as Input$1 } from '@base-ui/react/input';
|
|
20
20
|
import { Select as Select$1 } from '@base-ui/react/select';
|
|
21
21
|
import { createPortal } from 'react-dom';
|
|
@@ -63,14 +63,12 @@ var MelonyContextProviderInner = ({
|
|
|
63
63
|
children,
|
|
64
64
|
client,
|
|
65
65
|
initialEvents,
|
|
66
|
-
configApi,
|
|
67
66
|
setContextValue
|
|
68
67
|
}) => {
|
|
69
68
|
const [state, setState] = useState(client.getState());
|
|
70
69
|
const { data: config } = useQuery({
|
|
71
|
-
queryKey: ["melony-config",
|
|
72
|
-
queryFn: () => client.getConfig(
|
|
73
|
-
enabled: !!configApi,
|
|
70
|
+
queryKey: ["melony-config", client.url],
|
|
71
|
+
queryFn: () => client.getConfig(),
|
|
74
72
|
staleTime: Infinity
|
|
75
73
|
});
|
|
76
74
|
useEffect(() => {
|
|
@@ -85,17 +83,56 @@ var MelonyContextProviderInner = ({
|
|
|
85
83
|
unsubscribe();
|
|
86
84
|
};
|
|
87
85
|
}, [client]);
|
|
86
|
+
const reset = useCallback(
|
|
87
|
+
(events) => client.reset(events),
|
|
88
|
+
[client]
|
|
89
|
+
);
|
|
90
|
+
const dispatchClientAction = useCallback(
|
|
91
|
+
async (event) => {
|
|
92
|
+
if (!event.type.startsWith("client:")) return false;
|
|
93
|
+
switch (event.type) {
|
|
94
|
+
case "client:navigate": {
|
|
95
|
+
const url = event.data?.url;
|
|
96
|
+
if (url) {
|
|
97
|
+
window.history.pushState(null, "", url);
|
|
98
|
+
window.dispatchEvent(new PopStateEvent("popstate"));
|
|
99
|
+
}
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
case "client:open-url": {
|
|
103
|
+
const { url, target = "_blank" } = event.data || {};
|
|
104
|
+
if (url) {
|
|
105
|
+
window.open(url, target);
|
|
106
|
+
}
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
case "client:copy": {
|
|
110
|
+
const { text } = event.data || {};
|
|
111
|
+
if (text) {
|
|
112
|
+
await navigator.clipboard.writeText(text);
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
case "client:reset": {
|
|
117
|
+
reset([]);
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
default:
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
[client, reset]
|
|
125
|
+
);
|
|
88
126
|
const sendEvent = useCallback(
|
|
89
127
|
async (event, options) => {
|
|
128
|
+
const handled = await dispatchClientAction(event);
|
|
129
|
+
if (handled) return;
|
|
90
130
|
const generator = client.sendEvent(event, options);
|
|
91
|
-
for await (const
|
|
131
|
+
for await (const incomingEvent of generator) {
|
|
132
|
+
await dispatchClientAction(incomingEvent);
|
|
92
133
|
}
|
|
93
134
|
},
|
|
94
|
-
[client]
|
|
95
|
-
);
|
|
96
|
-
const reset = useCallback(
|
|
97
|
-
(events) => client.reset(events),
|
|
98
|
-
[client]
|
|
135
|
+
[client, dispatchClientAction]
|
|
99
136
|
);
|
|
100
137
|
const value = useMemo(
|
|
101
138
|
() => ({
|
|
@@ -117,8 +154,7 @@ var MelonyClientProvider = ({
|
|
|
117
154
|
children,
|
|
118
155
|
client,
|
|
119
156
|
initialEvents,
|
|
120
|
-
queryClient = defaultQueryClient
|
|
121
|
-
configApi
|
|
157
|
+
queryClient = defaultQueryClient
|
|
122
158
|
}) => {
|
|
123
159
|
const [contextValue, setContextValue] = useState(void 0);
|
|
124
160
|
return /* @__PURE__ */ jsx(MelonyContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(
|
|
@@ -126,7 +162,6 @@ var MelonyClientProvider = ({
|
|
|
126
162
|
{
|
|
127
163
|
client,
|
|
128
164
|
initialEvents,
|
|
129
|
-
configApi,
|
|
130
165
|
setContextValue,
|
|
131
166
|
children
|
|
132
167
|
}
|
|
@@ -377,6 +412,47 @@ var useThreads = () => {
|
|
|
377
412
|
}
|
|
378
413
|
return context;
|
|
379
414
|
};
|
|
415
|
+
function useScreenSize(mobileBreakpoint = 768, tabletBreakpoint = 1024) {
|
|
416
|
+
const [screenSize, setScreenSize] = useState(() => {
|
|
417
|
+
if (typeof window === "undefined") {
|
|
418
|
+
return {
|
|
419
|
+
width: 1024,
|
|
420
|
+
height: 768,
|
|
421
|
+
isMobile: false,
|
|
422
|
+
isTablet: false,
|
|
423
|
+
isDesktop: true
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
const width = window.innerWidth;
|
|
427
|
+
return {
|
|
428
|
+
width,
|
|
429
|
+
height: window.innerHeight,
|
|
430
|
+
isMobile: width < mobileBreakpoint,
|
|
431
|
+
isTablet: width >= mobileBreakpoint && width < tabletBreakpoint,
|
|
432
|
+
isDesktop: width >= tabletBreakpoint
|
|
433
|
+
};
|
|
434
|
+
});
|
|
435
|
+
useEffect(() => {
|
|
436
|
+
if (typeof window === "undefined") return;
|
|
437
|
+
const updateScreenSize = () => {
|
|
438
|
+
const width = window.innerWidth;
|
|
439
|
+
const height = window.innerHeight;
|
|
440
|
+
setScreenSize({
|
|
441
|
+
width,
|
|
442
|
+
height,
|
|
443
|
+
isMobile: width < mobileBreakpoint,
|
|
444
|
+
isTablet: width >= mobileBreakpoint && width < tabletBreakpoint,
|
|
445
|
+
isDesktop: width >= tabletBreakpoint
|
|
446
|
+
});
|
|
447
|
+
};
|
|
448
|
+
updateScreenSize();
|
|
449
|
+
window.addEventListener("resize", updateScreenSize);
|
|
450
|
+
return () => {
|
|
451
|
+
window.removeEventListener("resize", updateScreenSize);
|
|
452
|
+
};
|
|
453
|
+
}, [mobileBreakpoint, tabletBreakpoint]);
|
|
454
|
+
return screenSize;
|
|
455
|
+
}
|
|
380
456
|
function cn(...inputs) {
|
|
381
457
|
return twMerge(clsx(inputs));
|
|
382
458
|
}
|
|
@@ -437,6 +513,45 @@ function Textarea({ className, ...props }) {
|
|
|
437
513
|
}
|
|
438
514
|
);
|
|
439
515
|
}
|
|
516
|
+
var badgeVariants = cva(
|
|
517
|
+
"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",
|
|
518
|
+
{
|
|
519
|
+
variants: {
|
|
520
|
+
variant: {
|
|
521
|
+
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
|
|
522
|
+
secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
|
|
523
|
+
destructive: "bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20",
|
|
524
|
+
outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground bg-input/30",
|
|
525
|
+
ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
|
|
526
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
527
|
+
}
|
|
528
|
+
},
|
|
529
|
+
defaultVariants: {
|
|
530
|
+
variant: "default"
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
);
|
|
534
|
+
function Badge({
|
|
535
|
+
className,
|
|
536
|
+
variant = "default",
|
|
537
|
+
render,
|
|
538
|
+
...props
|
|
539
|
+
}) {
|
|
540
|
+
return useRender({
|
|
541
|
+
defaultTagName: "span",
|
|
542
|
+
props: mergeProps(
|
|
543
|
+
{
|
|
544
|
+
className: cn(badgeVariants({ className, variant }))
|
|
545
|
+
},
|
|
546
|
+
props
|
|
547
|
+
),
|
|
548
|
+
render,
|
|
549
|
+
state: {
|
|
550
|
+
slot: "badge",
|
|
551
|
+
variant
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
}
|
|
440
555
|
function DropdownMenu({ ...props }) {
|
|
441
556
|
return /* @__PURE__ */ jsx(Menu.Root, { "data-slot": "dropdown-menu", ...props });
|
|
442
557
|
}
|
|
@@ -564,21 +679,17 @@ function Composer({
|
|
|
564
679
|
options = [],
|
|
565
680
|
autoFocus = false,
|
|
566
681
|
defaultSelectedIds = [],
|
|
567
|
-
fileAttachments
|
|
568
|
-
// Legacy props for backward compatibility
|
|
569
|
-
accept: legacyAccept,
|
|
570
|
-
maxFiles: legacyMaxFiles,
|
|
571
|
-
maxFileSize: legacyMaxFileSize
|
|
682
|
+
fileAttachments
|
|
572
683
|
}) {
|
|
573
|
-
const enabled = fileAttachments?.enabled
|
|
574
|
-
const accept = fileAttachments?.accept
|
|
575
|
-
const maxFiles = fileAttachments?.maxFiles ??
|
|
576
|
-
const maxFileSize = fileAttachments?.maxFileSize ??
|
|
577
|
-
const [selectedOptions, setSelectedOptions] =
|
|
684
|
+
const enabled = fileAttachments?.enabled || false;
|
|
685
|
+
const accept = fileAttachments?.accept;
|
|
686
|
+
const maxFiles = fileAttachments?.maxFiles ?? 10;
|
|
687
|
+
const maxFileSize = fileAttachments?.maxFileSize ?? 10 * 1024 * 1024;
|
|
688
|
+
const [selectedOptions, setSelectedOptions] = React11__default.useState(
|
|
578
689
|
() => new Set(defaultSelectedIds)
|
|
579
690
|
);
|
|
580
|
-
const [attachedFiles, setAttachedFiles] =
|
|
581
|
-
const fileInputRef =
|
|
691
|
+
const [attachedFiles, setAttachedFiles] = React11__default.useState([]);
|
|
692
|
+
const fileInputRef = React11__default.useRef(null);
|
|
582
693
|
const toggleOption = (id, groupOptions, type = "multiple") => {
|
|
583
694
|
const next = new Set(selectedOptions);
|
|
584
695
|
if (type === "single") {
|
|
@@ -602,7 +713,9 @@ function Composer({
|
|
|
602
713
|
const files = Array.from(e.target.files || []);
|
|
603
714
|
const validFiles = files.filter((file) => {
|
|
604
715
|
if (file.size > maxFileSize) {
|
|
605
|
-
console.warn(
|
|
716
|
+
console.warn(
|
|
717
|
+
`File ${file.name} exceeds maximum size of ${maxFileSize} bytes`
|
|
718
|
+
);
|
|
606
719
|
return false;
|
|
607
720
|
}
|
|
608
721
|
return true;
|
|
@@ -610,7 +723,9 @@ function Composer({
|
|
|
610
723
|
const remainingSlots = maxFiles - attachedFiles.length;
|
|
611
724
|
const filesToAdd = validFiles.slice(0, remainingSlots);
|
|
612
725
|
if (filesToAdd.length < validFiles.length) {
|
|
613
|
-
console.warn(
|
|
726
|
+
console.warn(
|
|
727
|
+
`Only ${filesToAdd.length} files can be added (max: ${maxFiles})`
|
|
728
|
+
);
|
|
614
729
|
}
|
|
615
730
|
setAttachedFiles((prev) => [...prev, ...filesToAdd]);
|
|
616
731
|
if (fileInputRef.current) {
|
|
@@ -653,12 +768,11 @@ function Composer({
|
|
|
653
768
|
reject(new Error("FileReader returned empty result"));
|
|
654
769
|
return;
|
|
655
770
|
}
|
|
656
|
-
const base64Data = base64.includes(",") ? base64.split(",")[1] : base64;
|
|
657
771
|
resolve({
|
|
658
772
|
name: file.name,
|
|
659
773
|
type: file.type,
|
|
660
774
|
size: file.size,
|
|
661
|
-
data:
|
|
775
|
+
data: base64
|
|
662
776
|
});
|
|
663
777
|
} catch (error) {
|
|
664
778
|
reject(error);
|
|
@@ -691,129 +805,189 @@ function Composer({
|
|
|
691
805
|
handleInternalSubmit().catch(console.error);
|
|
692
806
|
}
|
|
693
807
|
};
|
|
694
|
-
return /* @__PURE__ */
|
|
695
|
-
|
|
696
|
-
|
|
808
|
+
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-input border-[1.5px] rounded-3xl bg-background shadow-sm focus-within:border-ring transition-all p-2", children: [
|
|
809
|
+
/* @__PURE__ */ jsx(
|
|
810
|
+
Textarea,
|
|
697
811
|
{
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
812
|
+
value,
|
|
813
|
+
onChange: (e) => onChange(e.target.value),
|
|
814
|
+
onKeyDown: handleKeyDown,
|
|
815
|
+
placeholder,
|
|
816
|
+
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",
|
|
817
|
+
autoFocus
|
|
818
|
+
}
|
|
819
|
+
),
|
|
820
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center px-1", children: [
|
|
821
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
822
|
+
enabled && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
702
823
|
/* @__PURE__ */ jsx(
|
|
703
|
-
"
|
|
824
|
+
"input",
|
|
825
|
+
{
|
|
826
|
+
ref: fileInputRef,
|
|
827
|
+
type: "file",
|
|
828
|
+
multiple: true,
|
|
829
|
+
accept,
|
|
830
|
+
onChange: handleFileSelect,
|
|
831
|
+
className: "hidden",
|
|
832
|
+
disabled: isLoading || attachedFiles.length >= maxFiles
|
|
833
|
+
}
|
|
834
|
+
),
|
|
835
|
+
attachedFiles.length === 0 ? /* @__PURE__ */ jsx(
|
|
836
|
+
Button,
|
|
704
837
|
{
|
|
705
838
|
type: "button",
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
839
|
+
variant: "ghost",
|
|
840
|
+
size: "sm",
|
|
841
|
+
onClick: () => fileInputRef.current?.click(),
|
|
842
|
+
disabled: isLoading,
|
|
843
|
+
className: "text-muted-foreground",
|
|
844
|
+
title: "Attach file",
|
|
845
|
+
children: /* @__PURE__ */ jsx(IconPaperclip, { className: "h-4 w-4" })
|
|
710
846
|
}
|
|
711
|
-
)
|
|
712
|
-
]
|
|
713
|
-
},
|
|
714
|
-
index
|
|
715
|
-
)) }),
|
|
716
|
-
/* @__PURE__ */ jsxs("div", { className: "relative flex flex-col w-full border-input border-[1.5px] rounded-3xl bg-background shadow-sm focus-within:border-ring transition-all p-2", children: [
|
|
717
|
-
/* @__PURE__ */ jsx(
|
|
718
|
-
Textarea,
|
|
719
|
-
{
|
|
720
|
-
value,
|
|
721
|
-
onChange: (e) => onChange(e.target.value),
|
|
722
|
-
onKeyDown: handleKeyDown,
|
|
723
|
-
placeholder,
|
|
724
|
-
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",
|
|
725
|
-
autoFocus
|
|
726
|
-
}
|
|
727
|
-
),
|
|
728
|
-
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center px-1", children: [
|
|
729
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
730
|
-
enabled && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
847
|
+
) : /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
731
848
|
/* @__PURE__ */ jsx(
|
|
732
|
-
|
|
849
|
+
DropdownMenuTrigger,
|
|
733
850
|
{
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
851
|
+
render: /* @__PURE__ */ jsxs(
|
|
852
|
+
Button,
|
|
853
|
+
{
|
|
854
|
+
type: "button",
|
|
855
|
+
variant: "ghost",
|
|
856
|
+
size: "sm",
|
|
857
|
+
className: "text-muted-foreground gap-2",
|
|
858
|
+
title: `${attachedFiles.length} files attached`,
|
|
859
|
+
children: [
|
|
860
|
+
/* @__PURE__ */ jsx(IconPaperclip, { className: "h-4 w-4" }),
|
|
861
|
+
/* @__PURE__ */ jsx(Badge, { className: "h-[18px] min-w-[18px] px-1.5 text-[10px]", children: attachedFiles.length })
|
|
862
|
+
]
|
|
863
|
+
}
|
|
864
|
+
)
|
|
741
865
|
}
|
|
742
866
|
),
|
|
743
|
-
/* @__PURE__ */
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
title: attachedFiles.length >= maxFiles ? `Maximum ${maxFiles} files allowed` : "Attach file",
|
|
753
|
-
children: /* @__PURE__ */ jsx(IconPaperclip, { className: "h-4 w-4" })
|
|
754
|
-
}
|
|
755
|
-
)
|
|
756
|
-
] }),
|
|
757
|
-
options.map((group) => {
|
|
758
|
-
const selectedInGroup = group.options.filter(
|
|
759
|
-
(o) => selectedOptions.has(o.id)
|
|
760
|
-
);
|
|
761
|
-
const label = selectedInGroup.length === 0 ? group.label : selectedInGroup.length === 1 ? selectedInGroup[0].label : `${group.label} (${selectedInGroup.length})`;
|
|
762
|
-
const isSingle = group.type === "single";
|
|
763
|
-
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
764
|
-
/* @__PURE__ */ jsx(
|
|
765
|
-
DropdownMenuTrigger,
|
|
766
|
-
{
|
|
767
|
-
render: /* @__PURE__ */ jsxs(
|
|
768
|
-
Button,
|
|
769
|
-
{
|
|
770
|
-
variant: "ghost",
|
|
771
|
-
size: "sm",
|
|
772
|
-
className: cn(
|
|
773
|
-
selectedInGroup.length > 0 ? "text-foreground bg-muted/50" : "text-muted-foreground"
|
|
774
|
-
),
|
|
775
|
-
children: [
|
|
776
|
-
label,
|
|
777
|
-
/* @__PURE__ */ jsx(IconChevronDown, { className: "h-3 w-3 opacity-50" })
|
|
778
|
-
]
|
|
779
|
-
}
|
|
780
|
-
)
|
|
781
|
-
}
|
|
782
|
-
),
|
|
783
|
-
/* @__PURE__ */ jsx(DropdownMenuContent, { align: "start", className: "w-56", children: /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
|
|
784
|
-
/* @__PURE__ */ jsx(DropdownMenuLabel, { children: group.label }),
|
|
867
|
+
/* @__PURE__ */ jsxs(DropdownMenuContent, { align: "start", className: "w-64", children: [
|
|
868
|
+
/* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
|
|
869
|
+
/* @__PURE__ */ jsxs(DropdownMenuLabel, { children: [
|
|
870
|
+
"Attached Files (",
|
|
871
|
+
attachedFiles.length,
|
|
872
|
+
"/",
|
|
873
|
+
maxFiles,
|
|
874
|
+
")"
|
|
875
|
+
] }),
|
|
785
876
|
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
786
|
-
|
|
787
|
-
|
|
877
|
+
attachedFiles.map((file, index) => /* @__PURE__ */ jsxs(
|
|
878
|
+
DropdownMenuItem,
|
|
788
879
|
{
|
|
789
|
-
|
|
790
|
-
onCheckedChange: () => toggleOption(
|
|
791
|
-
option.id,
|
|
792
|
-
group.options,
|
|
793
|
-
isSingle ? "single" : "multiple"
|
|
794
|
-
),
|
|
880
|
+
className: "flex items-center justify-between group",
|
|
795
881
|
onSelect: (e) => e.preventDefault(),
|
|
796
|
-
children:
|
|
882
|
+
children: [
|
|
883
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
|
|
884
|
+
/* @__PURE__ */ jsx(
|
|
885
|
+
"span",
|
|
886
|
+
{
|
|
887
|
+
className: "truncate text-sm",
|
|
888
|
+
title: file.name,
|
|
889
|
+
children: file.name
|
|
890
|
+
}
|
|
891
|
+
),
|
|
892
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: formatFileSize(file.size) })
|
|
893
|
+
] }),
|
|
894
|
+
/* @__PURE__ */ jsx(
|
|
895
|
+
Button,
|
|
896
|
+
{
|
|
897
|
+
type: "button",
|
|
898
|
+
variant: "ghost",
|
|
899
|
+
size: "icon",
|
|
900
|
+
className: "h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
901
|
+
onClick: () => handleRemoveFile(index),
|
|
902
|
+
children: /* @__PURE__ */ jsx(IconX, { className: "h-3 w-3" })
|
|
903
|
+
}
|
|
904
|
+
)
|
|
905
|
+
]
|
|
797
906
|
},
|
|
798
|
-
|
|
907
|
+
index
|
|
799
908
|
))
|
|
800
|
-
] })
|
|
801
|
-
|
|
802
|
-
|
|
909
|
+
] }),
|
|
910
|
+
attachedFiles.length < maxFiles && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
911
|
+
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
912
|
+
/* @__PURE__ */ jsxs(
|
|
913
|
+
DropdownMenuItem,
|
|
914
|
+
{
|
|
915
|
+
onSelect: (e) => {
|
|
916
|
+
e.preventDefault();
|
|
917
|
+
fileInputRef.current?.click();
|
|
918
|
+
},
|
|
919
|
+
className: "text-primary focus:text-primary",
|
|
920
|
+
children: [
|
|
921
|
+
/* @__PURE__ */ jsx(IconPlus, { className: "mr-2 h-4 w-4" }),
|
|
922
|
+
/* @__PURE__ */ jsx("span", { children: "Add more files" })
|
|
923
|
+
]
|
|
924
|
+
}
|
|
925
|
+
)
|
|
926
|
+
] })
|
|
927
|
+
] })
|
|
928
|
+
] })
|
|
803
929
|
] }),
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
930
|
+
options.map((group) => {
|
|
931
|
+
const selectedInGroup = group.options.filter(
|
|
932
|
+
(o) => selectedOptions.has(o.id)
|
|
933
|
+
);
|
|
934
|
+
const label = selectedInGroup.length === 0 ? group.label : selectedInGroup.length === 1 ? selectedInGroup[0].label : group.label;
|
|
935
|
+
const isSingle = group.type === "single";
|
|
936
|
+
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
937
|
+
/* @__PURE__ */ jsx(
|
|
938
|
+
DropdownMenuTrigger,
|
|
939
|
+
{
|
|
940
|
+
render: /* @__PURE__ */ jsxs(
|
|
941
|
+
Button,
|
|
942
|
+
{
|
|
943
|
+
variant: "ghost",
|
|
944
|
+
size: "sm",
|
|
945
|
+
className: cn(
|
|
946
|
+
"gap-2",
|
|
947
|
+
selectedInGroup.length > 0 ? "text-foreground bg-muted/50" : "text-muted-foreground"
|
|
948
|
+
),
|
|
949
|
+
children: [
|
|
950
|
+
label,
|
|
951
|
+
selectedInGroup.length > 1 && /* @__PURE__ */ jsx(Badge, { className: "h-[18px] min-w-[18px] px-1.5 text-[10px]", children: selectedInGroup.length }),
|
|
952
|
+
/* @__PURE__ */ jsx(IconChevronDown, { className: "h-3 w-3 opacity-50" })
|
|
953
|
+
]
|
|
954
|
+
}
|
|
955
|
+
)
|
|
956
|
+
}
|
|
957
|
+
),
|
|
958
|
+
/* @__PURE__ */ jsx(DropdownMenuContent, { align: "start", className: "w-56", children: /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
|
|
959
|
+
/* @__PURE__ */ jsx(DropdownMenuLabel, { children: group.label }),
|
|
960
|
+
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
961
|
+
group.options.map((option) => /* @__PURE__ */ jsx(
|
|
962
|
+
DropdownMenuCheckboxItem,
|
|
963
|
+
{
|
|
964
|
+
checked: selectedOptions.has(option.id),
|
|
965
|
+
onCheckedChange: () => toggleOption(
|
|
966
|
+
option.id,
|
|
967
|
+
group.options,
|
|
968
|
+
isSingle ? "single" : "multiple"
|
|
969
|
+
),
|
|
970
|
+
onSelect: (e) => e.preventDefault(),
|
|
971
|
+
children: option.label
|
|
972
|
+
},
|
|
973
|
+
option.id
|
|
974
|
+
))
|
|
975
|
+
] }) })
|
|
976
|
+
] }, group.id);
|
|
977
|
+
})
|
|
978
|
+
] }),
|
|
979
|
+
/* @__PURE__ */ jsx(
|
|
980
|
+
Button,
|
|
981
|
+
{
|
|
982
|
+
type: "submit",
|
|
983
|
+
disabled: !value.trim() && attachedFiles.length === 0 && !isLoading || isLoading,
|
|
984
|
+
size: "icon-lg",
|
|
985
|
+
onClick: () => handleInternalSubmit().catch(console.error),
|
|
986
|
+
children: isLoading ? /* @__PURE__ */ jsx(IconLoader2, { className: "h-5 w-5 animate-spin" }) : /* @__PURE__ */ jsx(IconArrowUp, { className: "h-5 w-5" })
|
|
987
|
+
}
|
|
988
|
+
)
|
|
815
989
|
] })
|
|
816
|
-
] });
|
|
990
|
+
] }) });
|
|
817
991
|
}
|
|
818
992
|
function Card({
|
|
819
993
|
className,
|
|
@@ -945,8 +1119,6 @@ var Col = ({
|
|
|
945
1119
|
gap = "sm",
|
|
946
1120
|
align = "start",
|
|
947
1121
|
justify = "start",
|
|
948
|
-
wrap = "nowrap",
|
|
949
|
-
flex = 1,
|
|
950
1122
|
width,
|
|
951
1123
|
height,
|
|
952
1124
|
padding,
|
|
@@ -996,13 +1168,11 @@ var Col = ({
|
|
|
996
1168
|
gapClasses[gap] || "gap-2",
|
|
997
1169
|
alignClasses[align] || "items-start",
|
|
998
1170
|
justifyClasses[justify] || "justify-start",
|
|
999
|
-
wrap === "wrap" ? "flex-wrap" : "flex-nowrap",
|
|
1000
1171
|
overflow && overflowClasses[overflow],
|
|
1001
1172
|
position && positionClasses[position],
|
|
1002
1173
|
className
|
|
1003
1174
|
),
|
|
1004
1175
|
style: {
|
|
1005
|
-
flex,
|
|
1006
1176
|
width,
|
|
1007
1177
|
height,
|
|
1008
1178
|
padding,
|
|
@@ -1436,45 +1606,6 @@ var Icon = ({
|
|
|
1436
1606
|
}
|
|
1437
1607
|
);
|
|
1438
1608
|
};
|
|
1439
|
-
var badgeVariants = cva(
|
|
1440
|
-
"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",
|
|
1441
|
-
{
|
|
1442
|
-
variants: {
|
|
1443
|
-
variant: {
|
|
1444
|
-
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
|
|
1445
|
-
secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
|
|
1446
|
-
destructive: "bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20",
|
|
1447
|
-
outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground bg-input/30",
|
|
1448
|
-
ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
|
|
1449
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
1450
|
-
}
|
|
1451
|
-
},
|
|
1452
|
-
defaultVariants: {
|
|
1453
|
-
variant: "default"
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
);
|
|
1457
|
-
function Badge({
|
|
1458
|
-
className,
|
|
1459
|
-
variant = "default",
|
|
1460
|
-
render,
|
|
1461
|
-
...props
|
|
1462
|
-
}) {
|
|
1463
|
-
return useRender({
|
|
1464
|
-
defaultTagName: "span",
|
|
1465
|
-
props: mergeProps(
|
|
1466
|
-
{
|
|
1467
|
-
className: cn(badgeVariants({ className, variant }))
|
|
1468
|
-
},
|
|
1469
|
-
props
|
|
1470
|
-
),
|
|
1471
|
-
render,
|
|
1472
|
-
state: {
|
|
1473
|
-
slot: "badge",
|
|
1474
|
-
variant
|
|
1475
|
-
}
|
|
1476
|
-
});
|
|
1477
|
-
}
|
|
1478
1609
|
var Badge2 = ({
|
|
1479
1610
|
label,
|
|
1480
1611
|
variant = "primary",
|
|
@@ -2063,9 +2194,9 @@ var Select2 = ({
|
|
|
2063
2194
|
defaultValue,
|
|
2064
2195
|
value,
|
|
2065
2196
|
disabled,
|
|
2066
|
-
onValueChange: handleValueChange,
|
|
2197
|
+
onValueChange: (value2) => handleValueChange(value2 || ""),
|
|
2067
2198
|
children: [
|
|
2068
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "w-full", children: /* @__PURE__ */ jsx(SelectValue, {
|
|
2199
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "w-full", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
2069
2200
|
/* @__PURE__ */ jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
|
|
2070
2201
|
]
|
|
2071
2202
|
}
|
|
@@ -2095,7 +2226,6 @@ var Label2 = ({
|
|
|
2095
2226
|
var Checkbox = ({
|
|
2096
2227
|
label,
|
|
2097
2228
|
name,
|
|
2098
|
-
value = "on",
|
|
2099
2229
|
checked,
|
|
2100
2230
|
defaultChecked,
|
|
2101
2231
|
disabled,
|
|
@@ -2110,46 +2240,37 @@ var Checkbox = ({
|
|
|
2110
2240
|
...onChangeAction,
|
|
2111
2241
|
data: {
|
|
2112
2242
|
name: name || "",
|
|
2113
|
-
value,
|
|
2114
2243
|
checked: e.target.checked
|
|
2115
2244
|
}
|
|
2116
2245
|
});
|
|
2117
2246
|
}
|
|
2118
2247
|
};
|
|
2119
|
-
return /* @__PURE__ */ jsxs(
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
{
|
|
2142
|
-
htmlFor: name,
|
|
2143
|
-
value: label,
|
|
2144
|
-
className: cn(
|
|
2145
|
-
"cursor-pointer select-none text-sm font-medium leading-none",
|
|
2146
|
-
disabled && "cursor-not-allowed opacity-50"
|
|
2147
|
-
)
|
|
2148
|
-
}
|
|
2248
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), style, children: [
|
|
2249
|
+
/* @__PURE__ */ jsx(
|
|
2250
|
+
"input",
|
|
2251
|
+
{
|
|
2252
|
+
type: "checkbox",
|
|
2253
|
+
name,
|
|
2254
|
+
id: name,
|
|
2255
|
+
checked,
|
|
2256
|
+
defaultChecked,
|
|
2257
|
+
disabled,
|
|
2258
|
+
onChange: handleChange,
|
|
2259
|
+
className: "h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary disabled:cursor-not-allowed disabled:opacity-50"
|
|
2260
|
+
}
|
|
2261
|
+
),
|
|
2262
|
+
label && /* @__PURE__ */ jsx(
|
|
2263
|
+
Label2,
|
|
2264
|
+
{
|
|
2265
|
+
htmlFor: name,
|
|
2266
|
+
value: label,
|
|
2267
|
+
className: cn(
|
|
2268
|
+
"cursor-pointer select-none text-sm font-medium leading-none",
|
|
2269
|
+
disabled && "cursor-not-allowed opacity-50"
|
|
2149
2270
|
)
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
);
|
|
2271
|
+
}
|
|
2272
|
+
)
|
|
2273
|
+
] });
|
|
2153
2274
|
};
|
|
2154
2275
|
var RadioGroup = ({
|
|
2155
2276
|
name,
|
|
@@ -2472,12 +2593,14 @@ function Thread({
|
|
|
2472
2593
|
});
|
|
2473
2594
|
const starterPrompts = localStarterPrompts ?? config?.starterPrompts;
|
|
2474
2595
|
const options = localOptions ?? config?.options;
|
|
2596
|
+
const fileAttachments = config?.fileAttachments;
|
|
2475
2597
|
const allDefaultSelectedIds = useMemo(() => {
|
|
2476
|
-
const defaultSelectedIdsFromOptions = options?.flatMap(
|
|
2477
|
-
(group) => group.defaultSelectedIds ?? []
|
|
2478
|
-
) ?? [];
|
|
2598
|
+
const defaultSelectedIdsFromOptions = options?.flatMap((group) => group.defaultSelectedIds ?? []) ?? [];
|
|
2479
2599
|
return [
|
|
2480
|
-
.../* @__PURE__ */ new Set([
|
|
2600
|
+
.../* @__PURE__ */ new Set([
|
|
2601
|
+
...defaultSelectedIdsFromOptions,
|
|
2602
|
+
...defaultSelectedIds ?? []
|
|
2603
|
+
])
|
|
2481
2604
|
];
|
|
2482
2605
|
}, [options, defaultSelectedIds]);
|
|
2483
2606
|
const [input, setInput] = useState("");
|
|
@@ -2553,7 +2676,7 @@ function Thread({
|
|
|
2553
2676
|
options,
|
|
2554
2677
|
autoFocus,
|
|
2555
2678
|
defaultSelectedIds: allDefaultSelectedIds,
|
|
2556
|
-
fileAttachments
|
|
2679
|
+
fileAttachments
|
|
2557
2680
|
}
|
|
2558
2681
|
) }) })
|
|
2559
2682
|
]
|
|
@@ -2561,20 +2684,36 @@ function Thread({
|
|
|
2561
2684
|
);
|
|
2562
2685
|
}
|
|
2563
2686
|
function ChatHeader({
|
|
2564
|
-
title,
|
|
2565
2687
|
leftContent,
|
|
2566
2688
|
rightContent,
|
|
2567
2689
|
className,
|
|
2568
|
-
titleClassName,
|
|
2569
2690
|
children
|
|
2570
2691
|
}) {
|
|
2571
2692
|
if (children) {
|
|
2572
|
-
return /* @__PURE__ */ jsx(
|
|
2693
|
+
return /* @__PURE__ */ jsx(
|
|
2694
|
+
"div",
|
|
2695
|
+
{
|
|
2696
|
+
className: cn(
|
|
2697
|
+
"px-2 border-b border-border h-14 flex items-center shrink-0",
|
|
2698
|
+
className
|
|
2699
|
+
),
|
|
2700
|
+
children
|
|
2701
|
+
}
|
|
2702
|
+
);
|
|
2573
2703
|
}
|
|
2574
|
-
return /* @__PURE__ */ jsxs(
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2704
|
+
return /* @__PURE__ */ jsxs(
|
|
2705
|
+
"div",
|
|
2706
|
+
{
|
|
2707
|
+
className: cn(
|
|
2708
|
+
"px-2 border-b border-border h-14 flex items-center justify-between shrink-0",
|
|
2709
|
+
className
|
|
2710
|
+
),
|
|
2711
|
+
children: [
|
|
2712
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: leftContent }),
|
|
2713
|
+
rightContent && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1 shrink-0 ml-2", children: rightContent })
|
|
2714
|
+
]
|
|
2715
|
+
}
|
|
2716
|
+
);
|
|
2578
2717
|
}
|
|
2579
2718
|
var ThreadList = ({
|
|
2580
2719
|
className,
|
|
@@ -2625,58 +2764,43 @@ var ThreadList = ({
|
|
|
2625
2764
|
if (diffDays < 7) return `${diffDays}d ago`;
|
|
2626
2765
|
return d.toLocaleDateString();
|
|
2627
2766
|
};
|
|
2628
|
-
return /* @__PURE__ */
|
|
2629
|
-
/* @__PURE__ */ jsx(
|
|
2630
|
-
|
|
2767
|
+
return /* @__PURE__ */ jsx("div", { className: cn("flex flex-col h-full", className), children: /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto", children: isLoading && threads.length === 0 ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsx(IconLoader2, { className: "size-5 animate-spin text-muted-foreground" }) }) : threads.length === 0 ? /* @__PURE__ */ jsx("div", { className: "p-4 text-center text-muted-foreground", children: emptyState || /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
2768
|
+
/* @__PURE__ */ jsx(IconMessage, { className: "size-8 mx-auto opacity-50" }),
|
|
2769
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm", children: "No threads yet" }),
|
|
2770
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: handleNewThread, children: "Start a conversation" })
|
|
2771
|
+
] }) }) : /* @__PURE__ */ jsx("div", { className: "p-2 space-y-1", children: threads.map((thread) => {
|
|
2772
|
+
const isActive = thread.id === activeThreadId;
|
|
2773
|
+
return /* @__PURE__ */ jsxs(
|
|
2774
|
+
"div",
|
|
2631
2775
|
{
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2776
|
+
onClick: () => handleThreadClick(thread.id),
|
|
2777
|
+
className: cn(
|
|
2778
|
+
"group relative flex items-center gap-3 px-3 py-1.5 rounded-lg cursor-pointer transition-colors",
|
|
2779
|
+
isActive ? "bg-muted" : "hover:bg-muted"
|
|
2780
|
+
),
|
|
2636
2781
|
children: [
|
|
2637
|
-
/* @__PURE__ */ jsx(
|
|
2638
|
-
|
|
2782
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
2783
|
+
/* @__PURE__ */ jsx("p", { className: cn("text-sm font-medium truncate"), children: thread.title || `Thread ${thread.id.slice(0, 8)}` }),
|
|
2784
|
+
thread.updatedAt && /* @__PURE__ */ jsx("span", { className: cn("text-xs shrink-0"), children: formatDate(thread.updatedAt) })
|
|
2785
|
+
] }) }),
|
|
2786
|
+
/* @__PURE__ */ jsx(
|
|
2787
|
+
Button,
|
|
2788
|
+
{
|
|
2789
|
+
variant: "ghost",
|
|
2790
|
+
size: "icon-xs",
|
|
2791
|
+
onClick: (e) => handleDelete(e, thread.id),
|
|
2792
|
+
className: cn(
|
|
2793
|
+
"opacity-0 group-hover:opacity-100 transition-opacity shrink-0",
|
|
2794
|
+
isActive && "hover:bg-primary-foreground/20"
|
|
2795
|
+
),
|
|
2796
|
+
children: /* @__PURE__ */ jsx(IconTrash, { className: "size-3" })
|
|
2797
|
+
}
|
|
2798
|
+
)
|
|
2639
2799
|
]
|
|
2640
|
-
}
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm", children: "No threads yet" }),
|
|
2645
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: handleNewThread, children: "Start a conversation" })
|
|
2646
|
-
] }) }) : /* @__PURE__ */ jsx("div", { className: "p-2 space-y-1", children: threads.map((thread) => {
|
|
2647
|
-
const isActive = thread.id === activeThreadId;
|
|
2648
|
-
return /* @__PURE__ */ jsxs(
|
|
2649
|
-
"div",
|
|
2650
|
-
{
|
|
2651
|
-
onClick: () => handleThreadClick(thread.id),
|
|
2652
|
-
className: cn(
|
|
2653
|
-
"group relative flex items-center gap-3 px-3 py-1.5 rounded-lg cursor-pointer transition-colors",
|
|
2654
|
-
isActive ? "bg-muted" : "hover:bg-muted"
|
|
2655
|
-
),
|
|
2656
|
-
children: [
|
|
2657
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
2658
|
-
/* @__PURE__ */ jsx("p", { className: cn("text-sm font-medium truncate"), children: thread.title || `Thread ${thread.id.slice(0, 8)}` }),
|
|
2659
|
-
thread.updatedAt && /* @__PURE__ */ jsx("span", { className: cn("text-xs shrink-0"), children: formatDate(thread.updatedAt) })
|
|
2660
|
-
] }) }),
|
|
2661
|
-
/* @__PURE__ */ jsx(
|
|
2662
|
-
Button,
|
|
2663
|
-
{
|
|
2664
|
-
variant: "ghost",
|
|
2665
|
-
size: "icon-xs",
|
|
2666
|
-
onClick: (e) => handleDelete(e, thread.id),
|
|
2667
|
-
className: cn(
|
|
2668
|
-
"opacity-0 group-hover:opacity-100 transition-opacity shrink-0",
|
|
2669
|
-
isActive && "hover:bg-primary-foreground/20"
|
|
2670
|
-
),
|
|
2671
|
-
children: /* @__PURE__ */ jsx(IconTrash, { className: "size-3" })
|
|
2672
|
-
}
|
|
2673
|
-
)
|
|
2674
|
-
]
|
|
2675
|
-
},
|
|
2676
|
-
thread.id
|
|
2677
|
-
);
|
|
2678
|
-
}) }) })
|
|
2679
|
-
] });
|
|
2800
|
+
},
|
|
2801
|
+
thread.id
|
|
2802
|
+
);
|
|
2803
|
+
}) }) }) });
|
|
2680
2804
|
};
|
|
2681
2805
|
function ChatPopup({
|
|
2682
2806
|
title = "Chat",
|
|
@@ -2805,6 +2929,16 @@ function ChatSidebar({
|
|
|
2805
2929
|
) })
|
|
2806
2930
|
] });
|
|
2807
2931
|
}
|
|
2932
|
+
var ChatSidebarContext = createContext(
|
|
2933
|
+
void 0
|
|
2934
|
+
);
|
|
2935
|
+
function useChatSidebar() {
|
|
2936
|
+
const context = useContext(ChatSidebarContext);
|
|
2937
|
+
if (context === void 0) {
|
|
2938
|
+
throw new Error("useChatSidebar must be used within a ChatSidebarProvider");
|
|
2939
|
+
}
|
|
2940
|
+
return context;
|
|
2941
|
+
}
|
|
2808
2942
|
function ChatFull({
|
|
2809
2943
|
title = "Chat",
|
|
2810
2944
|
placeholder = "Message the AI",
|
|
@@ -2816,134 +2950,134 @@ function ChatFull({
|
|
|
2816
2950
|
rightSidebar,
|
|
2817
2951
|
leftSidebarClassName,
|
|
2818
2952
|
rightSidebarClassName,
|
|
2819
|
-
leftSidebarCollapsible = false,
|
|
2820
|
-
rightSidebarCollapsible = false,
|
|
2821
|
-
defaultLeftSidebarCollapsed = false,
|
|
2822
|
-
defaultRightSidebarCollapsed = false,
|
|
2823
|
-
leftSidebarCollapsed: controlledLeftCollapsed,
|
|
2824
|
-
rightSidebarCollapsed: controlledRightCollapsed,
|
|
2825
|
-
onLeftSidebarCollapseChange,
|
|
2826
|
-
onRightSidebarCollapseChange,
|
|
2827
2953
|
autoFocus = false,
|
|
2828
2954
|
defaultSelectedIds
|
|
2829
2955
|
}) {
|
|
2830
|
-
const
|
|
2831
|
-
|
|
2832
|
-
)
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
);
|
|
2836
|
-
const leftCollapsed = controlledLeftCollapsed !== void 0 ? controlledLeftCollapsed : internalLeftCollapsed;
|
|
2837
|
-
const rightCollapsed = controlledRightCollapsed !== void 0 ? controlledRightCollapsed : internalRightCollapsed;
|
|
2838
|
-
const handleLeftToggle = () => {
|
|
2839
|
-
const newCollapsed = !leftCollapsed;
|
|
2840
|
-
if (controlledLeftCollapsed === void 0) {
|
|
2841
|
-
setInternalLeftCollapsed(newCollapsed);
|
|
2956
|
+
const { isMobile, isTablet } = useScreenSize();
|
|
2957
|
+
const isSmallScreen = isMobile || isTablet;
|
|
2958
|
+
const [internalLeftCollapsed, setInternalLeftCollapsed] = useState(() => {
|
|
2959
|
+
if (typeof window !== "undefined") {
|
|
2960
|
+
return window.innerWidth < 1024;
|
|
2842
2961
|
}
|
|
2843
|
-
|
|
2844
|
-
};
|
|
2845
|
-
const
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
setInternalRightCollapsed(newCollapsed);
|
|
2962
|
+
return false;
|
|
2963
|
+
});
|
|
2964
|
+
const [internalRightCollapsed, setInternalRightCollapsed] = useState(() => {
|
|
2965
|
+
if (typeof window !== "undefined") {
|
|
2966
|
+
return window.innerWidth < 1024;
|
|
2849
2967
|
}
|
|
2850
|
-
|
|
2851
|
-
};
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2968
|
+
return false;
|
|
2969
|
+
});
|
|
2970
|
+
useEffect(() => {
|
|
2971
|
+
if (isSmallScreen) {
|
|
2972
|
+
setInternalLeftCollapsed(true);
|
|
2973
|
+
setInternalRightCollapsed(true);
|
|
2974
|
+
}
|
|
2975
|
+
}, [isSmallScreen]);
|
|
2976
|
+
const leftCollapsed = internalLeftCollapsed;
|
|
2977
|
+
const rightCollapsed = internalRightCollapsed;
|
|
2978
|
+
const handleLeftToggle = useCallback((collapsed) => {
|
|
2979
|
+
setInternalLeftCollapsed(collapsed);
|
|
2980
|
+
}, []);
|
|
2981
|
+
const handleRightToggle = useCallback((collapsed) => {
|
|
2982
|
+
setInternalRightCollapsed(collapsed);
|
|
2983
|
+
}, []);
|
|
2984
|
+
const contextValue = useMemo(
|
|
2985
|
+
() => ({
|
|
2986
|
+
leftCollapsed,
|
|
2987
|
+
rightCollapsed,
|
|
2988
|
+
setLeftCollapsed: handleLeftToggle,
|
|
2989
|
+
setRightCollapsed: handleRightToggle,
|
|
2990
|
+
leftCollapsible: true,
|
|
2991
|
+
rightCollapsible: true
|
|
2992
|
+
}),
|
|
2993
|
+
[leftCollapsed, rightCollapsed, handleLeftToggle, handleRightToggle]
|
|
2994
|
+
);
|
|
2995
|
+
return /* @__PURE__ */ jsx(ChatSidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs(
|
|
2996
|
+
"div",
|
|
2997
|
+
{
|
|
2998
|
+
className: cn("flex flex-col h-full w-full bg-background", className),
|
|
2999
|
+
children: [
|
|
3000
|
+
title && /* @__PURE__ */ jsx(ChatHeader, { title, ...headerProps }),
|
|
3001
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-hidden flex relative", children: [
|
|
3002
|
+
leftSidebar && /* @__PURE__ */ jsx(
|
|
3003
|
+
"div",
|
|
3004
|
+
{
|
|
3005
|
+
className: cn(
|
|
3006
|
+
"flex-shrink-0 border-r border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
|
|
3007
|
+
leftCollapsed ? "w-0 border-r-0 min-w-0" : "",
|
|
3008
|
+
!leftCollapsed && leftSidebarClassName
|
|
3009
|
+
),
|
|
3010
|
+
children: /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: leftSidebar })
|
|
3011
|
+
}
|
|
3012
|
+
),
|
|
3013
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden min-w-0", children: /* @__PURE__ */ jsx(
|
|
3014
|
+
Thread,
|
|
3015
|
+
{
|
|
3016
|
+
placeholder,
|
|
3017
|
+
starterPrompts,
|
|
3018
|
+
options,
|
|
3019
|
+
autoFocus,
|
|
3020
|
+
defaultSelectedIds
|
|
3021
|
+
}
|
|
3022
|
+
) }),
|
|
3023
|
+
rightSidebar && /* @__PURE__ */ jsx(
|
|
3024
|
+
"div",
|
|
3025
|
+
{
|
|
3026
|
+
className: cn(
|
|
3027
|
+
"flex-shrink-0 border-l border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
|
|
3028
|
+
rightCollapsed ? "w-0 border-l-0 min-w-0" : "",
|
|
3029
|
+
!rightCollapsed && rightSidebarClassName
|
|
3030
|
+
),
|
|
3031
|
+
children: /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: rightSidebar })
|
|
3032
|
+
}
|
|
3033
|
+
)
|
|
3034
|
+
] })
|
|
3035
|
+
]
|
|
3036
|
+
}
|
|
3037
|
+
) });
|
|
3038
|
+
}
|
|
3039
|
+
function SidebarToggle({ side, className }) {
|
|
3040
|
+
const {
|
|
3041
|
+
leftCollapsed,
|
|
3042
|
+
rightCollapsed,
|
|
3043
|
+
setLeftCollapsed,
|
|
3044
|
+
setRightCollapsed,
|
|
3045
|
+
leftCollapsible,
|
|
3046
|
+
rightCollapsible
|
|
3047
|
+
} = useChatSidebar();
|
|
3048
|
+
if (side === "left") {
|
|
3049
|
+
if (!leftCollapsible) return null;
|
|
3050
|
+
return /* @__PURE__ */ jsx(
|
|
3051
|
+
Button,
|
|
3052
|
+
{
|
|
3053
|
+
variant: "ghost",
|
|
3054
|
+
onClick: () => setLeftCollapsed(!leftCollapsed),
|
|
3055
|
+
"aria-label": leftCollapsed ? "Expand left sidebar" : "Collapse left sidebar",
|
|
3056
|
+
className: cn("", className),
|
|
3057
|
+
children: leftCollapsed ? /* @__PURE__ */ jsx(IconLayoutSidebarLeftExpand, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(IconLayoutSidebarLeftCollapse, { className: "h-4 w-4" })
|
|
3058
|
+
}
|
|
3059
|
+
);
|
|
3060
|
+
}
|
|
3061
|
+
if (side === "right") {
|
|
3062
|
+
if (!rightCollapsible) return null;
|
|
3063
|
+
return /* @__PURE__ */ jsx(
|
|
3064
|
+
Button,
|
|
3065
|
+
{
|
|
3066
|
+
variant: "ghost",
|
|
3067
|
+
onClick: () => setRightCollapsed(!rightCollapsed),
|
|
3068
|
+
"aria-label": rightCollapsed ? "Expand right sidebar" : "Collapse right sidebar",
|
|
3069
|
+
className: cn("", className),
|
|
3070
|
+
children: rightCollapsed ? /* @__PURE__ */ jsx(IconLayoutSidebarRightExpand, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(IconLayoutSidebarRightCollapse, { className: "h-4 w-4" })
|
|
3071
|
+
}
|
|
3072
|
+
);
|
|
3073
|
+
}
|
|
3074
|
+
return null;
|
|
2941
3075
|
}
|
|
2942
|
-
var PopoverContext =
|
|
3076
|
+
var PopoverContext = React11.createContext(
|
|
2943
3077
|
void 0
|
|
2944
3078
|
);
|
|
2945
3079
|
function usePopoverContext() {
|
|
2946
|
-
const context =
|
|
3080
|
+
const context = React11.useContext(PopoverContext);
|
|
2947
3081
|
if (!context) {
|
|
2948
3082
|
throw new Error("Popover components must be used within a Popover");
|
|
2949
3083
|
}
|
|
@@ -2955,10 +3089,10 @@ function Popover({
|
|
|
2955
3089
|
open: controlledOpen,
|
|
2956
3090
|
onOpenChange
|
|
2957
3091
|
}) {
|
|
2958
|
-
const [internalOpen, setInternalOpen] =
|
|
2959
|
-
const triggerRef =
|
|
3092
|
+
const [internalOpen, setInternalOpen] = React11.useState(defaultOpen);
|
|
3093
|
+
const triggerRef = React11.useRef(null);
|
|
2960
3094
|
const open = controlledOpen ?? internalOpen;
|
|
2961
|
-
const setOpen =
|
|
3095
|
+
const setOpen = React11.useCallback(
|
|
2962
3096
|
(newOpen) => {
|
|
2963
3097
|
if (controlledOpen === void 0) {
|
|
2964
3098
|
setInternalOpen(newOpen);
|
|
@@ -2967,7 +3101,7 @@ function Popover({
|
|
|
2967
3101
|
},
|
|
2968
3102
|
[controlledOpen, onOpenChange]
|
|
2969
3103
|
);
|
|
2970
|
-
const value =
|
|
3104
|
+
const value = React11.useMemo(
|
|
2971
3105
|
() => ({
|
|
2972
3106
|
open,
|
|
2973
3107
|
setOpen,
|
|
@@ -2977,15 +3111,15 @@ function Popover({
|
|
|
2977
3111
|
);
|
|
2978
3112
|
return /* @__PURE__ */ jsx(PopoverContext.Provider, { value, children });
|
|
2979
3113
|
}
|
|
2980
|
-
var PopoverTrigger =
|
|
3114
|
+
var PopoverTrigger = React11.forwardRef(
|
|
2981
3115
|
({ asChild, className, children, ...props }, ref) => {
|
|
2982
3116
|
const { setOpen, triggerRef } = usePopoverContext();
|
|
2983
3117
|
const handleClick = (e) => {
|
|
2984
3118
|
setOpen(true);
|
|
2985
3119
|
props.onClick?.(e);
|
|
2986
3120
|
};
|
|
2987
|
-
if (asChild &&
|
|
2988
|
-
return
|
|
3121
|
+
if (asChild && React11.isValidElement(children)) {
|
|
3122
|
+
return React11.cloneElement(children, {
|
|
2989
3123
|
ref: (node) => {
|
|
2990
3124
|
triggerRef.current = node;
|
|
2991
3125
|
if (typeof children.ref === "function") {
|
|
@@ -3017,7 +3151,7 @@ var PopoverTrigger = React10.forwardRef(
|
|
|
3017
3151
|
}
|
|
3018
3152
|
);
|
|
3019
3153
|
PopoverTrigger.displayName = "PopoverTrigger";
|
|
3020
|
-
var PopoverContent =
|
|
3154
|
+
var PopoverContent = React11.forwardRef(
|
|
3021
3155
|
({
|
|
3022
3156
|
className,
|
|
3023
3157
|
side = "bottom",
|
|
@@ -3028,9 +3162,9 @@ var PopoverContent = React10.forwardRef(
|
|
|
3028
3162
|
...props
|
|
3029
3163
|
}, ref) => {
|
|
3030
3164
|
const { open, setOpen, triggerRef } = usePopoverContext();
|
|
3031
|
-
const [position, setPosition] =
|
|
3032
|
-
const contentRef =
|
|
3033
|
-
|
|
3165
|
+
const [position, setPosition] = React11.useState({ top: 0, left: 0 });
|
|
3166
|
+
const contentRef = React11.useRef(null);
|
|
3167
|
+
React11.useEffect(() => {
|
|
3034
3168
|
if (!open || !triggerRef.current) return;
|
|
3035
3169
|
const updatePosition = () => {
|
|
3036
3170
|
if (!triggerRef.current || !contentRef.current) return;
|
|
@@ -3091,7 +3225,7 @@ var PopoverContent = React10.forwardRef(
|
|
|
3091
3225
|
window.removeEventListener("scroll", updatePosition, true);
|
|
3092
3226
|
};
|
|
3093
3227
|
}, [open, side, align, sideOffset, alignOffset, triggerRef]);
|
|
3094
|
-
|
|
3228
|
+
React11.useEffect(() => {
|
|
3095
3229
|
if (!open) return;
|
|
3096
3230
|
const handleClickOutside = (event) => {
|
|
3097
3231
|
if (contentRef.current && !contentRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
|
|
@@ -3147,7 +3281,7 @@ var ThreadPopover = ({
|
|
|
3147
3281
|
emptyState,
|
|
3148
3282
|
onThreadSelect
|
|
3149
3283
|
}) => {
|
|
3150
|
-
const [isOpen, setIsOpen] =
|
|
3284
|
+
const [isOpen, setIsOpen] = React11.useState(false);
|
|
3151
3285
|
useHotkeys(
|
|
3152
3286
|
"h",
|
|
3153
3287
|
(e) => {
|
|
@@ -3202,7 +3336,7 @@ var CreateThreadButton = ({
|
|
|
3202
3336
|
onThreadCreated
|
|
3203
3337
|
}) => {
|
|
3204
3338
|
const { createThread } = useThreads();
|
|
3205
|
-
const [isCreating, setIsCreating] =
|
|
3339
|
+
const [isCreating, setIsCreating] = React11.useState(false);
|
|
3206
3340
|
const handleCreateThread = async () => {
|
|
3207
3341
|
if (isCreating) return;
|
|
3208
3342
|
try {
|
|
@@ -3328,10 +3462,10 @@ var AccountDialog = ({
|
|
|
3328
3462
|
size
|
|
3329
3463
|
}) => {
|
|
3330
3464
|
const { isLoading, isAuthenticated, user, login, logout } = useAuth();
|
|
3331
|
-
const [open, setOpen] =
|
|
3332
|
-
const [accountInfoOpen, setAccountInfoOpen] =
|
|
3333
|
-
const [error, setError] =
|
|
3334
|
-
const initials =
|
|
3465
|
+
const [open, setOpen] = React11.useState(false);
|
|
3466
|
+
const [accountInfoOpen, setAccountInfoOpen] = React11.useState(false);
|
|
3467
|
+
const [error, setError] = React11.useState(null);
|
|
3468
|
+
const initials = React11.useMemo(() => {
|
|
3335
3469
|
const name = user?.displayName || user?.name;
|
|
3336
3470
|
if (!name) return "";
|
|
3337
3471
|
return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
|
|
@@ -3504,6 +3638,6 @@ function ThemeToggle() {
|
|
|
3504
3638
|
);
|
|
3505
3639
|
}
|
|
3506
3640
|
|
|
3507
|
-
export { AccountDialog, AuthContext, AuthProvider, ChatFull, ChatHeader, ChatPopup, ChatSidebar, Composer, CreateThreadButton, MelonyClientProvider, MelonyContext, ThemeProvider, ThemeToggle, Thread, ThreadContext, ThreadList, ThreadPopover, ThreadProvider, UIRenderer, groupEventsToMessages, useAuth, useMelony, useTheme, useThreads };
|
|
3641
|
+
export { AccountDialog, AuthContext, AuthProvider, Badge2 as Badge, Box, Button2 as Button, Card2 as Card, Chart, ChatFull, ChatHeader, ChatPopup, ChatSidebar, ChatSidebarContext, Checkbox, Col, Composer, CreateThreadButton, Divider, Form, Heading, Image, Input2 as Input, Label2 as Label, List, ListItem, MelonyClientProvider, MelonyContext, RadioGroup, Row, Select2 as Select, SidebarToggle, Spacer, Text, Textarea2 as Textarea, ThemeProvider, ThemeToggle, Thread, ThreadContext, ThreadList, ThreadPopover, ThreadProvider, UIRenderer, groupEventsToMessages, useAuth, useChatSidebar, useMelony, useScreenSize, useTheme, useThreads };
|
|
3508
3642
|
//# sourceMappingURL=index.js.map
|
|
3509
3643
|
//# sourceMappingURL=index.js.map
|