@melony/react 0.1.14 → 0.1.16

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React10 = require('react');
3
+ var React11 = require('react');
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var client = require('melony/client');
6
6
  var clsx = require('clsx');
@@ -8,13 +8,16 @@ var tailwindMerge = require('tailwind-merge');
8
8
  var button = require('@base-ui/react/button');
9
9
  var classVarianceAuthority = require('class-variance-authority');
10
10
  var ICONS = require('@tabler/icons-react');
11
+ var menu = require('@base-ui/react/menu');
11
12
  var separator = require('@base-ui/react/separator');
13
+ var dialog = require('@base-ui/react/dialog');
12
14
  var mergeProps = require('@base-ui/react/merge-props');
13
15
  var useRender = require('@base-ui/react/use-render');
14
16
  var input = require('@base-ui/react/input');
15
17
  var select = require('@base-ui/react/select');
18
+ var reactDom = require('react-dom');
19
+ var reactHotkeysHook = require('react-hotkeys-hook');
16
20
  var alertDialog = require('@base-ui/react/alert-dialog');
17
- var menu = require('@base-ui/react/menu');
18
21
 
19
22
  function _interopNamespace(e) {
20
23
  if (e && e.__esModule) return e;
@@ -34,7 +37,7 @@ function _interopNamespace(e) {
34
37
  return Object.freeze(n);
35
38
  }
36
39
 
37
- var React10__namespace = /*#__PURE__*/_interopNamespace(React10);
40
+ var React11__namespace = /*#__PURE__*/_interopNamespace(React11);
38
41
  var ICONS__namespace = /*#__PURE__*/_interopNamespace(ICONS);
39
42
 
40
43
  // src/providers/melony-provider.tsx
@@ -63,7 +66,7 @@ function groupEventsToMessages(events) {
63
66
  }
64
67
  return messages;
65
68
  }
66
- var MelonyContext = React10.createContext(
69
+ var MelonyContext = React11.createContext(
67
70
  void 0
68
71
  );
69
72
  var MelonyClientProvider = ({
@@ -71,20 +74,20 @@ var MelonyClientProvider = ({
71
74
  client,
72
75
  initialEvents
73
76
  }) => {
74
- const [state, setState] = React10.useState(client.getState());
75
- React10.useEffect(() => {
77
+ const [state, setState] = React11.useState(client.getState());
78
+ React11.useEffect(() => {
76
79
  if (initialEvents && initialEvents.length > 0 && client.getState().events.length === 0) {
77
80
  client.reset(initialEvents);
78
81
  }
79
82
  }, [client, initialEvents]);
80
- React10.useEffect(() => {
83
+ React11.useEffect(() => {
81
84
  setState(client.getState());
82
85
  const unsubscribe = client.subscribe(setState);
83
86
  return () => {
84
87
  unsubscribe();
85
88
  };
86
89
  }, [client]);
87
- const sendEvent = React10.useCallback(
90
+ const sendEvent = React11.useCallback(
88
91
  async (event, options) => {
89
92
  const generator = client.sendEvent(event, options);
90
93
  for await (const _ of generator) {
@@ -92,11 +95,11 @@ var MelonyClientProvider = ({
92
95
  },
93
96
  [client]
94
97
  );
95
- const reset = React10.useCallback(
98
+ const reset = React11.useCallback(
96
99
  (events) => client.reset(events),
97
100
  [client]
98
101
  );
99
- const value = React10.useMemo(
102
+ const value = React11.useMemo(
100
103
  () => ({
101
104
  ...state,
102
105
  messages: groupEventsToMessages(state.events),
@@ -108,16 +111,16 @@ var MelonyClientProvider = ({
108
111
  );
109
112
  return /* @__PURE__ */ jsxRuntime.jsx(MelonyContext.Provider, { value, children });
110
113
  };
111
- var AuthContext = React10.createContext(
114
+ var AuthContext = React11.createContext(
112
115
  void 0
113
116
  );
114
117
  var AuthProvider = ({
115
118
  children,
116
119
  service
117
120
  }) => {
118
- const [user, setUser] = React10.useState(null);
119
- const [isLoading, setIsLoading] = React10.useState(true);
120
- const fetchMe = React10.useCallback(async () => {
121
+ const [user, setUser] = React11.useState(null);
122
+ const [isLoading, setIsLoading] = React11.useState(true);
123
+ const fetchMe = React11.useCallback(async () => {
121
124
  setIsLoading(true);
122
125
  try {
123
126
  const userData = await service.getMe();
@@ -129,13 +132,13 @@ var AuthProvider = ({
129
132
  setIsLoading(false);
130
133
  }
131
134
  }, [service]);
132
- React10.useEffect(() => {
135
+ React11.useEffect(() => {
133
136
  fetchMe();
134
137
  }, [fetchMe]);
135
- const login = React10.useCallback(() => {
138
+ const login = React11.useCallback(() => {
136
139
  service.login();
137
140
  }, [service]);
138
- const logout = React10.useCallback(async () => {
141
+ const logout = React11.useCallback(async () => {
139
142
  try {
140
143
  await service.logout();
141
144
  setUser(null);
@@ -171,7 +174,7 @@ var AuthProvider = ({
171
174
  }
172
175
  return /* @__PURE__ */ jsxRuntime.jsx(AuthContext.Provider, { value, children });
173
176
  };
174
- var ThreadContext = React10.createContext(
177
+ var ThreadContext = React11.createContext(
175
178
  void 0
176
179
  );
177
180
  var ThreadProvider = ({
@@ -179,17 +182,17 @@ var ThreadProvider = ({
179
182
  service,
180
183
  initialThreadId: providedInitialThreadId
181
184
  }) => {
182
- const defaultInitialThreadId = React10.useMemo(() => client.generateId(), []);
185
+ const defaultInitialThreadId = React11.useMemo(() => client.generateId(), []);
183
186
  const initialThreadId = providedInitialThreadId || defaultInitialThreadId;
184
- const [threads, setThreads] = React10.useState([]);
185
- const [activeThreadId, setActiveThreadId] = React10.useState(
187
+ const [threads, setThreads] = React11.useState([]);
188
+ const [activeThreadId, setActiveThreadId] = React11.useState(
186
189
  initialThreadId
187
190
  );
188
- const [isLoading, setIsLoading] = React10.useState(true);
189
- const [error, setError] = React10.useState(null);
190
- const [threadEvents, setThreadEvents] = React10.useState([]);
191
- const [isLoadingEvents, setIsLoadingEvents] = React10.useState(false);
192
- const fetchThreads = React10.useCallback(async () => {
191
+ const [isLoading, setIsLoading] = React11.useState(true);
192
+ const [error, setError] = React11.useState(null);
193
+ const [threadEvents, setThreadEvents] = React11.useState([]);
194
+ const [isLoadingEvents, setIsLoadingEvents] = React11.useState(false);
195
+ const fetchThreads = React11.useCallback(async () => {
193
196
  setIsLoading(true);
194
197
  setError(null);
195
198
  try {
@@ -203,13 +206,13 @@ var ThreadProvider = ({
203
206
  setIsLoading(false);
204
207
  }
205
208
  }, [service]);
206
- React10.useEffect(() => {
209
+ React11.useEffect(() => {
207
210
  fetchThreads();
208
211
  }, [fetchThreads]);
209
- const selectThread = React10.useCallback((threadId) => {
212
+ const selectThread = React11.useCallback((threadId) => {
210
213
  setActiveThreadId(threadId);
211
214
  }, []);
212
- const createThread = React10.useCallback(async () => {
215
+ const createThread = React11.useCallback(async () => {
213
216
  const newId = service.createThread ? await service.createThread() : client.generateId();
214
217
  const newThread = {
215
218
  id: newId,
@@ -219,7 +222,7 @@ var ThreadProvider = ({
219
222
  setActiveThreadId(newId);
220
223
  return newId;
221
224
  }, [service]);
222
- const deleteThread = React10.useCallback(
225
+ const deleteThread = React11.useCallback(
223
226
  async (threadId) => {
224
227
  try {
225
228
  await service.deleteThread(threadId);
@@ -241,10 +244,10 @@ var ThreadProvider = ({
241
244
  },
242
245
  [service]
243
246
  );
244
- const refreshThreads = React10.useCallback(async () => {
247
+ const refreshThreads = React11.useCallback(async () => {
245
248
  await fetchThreads();
246
249
  }, [fetchThreads]);
247
- React10.useEffect(() => {
250
+ React11.useEffect(() => {
248
251
  if (!activeThreadId) {
249
252
  setThreadEvents([]);
250
253
  setIsLoadingEvents(false);
@@ -274,7 +277,7 @@ var ThreadProvider = ({
274
277
  cancelled = true;
275
278
  };
276
279
  }, [activeThreadId, service]);
277
- const value = React10.useMemo(
280
+ const value = React11.useMemo(
278
281
  () => ({
279
282
  threads,
280
283
  activeThreadId,
@@ -302,11 +305,11 @@ var ThreadProvider = ({
302
305
  );
303
306
  return /* @__PURE__ */ jsxRuntime.jsx(ThreadContext.Provider, { value, children });
304
307
  };
305
- var ThemeContext = React10.createContext(void 0);
308
+ var ThemeContext = React11.createContext(void 0);
306
309
  function ThemeProvider({ children }) {
307
- const [theme, setThemeState] = React10.useState("system");
308
- const [resolvedTheme, setResolvedTheme] = React10.useState("light");
309
- React10.useEffect(() => {
310
+ const [theme, setThemeState] = React11.useState("system");
311
+ const [resolvedTheme, setResolvedTheme] = React11.useState("light");
312
+ React11.useEffect(() => {
310
313
  if (typeof window !== "undefined") {
311
314
  const stored = localStorage.getItem("theme");
312
315
  if (stored) {
@@ -314,7 +317,7 @@ function ThemeProvider({ children }) {
314
317
  }
315
318
  }
316
319
  }, []);
317
- React10.useEffect(() => {
320
+ React11.useEffect(() => {
318
321
  if (typeof window !== "undefined") {
319
322
  if (theme === "system") {
320
323
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
@@ -329,7 +332,7 @@ function ThemeProvider({ children }) {
329
332
  }
330
333
  }
331
334
  }, [theme]);
332
- React10.useEffect(() => {
335
+ React11.useEffect(() => {
333
336
  if (typeof window !== "undefined") {
334
337
  const root = document.documentElement;
335
338
  if (resolvedTheme === "dark") {
@@ -348,20 +351,20 @@ function ThemeProvider({ children }) {
348
351
  return /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value: { theme, setTheme, resolvedTheme }, children });
349
352
  }
350
353
  function useTheme() {
351
- const context = React10.useContext(ThemeContext);
354
+ const context = React11.useContext(ThemeContext);
352
355
  if (context === void 0) {
353
356
  throw new Error("useTheme must be used within a ThemeProvider");
354
357
  }
355
358
  return context;
356
359
  }
357
360
  var useMelony = (options) => {
358
- const context = React10.useContext(MelonyContext);
361
+ const context = React11.useContext(MelonyContext);
359
362
  if (context === void 0) {
360
363
  throw new Error("useMelony must be used within a MelonyClientProvider");
361
364
  }
362
365
  const { client, reset } = context;
363
366
  const { initialEvents } = options || {};
364
- React10.useEffect(() => {
367
+ React11.useEffect(() => {
365
368
  if (initialEvents && initialEvents.length > 0 && client.getState().events.length === 0) {
366
369
  reset(initialEvents);
367
370
  }
@@ -369,14 +372,14 @@ var useMelony = (options) => {
369
372
  return context;
370
373
  };
371
374
  var useAuth = () => {
372
- const context = React10.useContext(AuthContext);
375
+ const context = React11.useContext(AuthContext);
373
376
  if (context === void 0) {
374
377
  throw new Error("useAuth must be used within an AuthProvider");
375
378
  }
376
379
  return context;
377
380
  };
378
381
  var useThreads = () => {
379
- const context = React10.useContext(ThreadContext);
382
+ const context = React11.useContext(ThreadContext);
380
383
  if (context === void 0) {
381
384
  throw new Error("useThreads must be used within a ThreadProvider");
382
385
  }
@@ -442,18 +445,179 @@ function Textarea({ className, ...props }) {
442
445
  }
443
446
  );
444
447
  }
448
+ function DropdownMenu({ ...props }) {
449
+ return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Root, { "data-slot": "dropdown-menu", ...props });
450
+ }
451
+ function DropdownMenuTrigger({ ...props }) {
452
+ return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
453
+ }
454
+ function DropdownMenuContent({
455
+ align = "start",
456
+ alignOffset = 0,
457
+ side = "bottom",
458
+ sideOffset = 4,
459
+ className,
460
+ ...props
461
+ }) {
462
+ return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
463
+ menu.Menu.Positioner,
464
+ {
465
+ className: "isolate z-50 outline-none",
466
+ align,
467
+ alignOffset,
468
+ side,
469
+ sideOffset,
470
+ children: /* @__PURE__ */ jsxRuntime.jsx(
471
+ menu.Menu.Popup,
472
+ {
473
+ "data-slot": "dropdown-menu-content",
474
+ className: cn("data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/5 bg-popover text-popover-foreground min-w-48 rounded-2xl p-1 shadow-2xl ring-1 duration-100 z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto outline-none data-closed:overflow-hidden", className),
475
+ ...props
476
+ }
477
+ )
478
+ }
479
+ ) });
480
+ }
481
+ function DropdownMenuGroup({ ...props }) {
482
+ return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Group, { "data-slot": "dropdown-menu-group", ...props });
483
+ }
484
+ function DropdownMenuLabel({
485
+ className,
486
+ inset,
487
+ ...props
488
+ }) {
489
+ return /* @__PURE__ */ jsxRuntime.jsx(
490
+ menu.Menu.GroupLabel,
491
+ {
492
+ "data-slot": "dropdown-menu-label",
493
+ "data-inset": inset,
494
+ className: cn("text-muted-foreground px-3 py-2.5 text-xs data-[inset]:pl-8", className),
495
+ ...props
496
+ }
497
+ );
498
+ }
499
+ function DropdownMenuItem({
500
+ className,
501
+ inset,
502
+ variant = "default",
503
+ ...props
504
+ }) {
505
+ return /* @__PURE__ */ jsxRuntime.jsx(
506
+ menu.Menu.Item,
507
+ {
508
+ "data-slot": "dropdown-menu-item",
509
+ "data-inset": inset,
510
+ "data-variant": variant,
511
+ className: cn(
512
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2.5 rounded-xl px-3 py-2 text-sm [&_svg:not([class*='size-'])]:size-4 group/dropdown-menu-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0",
513
+ className
514
+ ),
515
+ ...props
516
+ }
517
+ );
518
+ }
519
+ function DropdownMenuCheckboxItem({
520
+ className,
521
+ children,
522
+ checked,
523
+ ...props
524
+ }) {
525
+ return /* @__PURE__ */ jsxRuntime.jsxs(
526
+ menu.Menu.CheckboxItem,
527
+ {
528
+ "data-slot": "dropdown-menu-checkbox-item",
529
+ className: cn(
530
+ "focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-2.5 rounded-xl py-2 pr-8 pl-3 text-sm [&_svg:not([class*='size-'])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
531
+ className
532
+ ),
533
+ checked,
534
+ ...props,
535
+ children: [
536
+ /* @__PURE__ */ jsxRuntime.jsx(
537
+ "span",
538
+ {
539
+ className: "pointer-events-none absolute right-2 flex items-center justify-center pointer-events-none",
540
+ "data-slot": "dropdown-menu-checkbox-item-indicator",
541
+ children: /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.CheckboxItemIndicator, { children: /* @__PURE__ */ jsxRuntime.jsx(
542
+ ICONS.IconCheck,
543
+ {}
544
+ ) })
545
+ }
546
+ ),
547
+ children
548
+ ]
549
+ }
550
+ );
551
+ }
552
+ function DropdownMenuSeparator({
553
+ className,
554
+ ...props
555
+ }) {
556
+ return /* @__PURE__ */ jsxRuntime.jsx(
557
+ menu.Menu.Separator,
558
+ {
559
+ "data-slot": "dropdown-menu-separator",
560
+ className: cn("bg-border/50 -mx-1 my-1 h-px", className),
561
+ ...props
562
+ }
563
+ );
564
+ }
445
565
  function Composer({
446
566
  value,
447
567
  onChange,
448
568
  onSubmit,
449
569
  placeholder = "Type a message...",
450
570
  isLoading,
451
- className
571
+ className,
572
+ options = [],
573
+ autoFocus = false,
574
+ defaultSelectedIds = []
452
575
  }) {
576
+ const [selectedOptions, setSelectedOptions] = React11__namespace.default.useState(
577
+ () => new Set(defaultSelectedIds)
578
+ );
579
+ const toggleOption = (id, groupOptions, type = "multiple") => {
580
+ const next = new Set(selectedOptions);
581
+ if (type === "single") {
582
+ const isAlreadySelected = next.has(id);
583
+ if (groupOptions) {
584
+ groupOptions.forEach((o) => next.delete(o.id));
585
+ }
586
+ if (!isAlreadySelected) {
587
+ next.add(id);
588
+ }
589
+ } else {
590
+ if (next.has(id)) {
591
+ next.delete(id);
592
+ } else {
593
+ next.add(id);
594
+ }
595
+ }
596
+ setSelectedOptions(next);
597
+ };
598
+ const handleInternalSubmit = () => {
599
+ const state = {};
600
+ options.forEach((group) => {
601
+ const selectedInGroup = group.options.filter(
602
+ (o) => selectedOptions.has(o.id)
603
+ );
604
+ if (selectedInGroup.length > 0) {
605
+ if (group.type === "single") {
606
+ state[group.id] = selectedInGroup[0].value;
607
+ } else {
608
+ state[group.id] = selectedInGroup.map((o) => ({
609
+ id: o.id,
610
+ value: o.value
611
+ }));
612
+ }
613
+ }
614
+ });
615
+ onSubmit(state);
616
+ };
453
617
  const handleKeyDown = (e) => {
454
618
  if (e.key === "Enter" && !e.shiftKey) {
455
619
  e.preventDefault();
456
- onSubmit();
620
+ handleInternalSubmit();
457
621
  }
458
622
  };
459
623
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("relative flex flex-col w-full", className), children: /* @__PURE__ */ jsxRuntime.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: [
@@ -464,19 +628,68 @@ function Composer({
464
628
  onChange: (e) => onChange(e.target.value),
465
629
  onKeyDown: handleKeyDown,
466
630
  placeholder,
467
- 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"
631
+ 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",
632
+ autoFocus
468
633
  }
469
634
  ),
470
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
471
- Button,
472
- {
473
- type: "submit",
474
- disabled: !value.trim() && !isLoading || isLoading,
475
- size: "icon-lg",
476
- onClick: () => onSubmit(),
477
- children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconArrowUp, { className: "h-5 w-5" })
478
- }
479
- ) })
635
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center px-1", children: [
636
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: options.map((group) => {
637
+ const selectedInGroup = group.options.filter(
638
+ (o) => selectedOptions.has(o.id)
639
+ );
640
+ const label = selectedInGroup.length === 0 ? group.label : selectedInGroup.length === 1 ? selectedInGroup[0].label : `${group.label} (${selectedInGroup.length})`;
641
+ const isSingle = group.type === "single";
642
+ return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
643
+ /* @__PURE__ */ jsxRuntime.jsx(
644
+ DropdownMenuTrigger,
645
+ {
646
+ render: /* @__PURE__ */ jsxRuntime.jsxs(
647
+ Button,
648
+ {
649
+ variant: "ghost",
650
+ size: "sm",
651
+ className: cn(
652
+ selectedInGroup.length > 0 ? "text-foreground bg-muted/50" : "text-muted-foreground"
653
+ ),
654
+ children: [
655
+ label,
656
+ /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronDown, { className: "h-3 w-3 opacity-50" })
657
+ ]
658
+ }
659
+ )
660
+ }
661
+ ),
662
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "start", className: "w-56", children: /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuGroup, { children: [
663
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuLabel, { children: group.label }),
664
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
665
+ group.options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
666
+ DropdownMenuCheckboxItem,
667
+ {
668
+ checked: selectedOptions.has(option.id),
669
+ onCheckedChange: () => toggleOption(
670
+ option.id,
671
+ group.options,
672
+ isSingle ? "single" : "multiple"
673
+ ),
674
+ onSelect: (e) => e.preventDefault(),
675
+ children: option.label
676
+ },
677
+ option.id
678
+ ))
679
+ ] }) })
680
+ ] }, group.id);
681
+ }) }),
682
+ /* @__PURE__ */ jsxRuntime.jsx(
683
+ Button,
684
+ {
685
+ type: "submit",
686
+ disabled: !value.trim() && !isLoading || isLoading,
687
+ size: "icon-lg",
688
+ onClick: handleInternalSubmit,
689
+ children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLoader2, { className: "h-5 w-5 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconArrowUp, { className: "h-5 w-5" })
690
+ }
691
+ )
692
+ ] })
480
693
  ] }) });
481
694
  }
482
695
  function Card({
@@ -862,6 +1075,111 @@ var ListItem = ({
862
1075
  }
863
1076
  );
864
1077
  };
1078
+ function Dialog({ ...props }) {
1079
+ return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog.Root, { "data-slot": "dialog", ...props });
1080
+ }
1081
+ function DialogTrigger({ ...props }) {
1082
+ return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog.Trigger, { "data-slot": "dialog-trigger", ...props });
1083
+ }
1084
+ function DialogPortal({ ...props }) {
1085
+ return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog.Portal, { "data-slot": "dialog-portal", ...props });
1086
+ }
1087
+ function DialogOverlay({
1088
+ className,
1089
+ ...props
1090
+ }) {
1091
+ return /* @__PURE__ */ jsxRuntime.jsx(
1092
+ dialog.Dialog.Backdrop,
1093
+ {
1094
+ "data-slot": "dialog-overlay",
1095
+ className: cn(
1096
+ "data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 bg-black/80 duration-200 supports-backdrop-filter:backdrop-blur-sm fixed inset-0 isolate z-50",
1097
+ className
1098
+ ),
1099
+ ...props
1100
+ }
1101
+ );
1102
+ }
1103
+ function DialogContent({
1104
+ className,
1105
+ ...props
1106
+ }) {
1107
+ return /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { children: [
1108
+ /* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
1109
+ /* @__PURE__ */ jsxRuntime.jsx(
1110
+ dialog.Dialog.Popup,
1111
+ {
1112
+ "data-slot": "dialog-content",
1113
+ className: cn(
1114
+ "data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 sm:rounded-lg outline-none",
1115
+ className
1116
+ ),
1117
+ ...props
1118
+ }
1119
+ )
1120
+ ] });
1121
+ }
1122
+ function DialogClose({
1123
+ className,
1124
+ ...props
1125
+ }) {
1126
+ return /* @__PURE__ */ jsxRuntime.jsx(
1127
+ dialog.Dialog.Close,
1128
+ {
1129
+ "data-slot": "dialog-close",
1130
+ className: cn(
1131
+ "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",
1132
+ className
1133
+ ),
1134
+ ...props
1135
+ }
1136
+ );
1137
+ }
1138
+ function DialogHeader({
1139
+ className,
1140
+ ...props
1141
+ }) {
1142
+ return /* @__PURE__ */ jsxRuntime.jsx(
1143
+ "div",
1144
+ {
1145
+ "data-slot": "dialog-header",
1146
+ className: cn(
1147
+ "flex flex-col space-y-1.5 text-center sm:text-left",
1148
+ className
1149
+ ),
1150
+ ...props
1151
+ }
1152
+ );
1153
+ }
1154
+ function DialogTitle({
1155
+ className,
1156
+ ...props
1157
+ }) {
1158
+ return /* @__PURE__ */ jsxRuntime.jsx(
1159
+ dialog.Dialog.Title,
1160
+ {
1161
+ "data-slot": "dialog-title",
1162
+ className: cn(
1163
+ "text-lg font-semibold leading-none tracking-tight",
1164
+ className
1165
+ ),
1166
+ ...props
1167
+ }
1168
+ );
1169
+ }
1170
+ function DialogDescription({
1171
+ className,
1172
+ ...props
1173
+ }) {
1174
+ return /* @__PURE__ */ jsxRuntime.jsx(
1175
+ dialog.Dialog.Description,
1176
+ {
1177
+ "data-slot": "dialog-description",
1178
+ className: cn("text-sm text-muted-foreground", className),
1179
+ ...props
1180
+ }
1181
+ );
1182
+ }
865
1183
  var Image = ({
866
1184
  src,
867
1185
  alt,
@@ -869,12 +1187,13 @@ var Image = ({
869
1187
  className,
870
1188
  style
871
1189
  }) => {
872
- const [hasError, setHasError] = React10.useState(false);
873
- const [isLoading, setIsLoading] = React10.useState(true);
1190
+ const [hasError, setHasError] = React11.useState(false);
1191
+ const [isLoading, setIsLoading] = React11.useState(true);
1192
+ const [open, setOpen] = React11.useState(false);
874
1193
  const sizes = {
875
- sm: "h-11 w-11",
876
- md: "h-22 w-22",
877
- lg: "h-44 w-44"
1194
+ sm: "h-11",
1195
+ md: "h-22",
1196
+ lg: "h-44"
878
1197
  };
879
1198
  const handleError = () => {
880
1199
  setHasError(true);
@@ -897,22 +1216,67 @@ var Image = ({
897
1216
  }
898
1217
  );
899
1218
  }
900
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative overflow-hidden rounded-md border", className), style, children: [
1219
+ return /* @__PURE__ */ jsxRuntime.jsxs(Dialog, { open, onOpenChange: setOpen, children: [
1220
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTrigger, { children: /* @__PURE__ */ jsxRuntime.jsxs(
1221
+ "div",
1222
+ {
1223
+ className: cn("relative overflow-hidden rounded-md border cursor-pointer", className),
1224
+ style,
1225
+ children: [
1226
+ /* @__PURE__ */ jsxRuntime.jsx(
1227
+ "img",
1228
+ {
1229
+ src,
1230
+ alt,
1231
+ onError: handleError,
1232
+ onLoad: handleLoad,
1233
+ className: cn(
1234
+ "block h-auto w-full transition-opacity duration-200 hover:opacity-90",
1235
+ isLoading ? "opacity-0" : "opacity-100",
1236
+ sizes[size]
1237
+ )
1238
+ }
1239
+ ),
1240
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-muted animate-pulse" })
1241
+ ]
1242
+ }
1243
+ ) }),
901
1244
  /* @__PURE__ */ jsxRuntime.jsx(
902
- "img",
1245
+ DialogContent,
903
1246
  {
904
- src,
905
- alt,
906
- onError: handleError,
907
- onLoad: handleLoad,
908
- className: cn(
909
- "block h-auto w-full transition-opacity duration-200",
910
- isLoading ? "opacity-0" : "opacity-100",
911
- sizes[size]
912
- )
1247
+ className: "max-w-[90vw] max-h-[90vh] p-0 bg-transparent border-none shadow-none",
1248
+ onClick: (e) => e.stopPropagation(),
1249
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-center justify-center", children: [
1250
+ /* @__PURE__ */ jsxRuntime.jsx(DialogClose, { className: "absolute -top-10 right-0 text-white hover:text-gray-300 transition-colors z-10 bg-black/50 rounded-full p-2", children: /* @__PURE__ */ jsxRuntime.jsx(
1251
+ "svg",
1252
+ {
1253
+ xmlns: "http://www.w3.org/2000/svg",
1254
+ className: "h-5 w-5",
1255
+ fill: "none",
1256
+ viewBox: "0 0 24 24",
1257
+ stroke: "currentColor",
1258
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1259
+ "path",
1260
+ {
1261
+ strokeLinecap: "round",
1262
+ strokeLinejoin: "round",
1263
+ strokeWidth: 2,
1264
+ d: "M6 18L18 6M6 6l12 12"
1265
+ }
1266
+ )
1267
+ }
1268
+ ) }),
1269
+ /* @__PURE__ */ jsxRuntime.jsx(
1270
+ "img",
1271
+ {
1272
+ src,
1273
+ alt: alt || "Enlarged image",
1274
+ className: "max-w-full max-h-[90vh] object-contain rounded-lg"
1275
+ }
1276
+ )
1277
+ ] })
913
1278
  }
914
- ),
915
- isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-muted animate-pulse" })
1279
+ )
916
1280
  ] });
917
1281
  };
918
1282
  var Icon = ({
@@ -1023,7 +1387,7 @@ var Chart = ({
1023
1387
  className,
1024
1388
  style
1025
1389
  }) => {
1026
- const [tooltip, setTooltip] = React10.useState(null);
1390
+ const [tooltip, setTooltip] = React11.useState(null);
1027
1391
  if (!Array.isArray(data)) {
1028
1392
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-destructive border border-destructive/20 rounded-md bg-destructive/5", children: "Error: Chart data must be an array" });
1029
1393
  }
@@ -1779,7 +2143,7 @@ var Button2 = ({
1779
2143
  };
1780
2144
  var Form = ({ children, onSubmitAction, className, style }) => {
1781
2145
  const { sendEvent } = useMelony();
1782
- const [isSubmitted, setIsSubmitted] = React10.useState(false);
2146
+ const [isSubmitted, setIsSubmitted] = React11.useState(false);
1783
2147
  const handleSubmit = (e) => {
1784
2148
  e.preventDefault();
1785
2149
  if (isSubmitted) return;
@@ -1925,19 +2289,42 @@ function MessageBubble({ message }) {
1925
2289
  }
1926
2290
  );
1927
2291
  }
1928
- function LoadingIndicator() {
1929
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground animate-pulse", children: "Thinking..." });
2292
+ function LoadingIndicator({ status }) {
2293
+ const [isExpanded, setIsExpanded] = React11.useState(false);
2294
+ const message = status?.message || "Processing...";
2295
+ const details = status?.details;
2296
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
2297
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-muted-foreground group", children: [
2298
+ /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLoader2, { className: "size-3.5 animate-spin" }),
2299
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-pulse", children: message }),
2300
+ details && /* @__PURE__ */ jsxRuntime.jsx(
2301
+ "button",
2302
+ {
2303
+ onClick: () => setIsExpanded(!isExpanded),
2304
+ className: "p-0.5 hover:bg-muted rounded-sm transition-colors flex items-center justify-center",
2305
+ title: isExpanded ? "Hide details" : "Show details",
2306
+ children: isExpanded ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronUp, { className: "size-3.5 opacity-50 group-hover:opacity-100" }) : /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronDown, { className: "size-3.5 opacity-50 group-hover:opacity-100" })
2307
+ }
2308
+ )
2309
+ ] }),
2310
+ isExpanded && details && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] leading-relaxed font-mono bg-muted/30 p-2.5 rounded border border-border/50 max-h-64 overflow-y-auto whitespace-pre-wrap text-muted-foreground shadow-sm", children: details })
2311
+ ] });
1930
2312
  }
1931
2313
  function ErrorDisplay({ error }) {
1932
2314
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-destructive p-2 border border-destructive rounded-md bg-destructive/10", children: error.message });
1933
2315
  }
1934
- function MessageList({ messages, isLoading, error }) {
2316
+ function MessageList({ messages, isLoading, error, loadingStatus }) {
1935
2317
  if (messages.length === 0) {
1936
2318
  return null;
1937
2319
  }
2320
+ const isTextStreaming = React11.useMemo(() => {
2321
+ if (messages.length === 0 || !isLoading) return false;
2322
+ const lastMessage = messages[messages.length - 1];
2323
+ return lastMessage.content.some((event) => event.type === "text-delta");
2324
+ }, [messages, isLoading]);
1938
2325
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
1939
2326
  messages.map((message, index) => /* @__PURE__ */ jsxRuntime.jsx(MessageBubble, { message }, index)),
1940
- isLoading && /* @__PURE__ */ jsxRuntime.jsx(LoadingIndicator, {}),
2327
+ isLoading && !isTextStreaming && /* @__PURE__ */ jsxRuntime.jsx(LoadingIndicator, { status: loadingStatus }),
1941
2328
  error && /* @__PURE__ */ jsxRuntime.jsx(ErrorDisplay, { error })
1942
2329
  ] });
1943
2330
  }
@@ -1945,24 +2332,29 @@ function Thread({
1945
2332
  className,
1946
2333
  placeholder = "Type a message...",
1947
2334
  starterPrompts,
1948
- onStarterPromptClick
2335
+ onStarterPromptClick,
2336
+ options,
2337
+ autoFocus = false,
2338
+ defaultSelectedIds
1949
2339
  }) {
1950
- const { messages, isLoading, error, sendEvent } = useMelony();
1951
- const [input, setInput] = React10.useState("");
1952
- const messagesEndRef = React10.useRef(null);
1953
- React10.useEffect(() => {
2340
+ const { messages, isLoading, error, sendEvent, loadingStatus } = useMelony();
2341
+ const [input, setInput] = React11.useState("");
2342
+ const messagesEndRef = React11.useRef(null);
2343
+ React11.useEffect(() => {
1954
2344
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
1955
2345
  }, [messages]);
1956
- const handleSubmit = async (e, overrideInput) => {
1957
- e?.preventDefault();
2346
+ const handleSubmit = async (state, overrideInput) => {
1958
2347
  const text = (overrideInput ?? input).trim();
1959
2348
  if (!text || isLoading) return;
1960
2349
  if (!overrideInput) setInput("");
1961
- await sendEvent({
1962
- type: "text",
1963
- role: "user",
1964
- data: { content: text }
1965
- });
2350
+ await sendEvent(
2351
+ {
2352
+ type: "text",
2353
+ role: "user",
2354
+ data: { content: text }
2355
+ },
2356
+ { state }
2357
+ );
1966
2358
  };
1967
2359
  const handleStarterPromptClick = (prompt) => {
1968
2360
  if (onStarterPromptClick) {
@@ -1972,47 +2364,57 @@ function Thread({
1972
2364
  }
1973
2365
  };
1974
2366
  const showStarterPrompts = messages.length === 0 && starterPrompts && starterPrompts.length > 0;
1975
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative flex flex-col h-full bg-background", className), children: [
1976
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto p-4 pb-36", children: [
1977
- /* @__PURE__ */ jsxRuntime.jsxs(
1978
- "div",
1979
- {
1980
- className: cn(
1981
- "max-w-4xl mx-auto w-full p-4",
1982
- showStarterPrompts && "min-h-full flex flex-col"
2367
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2368
+ "div",
2369
+ {
2370
+ className: cn("relative flex flex-col h-full bg-background", className),
2371
+ children: [
2372
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto p-4 pb-36", children: [
2373
+ /* @__PURE__ */ jsxRuntime.jsxs(
2374
+ "div",
2375
+ {
2376
+ className: cn(
2377
+ "max-w-4xl mx-auto w-full p-4",
2378
+ showStarterPrompts && "min-h-full flex flex-col"
2379
+ ),
2380
+ children: [
2381
+ showStarterPrompts && /* @__PURE__ */ jsxRuntime.jsx(
2382
+ StarterPrompts,
2383
+ {
2384
+ prompts: starterPrompts,
2385
+ onPromptClick: handleStarterPromptClick
2386
+ }
2387
+ ),
2388
+ /* @__PURE__ */ jsxRuntime.jsx(
2389
+ MessageList,
2390
+ {
2391
+ messages,
2392
+ isLoading,
2393
+ error,
2394
+ loadingStatus
2395
+ }
2396
+ )
2397
+ ]
2398
+ }
1983
2399
  ),
1984
- children: [
1985
- showStarterPrompts && /* @__PURE__ */ jsxRuntime.jsx(
1986
- StarterPrompts,
1987
- {
1988
- prompts: starterPrompts,
1989
- onPromptClick: handleStarterPromptClick
1990
- }
1991
- ),
1992
- /* @__PURE__ */ jsxRuntime.jsx(
1993
- MessageList,
1994
- {
1995
- messages,
1996
- isLoading,
1997
- error
1998
- }
1999
- )
2000
- ]
2001
- }
2002
- ),
2003
- /* @__PURE__ */ jsxRuntime.jsx("div", { ref: messagesEndRef })
2004
- ] }),
2005
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 p-4 w-full", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-4xl mx-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
2006
- Composer,
2007
- {
2008
- value: input,
2009
- onChange: setInput,
2010
- onSubmit: handleSubmit,
2011
- placeholder,
2012
- isLoading
2013
- }
2014
- ) }) })
2015
- ] });
2400
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: messagesEndRef })
2401
+ ] }),
2402
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 p-4 w-full", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-4xl mx-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
2403
+ Composer,
2404
+ {
2405
+ value: input,
2406
+ onChange: setInput,
2407
+ onSubmit: handleSubmit,
2408
+ placeholder,
2409
+ isLoading,
2410
+ options,
2411
+ autoFocus,
2412
+ defaultSelectedIds
2413
+ }
2414
+ ) }) })
2415
+ ]
2416
+ }
2417
+ );
2016
2418
  }
2017
2419
  function ChatHeader({
2018
2420
  title,
@@ -2026,13 +2428,7 @@ function ChatHeader({
2026
2428
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("p-4 border-b border-border h-14 flex items-center shrink-0", className), children });
2027
2429
  }
2028
2430
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("p-4 border-b border-border h-14 flex items-center justify-between shrink-0", className), children: [
2029
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [
2030
- leftContent,
2031
- title && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
2032
- "text-sm font-semibold truncate",
2033
- typeof title === "string" ? titleClassName : ""
2034
- ), children: title })
2035
- ] }),
2431
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: leftContent }),
2036
2432
  rightContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 shrink-0 ml-2", children: rightContent })
2037
2433
  ] });
2038
2434
  }
@@ -2135,11 +2531,13 @@ function ChatPopup({
2135
2531
  title = "Chat",
2136
2532
  placeholder = "Message the AI",
2137
2533
  starterPrompts,
2534
+ options,
2138
2535
  defaultOpen = false,
2139
- headerProps
2536
+ headerProps,
2537
+ defaultSelectedIds
2140
2538
  }) {
2141
- const [isOpen, setIsOpen] = React10.useState(defaultOpen);
2142
- const [view, setView] = React10.useState("chat");
2539
+ const [isOpen, setIsOpen] = React11.useState(defaultOpen);
2540
+ const [view, setView] = React11.useState("chat");
2143
2541
  const { createThread } = useThreads();
2144
2542
  const handleNewChat = async () => {
2145
2543
  try {
@@ -2150,7 +2548,7 @@ function ChatPopup({
2150
2548
  }
2151
2549
  };
2152
2550
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fixed bottom-6 right-6 z-50 flex flex-col items-end gap-4 font-sans", children: [
2153
- isOpen && /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "py-0 w-[440px] h-[640px] flex flex-col overflow-hidden border bg-background/95 backdrop-blur supports-backdrop-filter:bg-background/60 shadow-2xl animate-in fade-in zoom-in-95 duration-200 origin-bottom-right", children: [
2551
+ isOpen && /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "py-0 w-[440px] h-[640px] gap-0 flex flex-col overflow-hidden border bg-background/95 backdrop-blur supports-backdrop-filter:bg-background/60 shadow-2xl animate-in fade-in zoom-in-95 duration-200 origin-bottom-right", children: [
2154
2552
  /* @__PURE__ */ jsxRuntime.jsx(
2155
2553
  ChatHeader,
2156
2554
  {
@@ -2207,7 +2605,9 @@ function ChatPopup({
2207
2605
  {
2208
2606
  placeholder,
2209
2607
  starterPrompts,
2210
- className: "h-full"
2608
+ options,
2609
+ className: "h-full",
2610
+ defaultSelectedIds
2211
2611
  }
2212
2612
  ) : /* @__PURE__ */ jsxRuntime.jsx(
2213
2613
  ThreadList,
@@ -2235,8 +2635,10 @@ function ChatSidebar({
2235
2635
  title = "Chat",
2236
2636
  placeholder = "Message the AI",
2237
2637
  starterPrompts,
2638
+ options,
2238
2639
  className,
2239
- headerProps
2640
+ headerProps,
2641
+ defaultSelectedIds
2240
2642
  }) {
2241
2643
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full border-r bg-background w-80", className), children: [
2242
2644
  /* @__PURE__ */ jsxRuntime.jsx(ChatHeader, { title, ...headerProps }),
@@ -2245,7 +2647,9 @@ function ChatSidebar({
2245
2647
  {
2246
2648
  placeholder,
2247
2649
  starterPrompts,
2248
- className: "h-full"
2650
+ options,
2651
+ className: "h-full",
2652
+ defaultSelectedIds
2249
2653
  }
2250
2654
  ) })
2251
2655
  ] });
@@ -2254,6 +2658,7 @@ function ChatFull({
2254
2658
  title = "Chat",
2255
2659
  placeholder = "Message the AI",
2256
2660
  starterPrompts,
2661
+ options,
2257
2662
  className,
2258
2663
  headerProps,
2259
2664
  leftSidebar,
@@ -2267,12 +2672,14 @@ function ChatFull({
2267
2672
  leftSidebarCollapsed: controlledLeftCollapsed,
2268
2673
  rightSidebarCollapsed: controlledRightCollapsed,
2269
2674
  onLeftSidebarCollapseChange,
2270
- onRightSidebarCollapseChange
2675
+ onRightSidebarCollapseChange,
2676
+ autoFocus = false,
2677
+ defaultSelectedIds
2271
2678
  }) {
2272
- const [internalLeftCollapsed, setInternalLeftCollapsed] = React10.useState(
2679
+ const [internalLeftCollapsed, setInternalLeftCollapsed] = React11.useState(
2273
2680
  defaultLeftSidebarCollapsed
2274
2681
  );
2275
- const [internalRightCollapsed, setInternalRightCollapsed] = React10.useState(
2682
+ const [internalRightCollapsed, setInternalRightCollapsed] = React11.useState(
2276
2683
  defaultRightSidebarCollapsed
2277
2684
  );
2278
2685
  const leftCollapsed = controlledLeftCollapsed !== void 0 ? controlledLeftCollapsed : internalLeftCollapsed;
@@ -2331,7 +2738,16 @@ function ChatFull({
2331
2738
  }
2332
2739
  ) })
2333
2740
  ] }),
2334
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(Thread, { placeholder, starterPrompts }) }),
2741
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
2742
+ Thread,
2743
+ {
2744
+ placeholder,
2745
+ starterPrompts,
2746
+ options,
2747
+ autoFocus,
2748
+ defaultSelectedIds
2749
+ }
2750
+ ) }),
2335
2751
  rightSidebar && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2336
2752
  rightSidebarCollapsible && rightCollapsed && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 border-l border-border bg-background flex items-center justify-center w-10", children: /* @__PURE__ */ jsxRuntime.jsx(
2337
2753
  Button,
@@ -2372,6 +2788,307 @@ function ChatFull({
2372
2788
  ] })
2373
2789
  ] });
2374
2790
  }
2791
+ var PopoverContext = React11__namespace.createContext(
2792
+ void 0
2793
+ );
2794
+ function usePopoverContext() {
2795
+ const context = React11__namespace.useContext(PopoverContext);
2796
+ if (!context) {
2797
+ throw new Error("Popover components must be used within a Popover");
2798
+ }
2799
+ return context;
2800
+ }
2801
+ function Popover({
2802
+ children,
2803
+ defaultOpen = false,
2804
+ open: controlledOpen,
2805
+ onOpenChange
2806
+ }) {
2807
+ const [internalOpen, setInternalOpen] = React11__namespace.useState(defaultOpen);
2808
+ const triggerRef = React11__namespace.useRef(null);
2809
+ const open = controlledOpen ?? internalOpen;
2810
+ const setOpen = React11__namespace.useCallback(
2811
+ (newOpen) => {
2812
+ if (controlledOpen === void 0) {
2813
+ setInternalOpen(newOpen);
2814
+ }
2815
+ onOpenChange?.(newOpen);
2816
+ },
2817
+ [controlledOpen, onOpenChange]
2818
+ );
2819
+ const value = React11__namespace.useMemo(
2820
+ () => ({
2821
+ open,
2822
+ setOpen,
2823
+ triggerRef
2824
+ }),
2825
+ [open, setOpen]
2826
+ );
2827
+ return /* @__PURE__ */ jsxRuntime.jsx(PopoverContext.Provider, { value, children });
2828
+ }
2829
+ var PopoverTrigger = React11__namespace.forwardRef(
2830
+ ({ asChild, className, children, ...props }, ref) => {
2831
+ const { setOpen, triggerRef } = usePopoverContext();
2832
+ const handleClick = (e) => {
2833
+ setOpen(true);
2834
+ props.onClick?.(e);
2835
+ };
2836
+ if (asChild && React11__namespace.isValidElement(children)) {
2837
+ return React11__namespace.cloneElement(children, {
2838
+ ref: (node) => {
2839
+ triggerRef.current = node;
2840
+ if (typeof children.ref === "function") {
2841
+ children.ref(node);
2842
+ } else if (children.ref) {
2843
+ children.ref.current = node;
2844
+ }
2845
+ },
2846
+ onClick: handleClick
2847
+ });
2848
+ }
2849
+ return /* @__PURE__ */ jsxRuntime.jsx(
2850
+ "button",
2851
+ {
2852
+ ref: (node) => {
2853
+ triggerRef.current = node;
2854
+ if (typeof ref === "function") {
2855
+ ref(node);
2856
+ } else if (ref) {
2857
+ ref.current = node;
2858
+ }
2859
+ },
2860
+ className,
2861
+ onClick: handleClick,
2862
+ ...props,
2863
+ children
2864
+ }
2865
+ );
2866
+ }
2867
+ );
2868
+ PopoverTrigger.displayName = "PopoverTrigger";
2869
+ var PopoverContent = React11__namespace.forwardRef(
2870
+ ({
2871
+ className,
2872
+ side = "bottom",
2873
+ align = "start",
2874
+ sideOffset = 4,
2875
+ alignOffset = 0,
2876
+ children,
2877
+ ...props
2878
+ }, ref) => {
2879
+ const { open, setOpen, triggerRef } = usePopoverContext();
2880
+ const [position, setPosition] = React11__namespace.useState({ top: 0, left: 0 });
2881
+ const contentRef = React11__namespace.useRef(null);
2882
+ React11__namespace.useEffect(() => {
2883
+ if (!open || !triggerRef.current) return;
2884
+ const updatePosition = () => {
2885
+ if (!triggerRef.current || !contentRef.current) return;
2886
+ const triggerRect = triggerRef.current.getBoundingClientRect();
2887
+ const contentRect = contentRef.current.getBoundingClientRect();
2888
+ const scrollX = window.scrollX;
2889
+ const scrollY = window.scrollY;
2890
+ let top = 0;
2891
+ let left = 0;
2892
+ switch (side) {
2893
+ case "bottom":
2894
+ top = triggerRect.bottom + sideOffset + scrollY;
2895
+ break;
2896
+ case "top":
2897
+ top = triggerRect.top - contentRect.height - sideOffset + scrollY;
2898
+ break;
2899
+ case "right":
2900
+ top = triggerRect.top + scrollY;
2901
+ left = triggerRect.right + sideOffset + scrollX;
2902
+ break;
2903
+ case "left":
2904
+ top = triggerRect.top + scrollY;
2905
+ left = triggerRect.left - contentRect.width - sideOffset + scrollX;
2906
+ break;
2907
+ }
2908
+ switch (align) {
2909
+ case "start":
2910
+ if (side === "top" || side === "bottom") {
2911
+ left = triggerRect.left + scrollX + alignOffset;
2912
+ } else {
2913
+ top += alignOffset;
2914
+ }
2915
+ break;
2916
+ case "center":
2917
+ if (side === "top" || side === "bottom") {
2918
+ left = triggerRect.left + triggerRect.width / 2 - contentRect.width / 2 + scrollX + alignOffset;
2919
+ } else {
2920
+ top += triggerRect.height / 2 - contentRect.height / 2 + alignOffset;
2921
+ }
2922
+ break;
2923
+ case "end":
2924
+ if (side === "top" || side === "bottom") {
2925
+ left = triggerRect.left + triggerRect.width - contentRect.width + scrollX + alignOffset;
2926
+ } else {
2927
+ top += triggerRect.height - contentRect.height + alignOffset;
2928
+ }
2929
+ break;
2930
+ }
2931
+ setPosition({ top, left });
2932
+ };
2933
+ requestAnimationFrame(() => {
2934
+ updatePosition();
2935
+ });
2936
+ window.addEventListener("resize", updatePosition);
2937
+ window.addEventListener("scroll", updatePosition, true);
2938
+ return () => {
2939
+ window.removeEventListener("resize", updatePosition);
2940
+ window.removeEventListener("scroll", updatePosition, true);
2941
+ };
2942
+ }, [open, side, align, sideOffset, alignOffset, triggerRef]);
2943
+ React11__namespace.useEffect(() => {
2944
+ if (!open) return;
2945
+ const handleClickOutside = (event) => {
2946
+ if (contentRef.current && !contentRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
2947
+ setOpen(false);
2948
+ }
2949
+ };
2950
+ const handleEscape = (event) => {
2951
+ if (event.key === "Escape") {
2952
+ setOpen(false);
2953
+ }
2954
+ };
2955
+ document.addEventListener("mousedown", handleClickOutside);
2956
+ document.addEventListener("keydown", handleEscape);
2957
+ return () => {
2958
+ document.removeEventListener("mousedown", handleClickOutside);
2959
+ document.removeEventListener("keydown", handleEscape);
2960
+ };
2961
+ }, [open, setOpen, triggerRef]);
2962
+ if (!open) return null;
2963
+ const content = /* @__PURE__ */ jsxRuntime.jsx(
2964
+ "div",
2965
+ {
2966
+ ref: (node) => {
2967
+ contentRef.current = node;
2968
+ if (typeof ref === "function") {
2969
+ ref(node);
2970
+ } else if (ref) {
2971
+ ref.current = node;
2972
+ }
2973
+ },
2974
+ className: cn(
2975
+ "bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 ring-foreground/5 rounded-2xl shadow-2xl ring-1 z-50 min-w-48 max-h-96 overflow-hidden",
2976
+ className
2977
+ ),
2978
+ style: {
2979
+ position: "absolute",
2980
+ top: `${position.top}px`,
2981
+ left: `${position.left}px`
2982
+ },
2983
+ ...props,
2984
+ children
2985
+ }
2986
+ );
2987
+ return reactDom.createPortal(content, document.body);
2988
+ }
2989
+ );
2990
+ PopoverContent.displayName = "PopoverContent";
2991
+ var ThreadPopover = ({
2992
+ className,
2993
+ buttonClassName,
2994
+ buttonVariant = "ghost",
2995
+ buttonSize = "icon",
2996
+ emptyState,
2997
+ onThreadSelect
2998
+ }) => {
2999
+ const [isOpen, setIsOpen] = React11__namespace.useState(false);
3000
+ reactHotkeysHook.useHotkeys(
3001
+ "h",
3002
+ (e) => {
3003
+ e.preventDefault();
3004
+ setIsOpen((prev) => !prev);
3005
+ },
3006
+ {
3007
+ enableOnFormTags: false,
3008
+ // Don't trigger when typing in form inputs
3009
+ enableOnContentEditable: false
3010
+ // Don't trigger in contenteditable elements
3011
+ }
3012
+ );
3013
+ const handleThreadSelect = (threadId) => {
3014
+ setIsOpen(false);
3015
+ onThreadSelect?.(threadId);
3016
+ };
3017
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [
3018
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3019
+ Button,
3020
+ {
3021
+ variant: buttonVariant,
3022
+ size: buttonSize,
3023
+ className: cn(buttonClassName),
3024
+ children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconHistory, { className: "size-4" })
3025
+ }
3026
+ ) }),
3027
+ /* @__PURE__ */ jsxRuntime.jsx(
3028
+ PopoverContent,
3029
+ {
3030
+ className: cn("w-80 p-0", className),
3031
+ side: "bottom",
3032
+ align: "start",
3033
+ sideOffset: 8,
3034
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col h-[400px]", children: /* @__PURE__ */ jsxRuntime.jsx(
3035
+ ThreadList,
3036
+ {
3037
+ emptyState,
3038
+ onThreadSelect: handleThreadSelect,
3039
+ className: "h-full"
3040
+ }
3041
+ ) })
3042
+ }
3043
+ )
3044
+ ] });
3045
+ };
3046
+ var CreateThreadButton = ({
3047
+ className,
3048
+ variant = "ghost",
3049
+ size = "icon",
3050
+ children,
3051
+ onThreadCreated
3052
+ }) => {
3053
+ const { createThread } = useThreads();
3054
+ const [isCreating, setIsCreating] = React11__namespace.useState(false);
3055
+ const handleCreateThread = async () => {
3056
+ if (isCreating) return;
3057
+ try {
3058
+ setIsCreating(true);
3059
+ const threadId = await createThread();
3060
+ onThreadCreated?.(threadId);
3061
+ } catch (error) {
3062
+ console.error("Failed to create thread:", error);
3063
+ } finally {
3064
+ setIsCreating(false);
3065
+ }
3066
+ };
3067
+ reactHotkeysHook.useHotkeys(
3068
+ "n",
3069
+ (e) => {
3070
+ e.preventDefault();
3071
+ handleCreateThread();
3072
+ },
3073
+ {
3074
+ enableOnFormTags: false,
3075
+ // Don't trigger when typing in form inputs
3076
+ enableOnContentEditable: false
3077
+ // Don't trigger in contenteditable elements
3078
+ }
3079
+ );
3080
+ return /* @__PURE__ */ jsxRuntime.jsx(
3081
+ Button,
3082
+ {
3083
+ variant,
3084
+ size,
3085
+ onClick: handleCreateThread,
3086
+ disabled: isCreating,
3087
+ className: cn(className),
3088
+ children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconPlus, { className: "size-4" })
3089
+ }
3090
+ );
3091
+ };
2375
3092
  function AlertDialog({ ...props }) {
2376
3093
  return /* @__PURE__ */ jsxRuntime.jsx(alertDialog.AlertDialog.Root, { "data-slot": "alert-dialog", ...props });
2377
3094
  }
@@ -2454,100 +3171,111 @@ function AlertDialogDescription({
2454
3171
  }
2455
3172
  );
2456
3173
  }
2457
- function DropdownMenu({ ...props }) {
2458
- return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Root, { "data-slot": "dropdown-menu", ...props });
2459
- }
2460
- function DropdownMenuTrigger({ ...props }) {
2461
- return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
2462
- }
2463
- function DropdownMenuContent({
2464
- align = "start",
2465
- alignOffset = 0,
2466
- side = "bottom",
2467
- sideOffset = 4,
2468
- className,
2469
- ...props
2470
- }) {
2471
- return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
2472
- menu.Menu.Positioner,
2473
- {
2474
- className: "isolate z-50 outline-none",
2475
- align,
2476
- alignOffset,
2477
- side,
2478
- sideOffset,
2479
- children: /* @__PURE__ */ jsxRuntime.jsx(
2480
- menu.Menu.Popup,
2481
- {
2482
- "data-slot": "dropdown-menu-content",
2483
- className: cn("data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/5 bg-popover text-popover-foreground min-w-48 rounded-2xl p-1 shadow-2xl ring-1 duration-100 z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto outline-none data-closed:overflow-hidden", className),
2484
- ...props
2485
- }
2486
- )
2487
- }
2488
- ) });
2489
- }
2490
- function DropdownMenuItem({
2491
- className,
2492
- inset,
2493
- variant = "default",
2494
- ...props
2495
- }) {
2496
- return /* @__PURE__ */ jsxRuntime.jsx(
2497
- menu.Menu.Item,
2498
- {
2499
- "data-slot": "dropdown-menu-item",
2500
- "data-inset": inset,
2501
- "data-variant": variant,
2502
- className: cn(
2503
- "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2.5 rounded-xl px-3 py-2 text-sm [&_svg:not([class*='size-'])]:size-4 group/dropdown-menu-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0",
2504
- className
2505
- ),
2506
- ...props
2507
- }
2508
- );
2509
- }
2510
3174
  var AccountDialog = ({
2511
3175
  className,
2512
- variant,
3176
+ variant = "outline",
2513
3177
  size
2514
3178
  }) => {
2515
- const { isLoading, isAuthenticated, login, logout } = useAuth();
2516
- const [open, setOpen] = React10__namespace.useState(false);
2517
- const [error, setError] = React10__namespace.useState(null);
3179
+ const { isLoading, isAuthenticated, user, login, logout } = useAuth();
3180
+ const [open, setOpen] = React11__namespace.useState(false);
3181
+ const [accountInfoOpen, setAccountInfoOpen] = React11__namespace.useState(false);
3182
+ const [error, setError] = React11__namespace.useState(null);
3183
+ const initials = React11__namespace.useMemo(() => {
3184
+ const name = user?.displayName || user?.name;
3185
+ if (!name) return "";
3186
+ return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
3187
+ }, [user?.displayName, user?.name]);
2518
3188
  const handleGoogleSignIn = async () => {
2519
3189
  login();
2520
3190
  };
2521
3191
  if (isAuthenticated) {
2522
- return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
2523
- /* @__PURE__ */ jsxRuntime.jsx(
2524
- DropdownMenuTrigger,
2525
- {
2526
- render: (props) => /* @__PURE__ */ jsxRuntime.jsxs(
2527
- Button,
2528
- {
2529
- variant,
2530
- size,
2531
- ...props,
2532
- className,
2533
- children: [
2534
- /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconUser, { className: "mr-2 size-4" }),
2535
- "Account"
2536
- ]
2537
- }
2538
- )
2539
- }
2540
- ),
2541
- /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuContent, { children: [
2542
- /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
2543
- /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconUser, { className: "mr-2 size-4" }),
2544
- "Account"
3192
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3193
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
3194
+ /* @__PURE__ */ jsxRuntime.jsx(
3195
+ DropdownMenuTrigger,
3196
+ {
3197
+ render: (props) => /* @__PURE__ */ jsxRuntime.jsx(
3198
+ Button,
3199
+ {
3200
+ variant,
3201
+ size: "icon",
3202
+ ...props,
3203
+ className: cn("rounded-full", className),
3204
+ children: user?.picture ? /* @__PURE__ */ jsxRuntime.jsx(
3205
+ "img",
3206
+ {
3207
+ src: user.picture,
3208
+ alt: user.displayName || user.name,
3209
+ className: "size-7 rounded-full object-cover"
3210
+ }
3211
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex size-7 items-center justify-center rounded-full bg-muted text-xs font-bold", children: initials || /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconUser, { className: "size-4" }) })
3212
+ }
3213
+ )
3214
+ }
3215
+ ),
3216
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuContent, { align: "end", className: "w-56", children: [
3217
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 p-2", children: [
3218
+ user?.picture ? /* @__PURE__ */ jsxRuntime.jsx(
3219
+ "img",
3220
+ {
3221
+ src: user.picture,
3222
+ alt: user.displayName || user.name,
3223
+ className: "size-8 rounded-full object-cover"
3224
+ }
3225
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex size-8 items-center justify-center rounded-full bg-muted text-xs font-bold", children: initials || /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconUser, { className: "size-4" }) }),
3226
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col space-y-0.5 overflow-hidden", children: [
3227
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-sm font-medium", children: user?.displayName || user?.name }),
3228
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-xs text-muted-foreground", children: user?.email })
3229
+ ] })
3230
+ ] }),
3231
+ /* @__PURE__ */ jsxRuntime.jsx(Separator, { className: "my-1" }),
3232
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { onClick: () => setAccountInfoOpen(true), children: [
3233
+ /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconUser, { className: "mr-2 size-4" }),
3234
+ "Account Settings"
3235
+ ] }),
3236
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { onClick: logout, className: "text-destructive", children: [
3237
+ /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLogout, { className: "mr-2 size-4" }),
3238
+ "Logout"
3239
+ ] })
3240
+ ] })
3241
+ ] }),
3242
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: accountInfoOpen, onOpenChange: setAccountInfoOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "sm:max-w-md", children: [
3243
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
3244
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Account Information" }),
3245
+ /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Your account details and settings." })
2545
3246
  ] }),
2546
- /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { onClick: logout, children: [
2547
- /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLogout, { className: "mr-2 size-4" }),
2548
- "Logout"
3247
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogClose, { children: [
3248
+ /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconX, { className: "size-4" }),
3249
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
3250
+ ] }),
3251
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 py-4", children: [
3252
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
3253
+ user?.picture ? /* @__PURE__ */ jsxRuntime.jsx(
3254
+ "img",
3255
+ {
3256
+ src: user.picture,
3257
+ alt: user.displayName || user.name,
3258
+ className: "size-16 rounded-full object-cover"
3259
+ }
3260
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex size-16 items-center justify-center rounded-full bg-muted text-xl font-bold", children: initials || /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconUser, { className: "size-8 text-muted-foreground" }) }),
3261
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
3262
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold", children: user?.displayName || user?.name }),
3263
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: user?.email })
3264
+ ] })
3265
+ ] }),
3266
+ /* @__PURE__ */ jsxRuntime.jsx(Separator, {}),
3267
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
3268
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
3269
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-muted-foreground", children: "User ID" }),
3270
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-mono text-xs truncate", children: user?.uid || user?.id })
3271
+ ] }),
3272
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
3273
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-muted-foreground", children: "Created At" }),
3274
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs", children: user?.createdAt || "N/A" })
3275
+ ] })
3276
+ ] })
2549
3277
  ] })
2550
- ] })
3278
+ ] }) })
2551
3279
  ] });
2552
3280
  }
2553
3281
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -2633,6 +3361,7 @@ exports.ChatHeader = ChatHeader;
2633
3361
  exports.ChatPopup = ChatPopup;
2634
3362
  exports.ChatSidebar = ChatSidebar;
2635
3363
  exports.Composer = Composer;
3364
+ exports.CreateThreadButton = CreateThreadButton;
2636
3365
  exports.MelonyClientProvider = MelonyClientProvider;
2637
3366
  exports.MelonyContext = MelonyContext;
2638
3367
  exports.ThemeProvider = ThemeProvider;
@@ -2640,6 +3369,7 @@ exports.ThemeToggle = ThemeToggle;
2640
3369
  exports.Thread = Thread;
2641
3370
  exports.ThreadContext = ThreadContext;
2642
3371
  exports.ThreadList = ThreadList;
3372
+ exports.ThreadPopover = ThreadPopover;
2643
3373
  exports.ThreadProvider = ThreadProvider;
2644
3374
  exports.UIRenderer = UIRenderer;
2645
3375
  exports.groupEventsToMessages = groupEventsToMessages;