@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/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 React11 from 'react';
2
- import React11__default, { createContext, useState, useCallback, useEffect, useMemo, useContext, useRef } from 'react';
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, IconBrandGoogle, IconDeviceDesktop, IconMoon, IconSun, IconCheck, IconSelector, IconChevronUp } from '@tabler/icons-react';
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] = React11__default.useState(
688
+ const [selectedOptions, setSelectedOptions] = React12__default.useState(
689
689
  () => new Set(defaultSelectedIds)
690
690
  );
691
- const [attachedFiles, setAttachedFiles] = React11__default.useState([]);
692
- const fileInputRef = React11__default.useRef(null);
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 (e, threadId) => {
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
- const formatDate = (date) => {
2753
- if (!date) return "";
2754
- const d = typeof date === "string" ? new Date(date) : date;
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
- 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
- ),
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("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
- )
2766
+ /* @__PURE__ */ jsx(IconPlus, { className: "size-4" }),
2767
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "New chat" })
2799
2768
  ]
2800
- },
2801
- thread.id
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 = "Message the AI",
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 = React11.createContext(
3230
+ var PopoverContext = React12.createContext(
3077
3231
  void 0
3078
3232
  );
3079
3233
  function usePopoverContext() {
3080
- const context = React11.useContext(PopoverContext);
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] = React11.useState(defaultOpen);
3093
- const triggerRef = React11.useRef(null);
3246
+ const [internalOpen, setInternalOpen] = React12.useState(defaultOpen);
3247
+ const triggerRef = React12.useRef(null);
3094
3248
  const open = controlledOpen ?? internalOpen;
3095
- const setOpen = React11.useCallback(
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 = React11.useMemo(
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 = React11.forwardRef(
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 && React11.isValidElement(children)) {
3122
- return React11.cloneElement(children, {
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 = React11.forwardRef(
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] = React11.useState({ top: 0, left: 0 });
3166
- const contentRef = React11.useRef(null);
3167
- React11.useEffect(() => {
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
- React11.useEffect(() => {
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] = React11.useState(false);
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] = React11.useState(false);
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] = React11.useState(false);
3466
- const [accountInfoOpen, setAccountInfoOpen] = React11.useState(false);
3467
- const [error, setError] = React11.useState(null);
3468
- const initials = React11.useMemo(() => {
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