@melony/react 0.1.25 → 0.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/index.cjs +291 -136
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -2
- package/dist/index.d.ts +27 -2
- package/dist/index.js +234 -80
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -242,6 +242,22 @@ interface ChatSidebarProps {
|
|
|
242
242
|
}
|
|
243
243
|
declare function ChatSidebar({ title, placeholder, starterPrompts, options, className, headerProps, defaultSelectedIds, }: ChatSidebarProps): react_jsx_runtime.JSX.Element;
|
|
244
244
|
|
|
245
|
+
interface WelcomeScreenProps {
|
|
246
|
+
title?: string;
|
|
247
|
+
description?: string;
|
|
248
|
+
features?: {
|
|
249
|
+
title: string;
|
|
250
|
+
description: string;
|
|
251
|
+
}[];
|
|
252
|
+
className?: string;
|
|
253
|
+
onLoginClick?: () => void;
|
|
254
|
+
termsUrl?: string;
|
|
255
|
+
privacyUrl?: string;
|
|
256
|
+
imageUrl?: string;
|
|
257
|
+
imageAlt?: string;
|
|
258
|
+
}
|
|
259
|
+
declare function WelcomeScreen({ title, description, features, className, onLoginClick, termsUrl, privacyUrl, imageUrl, imageAlt, }: WelcomeScreenProps): react_jsx_runtime.JSX.Element;
|
|
260
|
+
|
|
245
261
|
interface ChatFullProps {
|
|
246
262
|
title?: string;
|
|
247
263
|
placeholder?: string;
|
|
@@ -276,8 +292,17 @@ interface ChatFullProps {
|
|
|
276
292
|
* IDs of options to be selected by default
|
|
277
293
|
*/
|
|
278
294
|
defaultSelectedIds?: string[];
|
|
295
|
+
/**
|
|
296
|
+
* Whether to show a welcome screen when the user is not authenticated.
|
|
297
|
+
* Defaults to false.
|
|
298
|
+
*/
|
|
299
|
+
showWelcomeScreen?: boolean;
|
|
300
|
+
/**
|
|
301
|
+
* Props to customize the welcome screen
|
|
302
|
+
*/
|
|
303
|
+
welcomeScreenProps?: WelcomeScreenProps;
|
|
279
304
|
}
|
|
280
|
-
declare function ChatFull({ title, placeholder, starterPrompts, options, className, headerProps, leftSidebar, rightSidebar, leftSidebarClassName, rightSidebarClassName, autoFocus, defaultSelectedIds, }: ChatFullProps): react_jsx_runtime.JSX.Element;
|
|
305
|
+
declare function ChatFull({ title, placeholder, starterPrompts, options, className, headerProps, leftSidebar, rightSidebar, leftSidebarClassName, rightSidebarClassName, autoFocus, defaultSelectedIds, showWelcomeScreen, welcomeScreenProps, }: ChatFullProps): react_jsx_runtime.JSX.Element;
|
|
281
306
|
|
|
282
307
|
interface SidebarToggleProps {
|
|
283
308
|
side: "left" | "right";
|
|
@@ -473,4 +498,4 @@ declare const Badge: React__default.FC<BadgeProps>;
|
|
|
473
498
|
|
|
474
499
|
declare function groupEventsToMessages(events: Event[]): Message[];
|
|
475
500
|
|
|
476
|
-
export { AccountDialog, type AccountDialogProps, AuthContext, type AuthContextValue, AuthProvider, type AuthProviderProps, type AuthService, Badge, Box, Button, Card, Chart, ChatFull, type ChatFullProps, ChatHeader, type ChatHeaderProps, ChatPopup, type ChatPopupProps, ChatSidebar, ChatSidebarContext, type ChatSidebarContextValue, type ChatSidebarProps, Checkbox, Col, Composer, type ComposerOption, type ComposerOptionGroup, CreateThreadButton, type CreateThreadButtonProps, Divider, Form, Heading, Image, Input, Label, List, ListItem, MelonyClientProvider, type MelonyClientProviderProps, MelonyContext, type MelonyContextValue, type Message, RadioGroup, Row, type ScreenSize, Select, SidebarToggle, type SidebarToggleProps, Spacer, type StarterPrompt, Text, Textarea, ThemeProvider, ThemeToggle, Thread, ThreadContext, type ThreadContextValue, type ThreadData, ThreadList, type ThreadListProps, ThreadPopover, type ThreadPopoverProps, ThreadProvider, type ThreadProviderProps, type ThreadService, UIRenderer, type UIRendererProps, type UseMelonyOptions, type User, groupEventsToMessages, useAuth, useChatSidebar, useMelony, useScreenSize, useTheme, useThreads };
|
|
501
|
+
export { AccountDialog, type AccountDialogProps, AuthContext, type AuthContextValue, AuthProvider, type AuthProviderProps, type AuthService, Badge, Box, Button, Card, Chart, ChatFull, type ChatFullProps, ChatHeader, type ChatHeaderProps, ChatPopup, type ChatPopupProps, ChatSidebar, ChatSidebarContext, type ChatSidebarContextValue, type ChatSidebarProps, Checkbox, Col, Composer, type ComposerOption, type ComposerOptionGroup, CreateThreadButton, type CreateThreadButtonProps, Divider, Form, Heading, Image, Input, Label, List, ListItem, MelonyClientProvider, type MelonyClientProviderProps, MelonyContext, type MelonyContextValue, type Message, RadioGroup, Row, type ScreenSize, Select, SidebarToggle, type SidebarToggleProps, Spacer, type StarterPrompt, Text, Textarea, ThemeProvider, ThemeToggle, Thread, ThreadContext, type ThreadContextValue, type ThreadData, ThreadList, type ThreadListProps, ThreadPopover, type ThreadPopoverProps, ThreadProvider, type ThreadProviderProps, type ThreadService, UIRenderer, type UIRendererProps, type UseMelonyOptions, type User, WelcomeScreen, type WelcomeScreenProps, groupEventsToMessages, useAuth, useChatSidebar, useMelony, useScreenSize, useTheme, useThreads };
|
package/dist/index.d.ts
CHANGED
|
@@ -242,6 +242,22 @@ interface ChatSidebarProps {
|
|
|
242
242
|
}
|
|
243
243
|
declare function ChatSidebar({ title, placeholder, starterPrompts, options, className, headerProps, defaultSelectedIds, }: ChatSidebarProps): react_jsx_runtime.JSX.Element;
|
|
244
244
|
|
|
245
|
+
interface WelcomeScreenProps {
|
|
246
|
+
title?: string;
|
|
247
|
+
description?: string;
|
|
248
|
+
features?: {
|
|
249
|
+
title: string;
|
|
250
|
+
description: string;
|
|
251
|
+
}[];
|
|
252
|
+
className?: string;
|
|
253
|
+
onLoginClick?: () => void;
|
|
254
|
+
termsUrl?: string;
|
|
255
|
+
privacyUrl?: string;
|
|
256
|
+
imageUrl?: string;
|
|
257
|
+
imageAlt?: string;
|
|
258
|
+
}
|
|
259
|
+
declare function WelcomeScreen({ title, description, features, className, onLoginClick, termsUrl, privacyUrl, imageUrl, imageAlt, }: WelcomeScreenProps): react_jsx_runtime.JSX.Element;
|
|
260
|
+
|
|
245
261
|
interface ChatFullProps {
|
|
246
262
|
title?: string;
|
|
247
263
|
placeholder?: string;
|
|
@@ -276,8 +292,17 @@ interface ChatFullProps {
|
|
|
276
292
|
* IDs of options to be selected by default
|
|
277
293
|
*/
|
|
278
294
|
defaultSelectedIds?: string[];
|
|
295
|
+
/**
|
|
296
|
+
* Whether to show a welcome screen when the user is not authenticated.
|
|
297
|
+
* Defaults to false.
|
|
298
|
+
*/
|
|
299
|
+
showWelcomeScreen?: boolean;
|
|
300
|
+
/**
|
|
301
|
+
* Props to customize the welcome screen
|
|
302
|
+
*/
|
|
303
|
+
welcomeScreenProps?: WelcomeScreenProps;
|
|
279
304
|
}
|
|
280
|
-
declare function ChatFull({ title, placeholder, starterPrompts, options, className, headerProps, leftSidebar, rightSidebar, leftSidebarClassName, rightSidebarClassName, autoFocus, defaultSelectedIds, }: ChatFullProps): react_jsx_runtime.JSX.Element;
|
|
305
|
+
declare function ChatFull({ title, placeholder, starterPrompts, options, className, headerProps, leftSidebar, rightSidebar, leftSidebarClassName, rightSidebarClassName, autoFocus, defaultSelectedIds, showWelcomeScreen, welcomeScreenProps, }: ChatFullProps): react_jsx_runtime.JSX.Element;
|
|
281
306
|
|
|
282
307
|
interface SidebarToggleProps {
|
|
283
308
|
side: "left" | "right";
|
|
@@ -473,4 +498,4 @@ declare const Badge: React__default.FC<BadgeProps>;
|
|
|
473
498
|
|
|
474
499
|
declare function groupEventsToMessages(events: Event[]): Message[];
|
|
475
500
|
|
|
476
|
-
export { AccountDialog, type AccountDialogProps, AuthContext, type AuthContextValue, AuthProvider, type AuthProviderProps, type AuthService, Badge, Box, Button, Card, Chart, ChatFull, type ChatFullProps, ChatHeader, type ChatHeaderProps, ChatPopup, type ChatPopupProps, ChatSidebar, ChatSidebarContext, type ChatSidebarContextValue, type ChatSidebarProps, Checkbox, Col, Composer, type ComposerOption, type ComposerOptionGroup, CreateThreadButton, type CreateThreadButtonProps, Divider, Form, Heading, Image, Input, Label, List, ListItem, MelonyClientProvider, type MelonyClientProviderProps, MelonyContext, type MelonyContextValue, type Message, RadioGroup, Row, type ScreenSize, Select, SidebarToggle, type SidebarToggleProps, Spacer, type StarterPrompt, Text, Textarea, ThemeProvider, ThemeToggle, Thread, ThreadContext, type ThreadContextValue, type ThreadData, ThreadList, type ThreadListProps, ThreadPopover, type ThreadPopoverProps, ThreadProvider, type ThreadProviderProps, type ThreadService, UIRenderer, type UIRendererProps, type UseMelonyOptions, type User, groupEventsToMessages, useAuth, useChatSidebar, useMelony, useScreenSize, useTheme, useThreads };
|
|
501
|
+
export { AccountDialog, type AccountDialogProps, AuthContext, type AuthContextValue, AuthProvider, type AuthProviderProps, type AuthService, Badge, Box, Button, Card, Chart, ChatFull, type ChatFullProps, ChatHeader, type ChatHeaderProps, ChatPopup, type ChatPopupProps, ChatSidebar, ChatSidebarContext, type ChatSidebarContextValue, type ChatSidebarProps, Checkbox, Col, Composer, type ComposerOption, type ComposerOptionGroup, CreateThreadButton, type CreateThreadButtonProps, Divider, Form, Heading, Image, Input, Label, List, ListItem, MelonyClientProvider, type MelonyClientProviderProps, MelonyContext, type MelonyContextValue, type Message, RadioGroup, Row, type ScreenSize, Select, SidebarToggle, type SidebarToggleProps, Spacer, type StarterPrompt, Text, Textarea, ThemeProvider, ThemeToggle, Thread, ThreadContext, type ThreadContextValue, type ThreadData, ThreadList, type ThreadListProps, ThreadPopover, type ThreadPopoverProps, ThreadProvider, type ThreadProviderProps, type ThreadService, UIRenderer, type UIRendererProps, type UseMelonyOptions, type User, WelcomeScreen, type WelcomeScreenProps, groupEventsToMessages, useAuth, useChatSidebar, useMelony, useScreenSize, useTheme, useThreads };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React12 from 'react';
|
|
2
|
+
import React12__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';
|
|
@@ -12,7 +12,7 @@ import { cva } from 'class-variance-authority';
|
|
|
12
12
|
import { mergeProps } from '@base-ui/react/merge-props';
|
|
13
13
|
import { useRender } from '@base-ui/react/use-render';
|
|
14
14
|
import * as ICONS from '@tabler/icons-react';
|
|
15
|
-
import { IconPaperclip, IconX, IconPlus, IconChevronDown, IconLoader2, IconArrowUp, IconMessage, IconTrash, IconHistory, IconArrowLeft, IconLayoutSidebarLeftExpand, IconLayoutSidebarLeftCollapse, IconLayoutSidebarRightExpand, IconLayoutSidebarRightCollapse, IconUser, IconLogout,
|
|
15
|
+
import { IconPaperclip, IconX, IconPlus, IconChevronDown, IconLoader2, IconArrowUp, IconMessage, IconDotsVertical, IconTrash, IconHistory, IconArrowLeft, IconBrandGoogle, IconLayoutSidebarLeftExpand, IconLayoutSidebarLeftCollapse, IconLayoutSidebarRightExpand, IconLayoutSidebarRightCollapse, IconUser, IconLogout, IconDeviceDesktop, IconMoon, IconSun, IconCheck, IconSelector, IconChevronUp } from '@tabler/icons-react';
|
|
16
16
|
import { Menu } from '@base-ui/react/menu';
|
|
17
17
|
import { Separator as Separator$1 } from '@base-ui/react/separator';
|
|
18
18
|
import { Dialog as Dialog$1 } from '@base-ui/react/dialog';
|
|
@@ -685,11 +685,11 @@ function Composer({
|
|
|
685
685
|
const accept = fileAttachments?.accept;
|
|
686
686
|
const maxFiles = fileAttachments?.maxFiles ?? 10;
|
|
687
687
|
const maxFileSize = fileAttachments?.maxFileSize ?? 10 * 1024 * 1024;
|
|
688
|
-
const [selectedOptions, setSelectedOptions] =
|
|
688
|
+
const [selectedOptions, setSelectedOptions] = React12__default.useState(
|
|
689
689
|
() => new Set(defaultSelectedIds)
|
|
690
690
|
);
|
|
691
|
-
const [attachedFiles, setAttachedFiles] =
|
|
692
|
-
const fileInputRef =
|
|
691
|
+
const [attachedFiles, setAttachedFiles] = React12__default.useState([]);
|
|
692
|
+
const fileInputRef = React12__default.useRef(null);
|
|
693
693
|
const toggleOption = (id, groupOptions, type = "multiple") => {
|
|
694
694
|
const next = new Set(selectedOptions);
|
|
695
695
|
if (type === "single") {
|
|
@@ -2728,14 +2728,20 @@ var ThreadList = ({
|
|
|
2728
2728
|
deleteThread,
|
|
2729
2729
|
isLoading
|
|
2730
2730
|
} = useThreads();
|
|
2731
|
+
const sortedThreads = React12.useMemo(() => {
|
|
2732
|
+
return [...threads].sort((a, b) => {
|
|
2733
|
+
const dateA = a.updatedAt ? new Date(a.updatedAt).getTime() : 0;
|
|
2734
|
+
const dateB = b.updatedAt ? new Date(b.updatedAt).getTime() : 0;
|
|
2735
|
+
return dateB - dateA;
|
|
2736
|
+
});
|
|
2737
|
+
}, [threads]);
|
|
2731
2738
|
const handleThreadClick = (threadId) => {
|
|
2732
2739
|
if (threadId !== activeThreadId) {
|
|
2733
2740
|
selectThread(threadId);
|
|
2734
2741
|
}
|
|
2735
2742
|
onThreadSelect?.(threadId);
|
|
2736
2743
|
};
|
|
2737
|
-
const handleDelete = async (
|
|
2738
|
-
e.stopPropagation();
|
|
2744
|
+
const handleDelete = async (threadId) => {
|
|
2739
2745
|
try {
|
|
2740
2746
|
await deleteThread(threadId);
|
|
2741
2747
|
} catch (error) {
|
|
@@ -2749,58 +2755,75 @@ var ThreadList = ({
|
|
|
2749
2755
|
console.error("Failed to create thread:", error);
|
|
2750
2756
|
}
|
|
2751
2757
|
};
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
if (isNaN(d.getTime())) return "";
|
|
2756
|
-
const now = /* @__PURE__ */ new Date();
|
|
2757
|
-
const diffMs = now.getTime() - d.getTime();
|
|
2758
|
-
const diffMins = Math.floor(diffMs / 6e4);
|
|
2759
|
-
const diffHours = Math.floor(diffMs / 36e5);
|
|
2760
|
-
const diffDays = Math.floor(diffMs / 864e5);
|
|
2761
|
-
if (diffMins < 1) return "Just now";
|
|
2762
|
-
if (diffMins < 60) return `${diffMins}m ago`;
|
|
2763
|
-
if (diffHours < 24) return `${diffHours}h ago`;
|
|
2764
|
-
if (diffDays < 7) return `${diffDays}d ago`;
|
|
2765
|
-
return d.toLocaleDateString();
|
|
2766
|
-
};
|
|
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",
|
|
2758
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col h-full", className), children: [
|
|
2759
|
+
/* @__PURE__ */ jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxs(
|
|
2760
|
+
Button,
|
|
2775
2761
|
{
|
|
2776
|
-
|
|
2777
|
-
className:
|
|
2778
|
-
|
|
2779
|
-
isActive ? "bg-muted" : "hover:bg-muted"
|
|
2780
|
-
),
|
|
2762
|
+
variant: "outline",
|
|
2763
|
+
className: "w-full justify-start gap-2 h-9 px-3 border-dashed hover:border-solid transition-all",
|
|
2764
|
+
onClick: handleNewThread,
|
|
2781
2765
|
children: [
|
|
2782
|
-
/* @__PURE__ */ jsx(
|
|
2783
|
-
|
|
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
|
-
)
|
|
2766
|
+
/* @__PURE__ */ jsx(IconPlus, { className: "size-4" }),
|
|
2767
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "New chat" })
|
|
2799
2768
|
]
|
|
2800
|
-
}
|
|
2801
|
-
|
|
2802
|
-
)
|
|
2803
|
-
|
|
2769
|
+
}
|
|
2770
|
+
) }),
|
|
2771
|
+
/* @__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: [
|
|
2772
|
+
/* @__PURE__ */ jsx(IconMessage, { className: "size-8 mx-auto opacity-50" }),
|
|
2773
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm", children: "No threads yet" }),
|
|
2774
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: handleNewThread, children: "Start a conversation" })
|
|
2775
|
+
] }) }) : /* @__PURE__ */ jsx("div", { className: "p-2 space-y-1", children: sortedThreads.map((thread) => {
|
|
2776
|
+
const isActive = thread.id === activeThreadId;
|
|
2777
|
+
return /* @__PURE__ */ jsxs(
|
|
2778
|
+
"div",
|
|
2779
|
+
{
|
|
2780
|
+
onClick: () => handleThreadClick(thread.id),
|
|
2781
|
+
className: cn(
|
|
2782
|
+
"group relative flex items-center gap-3 px-3 py-1.5 rounded-lg cursor-pointer transition-colors",
|
|
2783
|
+
isActive ? "bg-muted text-foreground" : "hover:bg-muted/50 text-muted-foreground hover:text-foreground"
|
|
2784
|
+
),
|
|
2785
|
+
children: [
|
|
2786
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium truncate", children: thread.title || `Thread ${thread.id.slice(0, 8)}` }) }),
|
|
2787
|
+
/* @__PURE__ */ jsx("div", { className: "shrink-0 flex items-center opacity-0 group-hover:opacity-100 transition-opacity", children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
2788
|
+
/* @__PURE__ */ jsx(
|
|
2789
|
+
DropdownMenuTrigger,
|
|
2790
|
+
{
|
|
2791
|
+
render: (props) => /* @__PURE__ */ jsx(
|
|
2792
|
+
Button,
|
|
2793
|
+
{
|
|
2794
|
+
variant: "ghost",
|
|
2795
|
+
size: "icon-xs",
|
|
2796
|
+
...props,
|
|
2797
|
+
onClick: (e) => {
|
|
2798
|
+
e.stopPropagation();
|
|
2799
|
+
props.onClick?.(e);
|
|
2800
|
+
},
|
|
2801
|
+
children: /* @__PURE__ */ jsx(IconDotsVertical, { className: "size-3.5" })
|
|
2802
|
+
}
|
|
2803
|
+
)
|
|
2804
|
+
}
|
|
2805
|
+
),
|
|
2806
|
+
/* @__PURE__ */ jsx(DropdownMenuContent, { align: "start", className: "w-32", children: /* @__PURE__ */ jsxs(
|
|
2807
|
+
DropdownMenuItem,
|
|
2808
|
+
{
|
|
2809
|
+
variant: "destructive",
|
|
2810
|
+
onClick: (e) => {
|
|
2811
|
+
e.stopPropagation();
|
|
2812
|
+
handleDelete(thread.id);
|
|
2813
|
+
},
|
|
2814
|
+
children: [
|
|
2815
|
+
/* @__PURE__ */ jsx(IconTrash, { className: "size-4 mr-2" }),
|
|
2816
|
+
/* @__PURE__ */ jsx("span", { children: "Delete" })
|
|
2817
|
+
]
|
|
2818
|
+
}
|
|
2819
|
+
) })
|
|
2820
|
+
] }) })
|
|
2821
|
+
]
|
|
2822
|
+
},
|
|
2823
|
+
thread.id
|
|
2824
|
+
);
|
|
2825
|
+
}) }) })
|
|
2826
|
+
] });
|
|
2804
2827
|
};
|
|
2805
2828
|
function ChatPopup({
|
|
2806
2829
|
title = "Chat",
|
|
@@ -2939,9 +2962,134 @@ function useChatSidebar() {
|
|
|
2939
2962
|
}
|
|
2940
2963
|
return context;
|
|
2941
2964
|
}
|
|
2965
|
+
function WelcomeScreen({
|
|
2966
|
+
title = "Welcome to Melony",
|
|
2967
|
+
description = "The most powerful AI agent framework for building modern applications. Connect your tools, build your brain, and ship faster.",
|
|
2968
|
+
features = [
|
|
2969
|
+
{
|
|
2970
|
+
title: "Context Aware",
|
|
2971
|
+
description: "Built-in state management for complex LLM flows."
|
|
2972
|
+
},
|
|
2973
|
+
{
|
|
2974
|
+
title: "Extensible",
|
|
2975
|
+
description: "Plugin architecture for easy integrations."
|
|
2976
|
+
},
|
|
2977
|
+
{
|
|
2978
|
+
title: "Real-time",
|
|
2979
|
+
description: "Streaming responses and live state updates."
|
|
2980
|
+
},
|
|
2981
|
+
{
|
|
2982
|
+
title: "Tool-ready",
|
|
2983
|
+
description: "Ready-to-use actions for common tasks."
|
|
2984
|
+
}
|
|
2985
|
+
],
|
|
2986
|
+
className,
|
|
2987
|
+
onLoginClick,
|
|
2988
|
+
termsUrl = "#",
|
|
2989
|
+
privacyUrl = "#",
|
|
2990
|
+
imageUrl,
|
|
2991
|
+
imageAlt = "Product screenshot"
|
|
2992
|
+
}) {
|
|
2993
|
+
const { login, isLoading } = useAuth();
|
|
2994
|
+
const handleLogin = () => {
|
|
2995
|
+
if (onLoginClick) {
|
|
2996
|
+
onLoginClick();
|
|
2997
|
+
} else {
|
|
2998
|
+
login();
|
|
2999
|
+
}
|
|
3000
|
+
};
|
|
3001
|
+
return /* @__PURE__ */ jsxs(
|
|
3002
|
+
"div",
|
|
3003
|
+
{
|
|
3004
|
+
className: cn(
|
|
3005
|
+
"flex min-h-[600px] h-full w-full flex-col md:flex-row bg-background overflow-hidden",
|
|
3006
|
+
className
|
|
3007
|
+
),
|
|
3008
|
+
children: [
|
|
3009
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col bg-sidebar text-foreground relative overflow-hidden", children: [
|
|
3010
|
+
/* @__PURE__ */ jsx("div", { className: "absolute -top-24 -left-24 size-96 bg-primary/5 rounded-full blur-3xl" }),
|
|
3011
|
+
/* @__PURE__ */ jsx("div", { className: "absolute -bottom-24 -right-24 size-96 bg-primary/5 rounded-full blur-3xl" }),
|
|
3012
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto overflow-x-hidden relative z-10 flex flex-col p-8 md:p-12 lg:p-20", children: /* @__PURE__ */ jsxs("div", { className: "max-w-xl mx-auto w-full", children: [
|
|
3013
|
+
/* @__PURE__ */ jsx("h1", { className: "mb-6 text-4xl font-bold tracking-tight md:text-5xl lg:text-6xl text-foreground", children: title }),
|
|
3014
|
+
/* @__PURE__ */ jsx("p", { className: "mb-12 text-lg text-muted-foreground md:text-xl leading-relaxed", children: description }),
|
|
3015
|
+
imageUrl && /* @__PURE__ */ jsxs("div", { className: "mb-12 relative group", children: [
|
|
3016
|
+
/* @__PURE__ */ jsx("div", { className: "absolute -inset-1 bg-gradient-to-r from-primary/20 to-primary/10 rounded-xl blur opacity-25 group-hover:opacity-50 transition duration-1000 group-hover:duration-200" }),
|
|
3017
|
+
/* @__PURE__ */ jsx(
|
|
3018
|
+
"img",
|
|
3019
|
+
{
|
|
3020
|
+
src: imageUrl,
|
|
3021
|
+
alt: imageAlt,
|
|
3022
|
+
className: "relative rounded-xl border border-border/50 shadow-2xl transition-transform duration-500 hover:scale-[1.02] w-full"
|
|
3023
|
+
}
|
|
3024
|
+
)
|
|
3025
|
+
] }),
|
|
3026
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-x-8 gap-y-10 sm:grid-cols-2", children: features.map((feature, i) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
3027
|
+
/* @__PURE__ */ jsx("h3", { className: "font-bold text-lg text-foreground", children: feature.title }),
|
|
3028
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground leading-relaxed", children: feature.description })
|
|
3029
|
+
] }, i)) })
|
|
3030
|
+
] }) })
|
|
3031
|
+
] }),
|
|
3032
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-center justify-center p-8 md:p-12 lg:p-20 bg-background transition-colors duration-300", children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-sm space-y-8", children: [
|
|
3033
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-3 text-center md:text-left", children: [
|
|
3034
|
+
/* @__PURE__ */ jsx("h2", { className: "text-3xl font-bold tracking-tight text-foreground", children: "Get Started" }),
|
|
3035
|
+
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-lg", children: "Sign in to your account to continue" })
|
|
3036
|
+
] }),
|
|
3037
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
3038
|
+
/* @__PURE__ */ jsxs(
|
|
3039
|
+
Button,
|
|
3040
|
+
{
|
|
3041
|
+
size: "lg",
|
|
3042
|
+
variant: "outline",
|
|
3043
|
+
className: "w-full h-16 text-lg shadow-sm hover:shadow-md transition-all flex items-center justify-center gap-3 border-2 font-medium bg-background text-foreground hover:bg-accent",
|
|
3044
|
+
onClick: handleLogin,
|
|
3045
|
+
disabled: isLoading,
|
|
3046
|
+
children: [
|
|
3047
|
+
/* @__PURE__ */ jsx(IconBrandGoogle, { className: "size-6" }),
|
|
3048
|
+
isLoading ? "Signing in..." : "Continue with Google"
|
|
3049
|
+
]
|
|
3050
|
+
}
|
|
3051
|
+
),
|
|
3052
|
+
/* @__PURE__ */ jsxs("div", { className: "relative py-4", children: [
|
|
3053
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ jsx("span", { className: "w-full border-t border-border" }) }),
|
|
3054
|
+
/* @__PURE__ */ jsx("div", { className: "relative flex justify-center text-xs uppercase", children: /* @__PURE__ */ jsx("span", { className: "bg-background px-3 text-muted-foreground tracking-widest font-medium", children: "Secure access" }) })
|
|
3055
|
+
] })
|
|
3056
|
+
] }),
|
|
3057
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground leading-relaxed text-center md:text-left", children: [
|
|
3058
|
+
"By continuing, you agree to our ",
|
|
3059
|
+
/* @__PURE__ */ jsx("br", { className: "hidden md:block" }),
|
|
3060
|
+
/* @__PURE__ */ jsx(
|
|
3061
|
+
"a",
|
|
3062
|
+
{
|
|
3063
|
+
href: termsUrl,
|
|
3064
|
+
target: "_blank",
|
|
3065
|
+
rel: "noopener noreferrer",
|
|
3066
|
+
className: "underline underline-offset-4 hover:text-primary transition-colors font-medium",
|
|
3067
|
+
children: "Terms of Service"
|
|
3068
|
+
}
|
|
3069
|
+
),
|
|
3070
|
+
" ",
|
|
3071
|
+
"and",
|
|
3072
|
+
" ",
|
|
3073
|
+
/* @__PURE__ */ jsx(
|
|
3074
|
+
"a",
|
|
3075
|
+
{
|
|
3076
|
+
href: privacyUrl,
|
|
3077
|
+
target: "_blank",
|
|
3078
|
+
rel: "noopener noreferrer",
|
|
3079
|
+
className: "underline underline-offset-4 hover:text-primary transition-colors font-medium",
|
|
3080
|
+
children: "Privacy Policy"
|
|
3081
|
+
}
|
|
3082
|
+
),
|
|
3083
|
+
"."
|
|
3084
|
+
] })
|
|
3085
|
+
] }) })
|
|
3086
|
+
]
|
|
3087
|
+
}
|
|
3088
|
+
);
|
|
3089
|
+
}
|
|
2942
3090
|
function ChatFull({
|
|
2943
3091
|
title = "Chat",
|
|
2944
|
-
placeholder
|
|
3092
|
+
placeholder,
|
|
2945
3093
|
starterPrompts,
|
|
2946
3094
|
options,
|
|
2947
3095
|
className,
|
|
@@ -2951,9 +3099,12 @@ function ChatFull({
|
|
|
2951
3099
|
leftSidebarClassName,
|
|
2952
3100
|
rightSidebarClassName,
|
|
2953
3101
|
autoFocus = false,
|
|
2954
|
-
defaultSelectedIds
|
|
3102
|
+
defaultSelectedIds,
|
|
3103
|
+
showWelcomeScreen = false,
|
|
3104
|
+
welcomeScreenProps
|
|
2955
3105
|
}) {
|
|
2956
3106
|
const { isMobile, isTablet } = useScreenSize();
|
|
3107
|
+
const { isAuthenticated, isLoading } = useAuth();
|
|
2957
3108
|
const isSmallScreen = isMobile || isTablet;
|
|
2958
3109
|
const [internalLeftCollapsed, setInternalLeftCollapsed] = useState(() => {
|
|
2959
3110
|
if (typeof window !== "undefined") {
|
|
@@ -2992,6 +3143,9 @@ function ChatFull({
|
|
|
2992
3143
|
}),
|
|
2993
3144
|
[leftCollapsed, rightCollapsed, handleLeftToggle, handleRightToggle]
|
|
2994
3145
|
);
|
|
3146
|
+
if (showWelcomeScreen && !isAuthenticated && !isLoading) {
|
|
3147
|
+
return /* @__PURE__ */ jsx(WelcomeScreen, { ...welcomeScreenProps });
|
|
3148
|
+
}
|
|
2995
3149
|
return /* @__PURE__ */ jsx(ChatSidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs(
|
|
2996
3150
|
"div",
|
|
2997
3151
|
{
|
|
@@ -3073,11 +3227,11 @@ function SidebarToggle({ side, className }) {
|
|
|
3073
3227
|
}
|
|
3074
3228
|
return null;
|
|
3075
3229
|
}
|
|
3076
|
-
var PopoverContext =
|
|
3230
|
+
var PopoverContext = React12.createContext(
|
|
3077
3231
|
void 0
|
|
3078
3232
|
);
|
|
3079
3233
|
function usePopoverContext() {
|
|
3080
|
-
const context =
|
|
3234
|
+
const context = React12.useContext(PopoverContext);
|
|
3081
3235
|
if (!context) {
|
|
3082
3236
|
throw new Error("Popover components must be used within a Popover");
|
|
3083
3237
|
}
|
|
@@ -3089,10 +3243,10 @@ function Popover({
|
|
|
3089
3243
|
open: controlledOpen,
|
|
3090
3244
|
onOpenChange
|
|
3091
3245
|
}) {
|
|
3092
|
-
const [internalOpen, setInternalOpen] =
|
|
3093
|
-
const triggerRef =
|
|
3246
|
+
const [internalOpen, setInternalOpen] = React12.useState(defaultOpen);
|
|
3247
|
+
const triggerRef = React12.useRef(null);
|
|
3094
3248
|
const open = controlledOpen ?? internalOpen;
|
|
3095
|
-
const setOpen =
|
|
3249
|
+
const setOpen = React12.useCallback(
|
|
3096
3250
|
(newOpen) => {
|
|
3097
3251
|
if (controlledOpen === void 0) {
|
|
3098
3252
|
setInternalOpen(newOpen);
|
|
@@ -3101,7 +3255,7 @@ function Popover({
|
|
|
3101
3255
|
},
|
|
3102
3256
|
[controlledOpen, onOpenChange]
|
|
3103
3257
|
);
|
|
3104
|
-
const value =
|
|
3258
|
+
const value = React12.useMemo(
|
|
3105
3259
|
() => ({
|
|
3106
3260
|
open,
|
|
3107
3261
|
setOpen,
|
|
@@ -3111,15 +3265,15 @@ function Popover({
|
|
|
3111
3265
|
);
|
|
3112
3266
|
return /* @__PURE__ */ jsx(PopoverContext.Provider, { value, children });
|
|
3113
3267
|
}
|
|
3114
|
-
var PopoverTrigger =
|
|
3268
|
+
var PopoverTrigger = React12.forwardRef(
|
|
3115
3269
|
({ asChild, className, children, ...props }, ref) => {
|
|
3116
3270
|
const { setOpen, triggerRef } = usePopoverContext();
|
|
3117
3271
|
const handleClick = (e) => {
|
|
3118
3272
|
setOpen(true);
|
|
3119
3273
|
props.onClick?.(e);
|
|
3120
3274
|
};
|
|
3121
|
-
if (asChild &&
|
|
3122
|
-
return
|
|
3275
|
+
if (asChild && React12.isValidElement(children)) {
|
|
3276
|
+
return React12.cloneElement(children, {
|
|
3123
3277
|
ref: (node) => {
|
|
3124
3278
|
triggerRef.current = node;
|
|
3125
3279
|
if (typeof children.ref === "function") {
|
|
@@ -3151,7 +3305,7 @@ var PopoverTrigger = React11.forwardRef(
|
|
|
3151
3305
|
}
|
|
3152
3306
|
);
|
|
3153
3307
|
PopoverTrigger.displayName = "PopoverTrigger";
|
|
3154
|
-
var PopoverContent =
|
|
3308
|
+
var PopoverContent = React12.forwardRef(
|
|
3155
3309
|
({
|
|
3156
3310
|
className,
|
|
3157
3311
|
side = "bottom",
|
|
@@ -3162,9 +3316,9 @@ var PopoverContent = React11.forwardRef(
|
|
|
3162
3316
|
...props
|
|
3163
3317
|
}, ref) => {
|
|
3164
3318
|
const { open, setOpen, triggerRef } = usePopoverContext();
|
|
3165
|
-
const [position, setPosition] =
|
|
3166
|
-
const contentRef =
|
|
3167
|
-
|
|
3319
|
+
const [position, setPosition] = React12.useState({ top: 0, left: 0 });
|
|
3320
|
+
const contentRef = React12.useRef(null);
|
|
3321
|
+
React12.useEffect(() => {
|
|
3168
3322
|
if (!open || !triggerRef.current) return;
|
|
3169
3323
|
const updatePosition = () => {
|
|
3170
3324
|
if (!triggerRef.current || !contentRef.current) return;
|
|
@@ -3225,7 +3379,7 @@ var PopoverContent = React11.forwardRef(
|
|
|
3225
3379
|
window.removeEventListener("scroll", updatePosition, true);
|
|
3226
3380
|
};
|
|
3227
3381
|
}, [open, side, align, sideOffset, alignOffset, triggerRef]);
|
|
3228
|
-
|
|
3382
|
+
React12.useEffect(() => {
|
|
3229
3383
|
if (!open) return;
|
|
3230
3384
|
const handleClickOutside = (event) => {
|
|
3231
3385
|
if (contentRef.current && !contentRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
|
|
@@ -3281,7 +3435,7 @@ var ThreadPopover = ({
|
|
|
3281
3435
|
emptyState,
|
|
3282
3436
|
onThreadSelect
|
|
3283
3437
|
}) => {
|
|
3284
|
-
const [isOpen, setIsOpen] =
|
|
3438
|
+
const [isOpen, setIsOpen] = React12.useState(false);
|
|
3285
3439
|
useHotkeys(
|
|
3286
3440
|
"h",
|
|
3287
3441
|
(e) => {
|
|
@@ -3336,7 +3490,7 @@ var CreateThreadButton = ({
|
|
|
3336
3490
|
onThreadCreated
|
|
3337
3491
|
}) => {
|
|
3338
3492
|
const { createThread } = useThreads();
|
|
3339
|
-
const [isCreating, setIsCreating] =
|
|
3493
|
+
const [isCreating, setIsCreating] = React12.useState(false);
|
|
3340
3494
|
const handleCreateThread = async () => {
|
|
3341
3495
|
if (isCreating) return;
|
|
3342
3496
|
try {
|
|
@@ -3462,10 +3616,10 @@ var AccountDialog = ({
|
|
|
3462
3616
|
size
|
|
3463
3617
|
}) => {
|
|
3464
3618
|
const { isLoading, isAuthenticated, user, login, logout } = useAuth();
|
|
3465
|
-
const [open, setOpen] =
|
|
3466
|
-
const [accountInfoOpen, setAccountInfoOpen] =
|
|
3467
|
-
const [error, setError] =
|
|
3468
|
-
const initials =
|
|
3619
|
+
const [open, setOpen] = React12.useState(false);
|
|
3620
|
+
const [accountInfoOpen, setAccountInfoOpen] = React12.useState(false);
|
|
3621
|
+
const [error, setError] = React12.useState(null);
|
|
3622
|
+
const initials = React12.useMemo(() => {
|
|
3469
3623
|
const name = user?.displayName || user?.name;
|
|
3470
3624
|
if (!name) return "";
|
|
3471
3625
|
return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
|
|
@@ -3638,6 +3792,6 @@ function ThemeToggle() {
|
|
|
3638
3792
|
);
|
|
3639
3793
|
}
|
|
3640
3794
|
|
|
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 };
|
|
3795
|
+
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, WelcomeScreen, groupEventsToMessages, useAuth, useChatSidebar, useMelony, useScreenSize, useTheme, useThreads };
|
|
3642
3796
|
//# sourceMappingURL=index.js.map
|
|
3643
3797
|
//# sourceMappingURL=index.js.map
|