@melony/react 0.1.23 → 0.1.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React10 = require('react');
3
+ var React11 = require('react');
4
4
  var react = require('nuqs/adapters/react');
5
5
  var reactQuery = require('@tanstack/react-query');
6
6
  var jsxRuntime = require('react/jsx-runtime');
@@ -10,12 +10,12 @@ var clsx = require('clsx');
10
10
  var tailwindMerge = require('tailwind-merge');
11
11
  var button = require('@base-ui/react/button');
12
12
  var classVarianceAuthority = require('class-variance-authority');
13
+ var mergeProps = require('@base-ui/react/merge-props');
14
+ var useRender = require('@base-ui/react/use-render');
13
15
  var ICONS = require('@tabler/icons-react');
14
16
  var menu = require('@base-ui/react/menu');
15
17
  var separator = require('@base-ui/react/separator');
16
18
  var dialog = require('@base-ui/react/dialog');
17
- var mergeProps = require('@base-ui/react/merge-props');
18
- var useRender = require('@base-ui/react/use-render');
19
19
  var input = require('@base-ui/react/input');
20
20
  var select = require('@base-ui/react/select');
21
21
  var reactDom = require('react-dom');
@@ -40,7 +40,7 @@ function _interopNamespace(e) {
40
40
  return Object.freeze(n);
41
41
  }
42
42
 
43
- var React10__namespace = /*#__PURE__*/_interopNamespace(React10);
43
+ var React11__namespace = /*#__PURE__*/_interopNamespace(React11);
44
44
  var ICONS__namespace = /*#__PURE__*/_interopNamespace(ICONS);
45
45
 
46
46
  // src/providers/melony-provider.tsx
@@ -69,7 +69,7 @@ function groupEventsToMessages(events) {
69
69
  }
70
70
  return messages;
71
71
  }
72
- var MelonyContext = React10.createContext(
72
+ var MelonyContext = React11.createContext(
73
73
  void 0
74
74
  );
75
75
  var defaultQueryClient = new reactQuery.QueryClient({
@@ -84,41 +84,78 @@ var MelonyContextProviderInner = ({
84
84
  children,
85
85
  client,
86
86
  initialEvents,
87
- configApi,
88
87
  setContextValue
89
88
  }) => {
90
- const [state, setState] = React10.useState(client.getState());
89
+ const [state, setState] = React11.useState(client.getState());
91
90
  const { data: config } = reactQuery.useQuery({
92
- queryKey: ["melony-config", configApi],
93
- queryFn: () => client.getConfig(configApi),
94
- enabled: !!configApi,
91
+ queryKey: ["melony-config", client.url],
92
+ queryFn: () => client.getConfig(),
95
93
  staleTime: Infinity
96
94
  });
97
- React10.useEffect(() => {
95
+ React11.useEffect(() => {
98
96
  if (initialEvents && initialEvents.length > 0 && client.getState().events.length === 0) {
99
97
  client.reset(initialEvents);
100
98
  }
101
99
  }, [client, initialEvents]);
102
- React10.useEffect(() => {
100
+ React11.useEffect(() => {
103
101
  setState(client.getState());
104
102
  const unsubscribe = client.subscribe(setState);
105
103
  return () => {
106
104
  unsubscribe();
107
105
  };
108
106
  }, [client]);
109
- const sendEvent = React10.useCallback(
107
+ const reset = React11.useCallback(
108
+ (events) => client.reset(events),
109
+ [client]
110
+ );
111
+ const dispatchClientAction = React11.useCallback(
112
+ async (event) => {
113
+ if (!event.type.startsWith("client:")) return false;
114
+ switch (event.type) {
115
+ case "client:navigate": {
116
+ const url = event.data?.url;
117
+ if (url) {
118
+ window.history.pushState(null, "", url);
119
+ window.dispatchEvent(new PopStateEvent("popstate"));
120
+ }
121
+ return true;
122
+ }
123
+ case "client:open-url": {
124
+ const { url, target = "_blank" } = event.data || {};
125
+ if (url) {
126
+ window.open(url, target);
127
+ }
128
+ return true;
129
+ }
130
+ case "client:copy": {
131
+ const { text } = event.data || {};
132
+ if (text) {
133
+ await navigator.clipboard.writeText(text);
134
+ }
135
+ return true;
136
+ }
137
+ case "client:reset": {
138
+ reset([]);
139
+ return true;
140
+ }
141
+ default:
142
+ return false;
143
+ }
144
+ },
145
+ [client, reset]
146
+ );
147
+ const sendEvent = React11.useCallback(
110
148
  async (event, options) => {
149
+ const handled = await dispatchClientAction(event);
150
+ if (handled) return;
111
151
  const generator = client.sendEvent(event, options);
112
- for await (const _ of generator) {
152
+ for await (const incomingEvent of generator) {
153
+ await dispatchClientAction(incomingEvent);
113
154
  }
114
155
  },
115
- [client]
156
+ [client, dispatchClientAction]
116
157
  );
117
- const reset = React10.useCallback(
118
- (events) => client.reset(events),
119
- [client]
120
- );
121
- const value = React10.useMemo(
158
+ const value = React11.useMemo(
122
159
  () => ({
123
160
  ...state,
124
161
  messages: groupEventsToMessages(state.events),
@@ -129,7 +166,7 @@ var MelonyContextProviderInner = ({
129
166
  }),
130
167
  [state, sendEvent, reset, client, config]
131
168
  );
132
- React10.useEffect(() => {
169
+ React11.useEffect(() => {
133
170
  setContextValue(value);
134
171
  }, [value, setContextValue]);
135
172
  return /* @__PURE__ */ jsxRuntime.jsx(react.NuqsAdapter, { children });
@@ -138,31 +175,29 @@ var MelonyClientProvider = ({
138
175
  children,
139
176
  client,
140
177
  initialEvents,
141
- queryClient = defaultQueryClient,
142
- configApi
178
+ queryClient = defaultQueryClient
143
179
  }) => {
144
- const [contextValue, setContextValue] = React10.useState(void 0);
180
+ const [contextValue, setContextValue] = React11.useState(void 0);
145
181
  return /* @__PURE__ */ jsxRuntime.jsx(MelonyContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsxRuntime.jsx(
146
182
  MelonyContextProviderInner,
147
183
  {
148
184
  client,
149
185
  initialEvents,
150
- configApi,
151
186
  setContextValue,
152
187
  children
153
188
  }
154
189
  ) }) });
155
190
  };
156
- var AuthContext = React10.createContext(
191
+ var AuthContext = React11.createContext(
157
192
  void 0
158
193
  );
159
194
  var AuthProvider = ({
160
195
  children,
161
196
  service
162
197
  }) => {
163
- const [user, setUser] = React10.useState(null);
164
- const [isLoading, setIsLoading] = React10.useState(true);
165
- const fetchMe = React10.useCallback(async () => {
198
+ const [user, setUser] = React11.useState(null);
199
+ const [isLoading, setIsLoading] = React11.useState(true);
200
+ const fetchMe = React11.useCallback(async () => {
166
201
  setIsLoading(true);
167
202
  try {
168
203
  const userData = await service.getMe();
@@ -174,13 +209,13 @@ var AuthProvider = ({
174
209
  setIsLoading(false);
175
210
  }
176
211
  }, [service]);
177
- React10.useEffect(() => {
212
+ React11.useEffect(() => {
178
213
  fetchMe();
179
214
  }, [fetchMe]);
180
- const login = React10.useCallback(() => {
215
+ const login = React11.useCallback(() => {
181
216
  service.login();
182
217
  }, [service]);
183
- const logout = React10.useCallback(async () => {
218
+ const logout = React11.useCallback(async () => {
184
219
  try {
185
220
  await service.logout();
186
221
  setUser(null);
@@ -216,7 +251,7 @@ var AuthProvider = ({
216
251
  }
217
252
  return /* @__PURE__ */ jsxRuntime.jsx(AuthContext.Provider, { value, children });
218
253
  };
219
- var ThreadContext = React10.createContext(
254
+ var ThreadContext = React11.createContext(
220
255
  void 0
221
256
  );
222
257
  var ThreadProvider = ({
@@ -225,7 +260,7 @@ var ThreadProvider = ({
225
260
  initialThreadId: providedInitialThreadId
226
261
  }) => {
227
262
  const queryClient = reactQuery.useQueryClient();
228
- const defaultInitialThreadId = React10.useMemo(() => client.generateId(), []);
263
+ const defaultInitialThreadId = React11.useMemo(() => client.generateId(), []);
229
264
  const initialThreadId = providedInitialThreadId || defaultInitialThreadId;
230
265
  const [activeThreadId, setActiveThreadId] = nuqs.useQueryState(
231
266
  "threadId",
@@ -266,22 +301,22 @@ var ThreadProvider = ({
266
301
  }
267
302
  }
268
303
  });
269
- const selectThread = React10.useCallback(
304
+ const selectThread = React11.useCallback(
270
305
  (threadId) => {
271
306
  setActiveThreadId(threadId);
272
307
  },
273
308
  [setActiveThreadId]
274
309
  );
275
- const createThread = React10.useCallback(async () => {
310
+ const createThread = React11.useCallback(async () => {
276
311
  return createMutation.mutateAsync();
277
312
  }, [createMutation]);
278
- const deleteThread = React10.useCallback(
313
+ const deleteThread = React11.useCallback(
279
314
  async (threadId) => {
280
315
  return deleteMutation.mutateAsync(threadId);
281
316
  },
282
317
  [deleteMutation]
283
318
  );
284
- const value = React10.useMemo(
319
+ const value = React11.useMemo(
285
320
  () => ({
286
321
  threads,
287
322
  activeThreadId,
@@ -311,11 +346,11 @@ var ThreadProvider = ({
311
346
  );
312
347
  return /* @__PURE__ */ jsxRuntime.jsx(ThreadContext.Provider, { value, children });
313
348
  };
314
- var ThemeContext = React10.createContext(void 0);
349
+ var ThemeContext = React11.createContext(void 0);
315
350
  function ThemeProvider({ children }) {
316
- const [theme, setThemeState] = React10.useState("system");
317
- const [resolvedTheme, setResolvedTheme] = React10.useState("light");
318
- React10.useEffect(() => {
351
+ const [theme, setThemeState] = React11.useState("system");
352
+ const [resolvedTheme, setResolvedTheme] = React11.useState("light");
353
+ React11.useEffect(() => {
319
354
  if (typeof window !== "undefined") {
320
355
  const stored = localStorage.getItem("theme");
321
356
  if (stored) {
@@ -323,7 +358,7 @@ function ThemeProvider({ children }) {
323
358
  }
324
359
  }
325
360
  }, []);
326
- React10.useEffect(() => {
361
+ React11.useEffect(() => {
327
362
  if (typeof window !== "undefined") {
328
363
  if (theme === "system") {
329
364
  const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
@@ -338,7 +373,7 @@ function ThemeProvider({ children }) {
338
373
  }
339
374
  }
340
375
  }, [theme]);
341
- React10.useEffect(() => {
376
+ React11.useEffect(() => {
342
377
  if (typeof window !== "undefined") {
343
378
  const root = document.documentElement;
344
379
  if (resolvedTheme === "dark") {
@@ -357,21 +392,21 @@ function ThemeProvider({ children }) {
357
392
  return /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value: { theme, setTheme, resolvedTheme }, children });
358
393
  }
359
394
  function useTheme() {
360
- const context = React10.useContext(ThemeContext);
395
+ const context = React11.useContext(ThemeContext);
361
396
  if (context === void 0) {
362
397
  throw new Error("useTheme must be used within a ThemeProvider");
363
398
  }
364
399
  return context;
365
400
  }
366
401
  var useMelony = (options) => {
367
- const context = React10.useContext(MelonyContext);
402
+ const context = React11.useContext(MelonyContext);
368
403
  if (context === void 0) {
369
404
  throw new Error("useMelony must be used within a MelonyClientProvider");
370
405
  }
371
406
  const { client, reset } = context;
372
407
  const { initialEvents } = options || {};
373
- const prevInitialEventsRef = React10.useRef(void 0);
374
- React10.useEffect(() => {
408
+ const prevInitialEventsRef = React11.useRef(void 0);
409
+ React11.useEffect(() => {
375
410
  const currentSerialized = initialEvents ? JSON.stringify(initialEvents) : void 0;
376
411
  if (currentSerialized !== prevInitialEventsRef.current) {
377
412
  if (initialEvents) {
@@ -385,19 +420,60 @@ var useMelony = (options) => {
385
420
  return context;
386
421
  };
387
422
  var useAuth = () => {
388
- const context = React10.useContext(AuthContext);
423
+ const context = React11.useContext(AuthContext);
389
424
  if (context === void 0) {
390
425
  throw new Error("useAuth must be used within an AuthProvider");
391
426
  }
392
427
  return context;
393
428
  };
394
429
  var useThreads = () => {
395
- const context = React10.useContext(ThreadContext);
430
+ const context = React11.useContext(ThreadContext);
396
431
  if (context === void 0) {
397
432
  throw new Error("useThreads must be used within a ThreadProvider");
398
433
  }
399
434
  return context;
400
435
  };
436
+ function useScreenSize(mobileBreakpoint = 768, tabletBreakpoint = 1024) {
437
+ const [screenSize, setScreenSize] = React11.useState(() => {
438
+ if (typeof window === "undefined") {
439
+ return {
440
+ width: 1024,
441
+ height: 768,
442
+ isMobile: false,
443
+ isTablet: false,
444
+ isDesktop: true
445
+ };
446
+ }
447
+ const width = window.innerWidth;
448
+ return {
449
+ width,
450
+ height: window.innerHeight,
451
+ isMobile: width < mobileBreakpoint,
452
+ isTablet: width >= mobileBreakpoint && width < tabletBreakpoint,
453
+ isDesktop: width >= tabletBreakpoint
454
+ };
455
+ });
456
+ React11.useEffect(() => {
457
+ if (typeof window === "undefined") return;
458
+ const updateScreenSize = () => {
459
+ const width = window.innerWidth;
460
+ const height = window.innerHeight;
461
+ setScreenSize({
462
+ width,
463
+ height,
464
+ isMobile: width < mobileBreakpoint,
465
+ isTablet: width >= mobileBreakpoint && width < tabletBreakpoint,
466
+ isDesktop: width >= tabletBreakpoint
467
+ });
468
+ };
469
+ updateScreenSize();
470
+ window.addEventListener("resize", updateScreenSize);
471
+ return () => {
472
+ window.removeEventListener("resize", updateScreenSize);
473
+ };
474
+ }, [mobileBreakpoint, tabletBreakpoint]);
475
+ return screenSize;
476
+ }
401
477
  function cn(...inputs) {
402
478
  return tailwindMerge.twMerge(clsx.clsx(inputs));
403
479
  }
@@ -458,6 +534,45 @@ function Textarea({ className, ...props }) {
458
534
  }
459
535
  );
460
536
  }
537
+ var badgeVariants = classVarianceAuthority.cva(
538
+ "h-5 gap-1 rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium transition-all has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-3! inline-flex items-center justify-center w-fit whitespace-nowrap shrink-0 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-colors overflow-hidden group/badge",
539
+ {
540
+ variants: {
541
+ variant: {
542
+ default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
543
+ secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
544
+ destructive: "bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20",
545
+ outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground bg-input/30",
546
+ ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
547
+ link: "text-primary underline-offset-4 hover:underline"
548
+ }
549
+ },
550
+ defaultVariants: {
551
+ variant: "default"
552
+ }
553
+ }
554
+ );
555
+ function Badge({
556
+ className,
557
+ variant = "default",
558
+ render,
559
+ ...props
560
+ }) {
561
+ return useRender.useRender({
562
+ defaultTagName: "span",
563
+ props: mergeProps.mergeProps(
564
+ {
565
+ className: cn(badgeVariants({ className, variant }))
566
+ },
567
+ props
568
+ ),
569
+ render,
570
+ state: {
571
+ slot: "badge",
572
+ variant
573
+ }
574
+ });
575
+ }
461
576
  function DropdownMenu({ ...props }) {
462
577
  return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Root, { "data-slot": "dropdown-menu", ...props });
463
578
  }
@@ -584,11 +699,18 @@ function Composer({
584
699
  className,
585
700
  options = [],
586
701
  autoFocus = false,
587
- defaultSelectedIds = []
702
+ defaultSelectedIds = [],
703
+ fileAttachments
588
704
  }) {
589
- const [selectedOptions, setSelectedOptions] = React10__namespace.default.useState(
705
+ const enabled = fileAttachments?.enabled || false;
706
+ const accept = fileAttachments?.accept;
707
+ const maxFiles = fileAttachments?.maxFiles ?? 10;
708
+ const maxFileSize = fileAttachments?.maxFileSize ?? 10 * 1024 * 1024;
709
+ const [selectedOptions, setSelectedOptions] = React11__namespace.default.useState(
590
710
  () => new Set(defaultSelectedIds)
591
711
  );
712
+ const [attachedFiles, setAttachedFiles] = React11__namespace.default.useState([]);
713
+ const fileInputRef = React11__namespace.default.useRef(null);
592
714
  const toggleOption = (id, groupOptions, type = "multiple") => {
593
715
  const next = new Set(selectedOptions);
594
716
  if (type === "single") {
@@ -608,7 +730,38 @@ function Composer({
608
730
  }
609
731
  setSelectedOptions(next);
610
732
  };
611
- const handleInternalSubmit = () => {
733
+ const handleFileSelect = (e) => {
734
+ const files = Array.from(e.target.files || []);
735
+ const validFiles = files.filter((file) => {
736
+ if (file.size > maxFileSize) {
737
+ console.warn(
738
+ `File ${file.name} exceeds maximum size of ${maxFileSize} bytes`
739
+ );
740
+ return false;
741
+ }
742
+ return true;
743
+ });
744
+ const remainingSlots = maxFiles - attachedFiles.length;
745
+ const filesToAdd = validFiles.slice(0, remainingSlots);
746
+ if (filesToAdd.length < validFiles.length) {
747
+ console.warn(
748
+ `Only ${filesToAdd.length} files can be added (max: ${maxFiles})`
749
+ );
750
+ }
751
+ setAttachedFiles((prev) => [...prev, ...filesToAdd]);
752
+ if (fileInputRef.current) {
753
+ fileInputRef.current.value = "";
754
+ }
755
+ };
756
+ const handleRemoveFile = (index) => {
757
+ setAttachedFiles((prev) => prev.filter((_, i) => i !== index));
758
+ };
759
+ const formatFileSize = (bytes) => {
760
+ if (bytes < 1024) return bytes + " B";
761
+ if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + " KB";
762
+ return (bytes / (1024 * 1024)).toFixed(1) + " MB";
763
+ };
764
+ const handleInternalSubmit = async () => {
612
765
  const state = {};
613
766
  options.forEach((group) => {
614
767
  const selectedInGroup = group.options.filter(
@@ -625,12 +778,52 @@ function Composer({
625
778
  }
626
779
  }
627
780
  });
781
+ if (attachedFiles.length > 0) {
782
+ const filePromises = attachedFiles.map((file) => {
783
+ return new Promise((resolve, reject) => {
784
+ const reader = new FileReader();
785
+ reader.onload = () => {
786
+ try {
787
+ const base64 = reader.result;
788
+ if (!base64) {
789
+ reject(new Error("FileReader returned empty result"));
790
+ return;
791
+ }
792
+ resolve({
793
+ name: file.name,
794
+ type: file.type,
795
+ size: file.size,
796
+ data: base64
797
+ });
798
+ } catch (error) {
799
+ reject(error);
800
+ }
801
+ };
802
+ reader.onerror = (error) => {
803
+ reject(new Error(`Failed to read file ${file.name}: ${error}`));
804
+ };
805
+ reader.onabort = () => {
806
+ reject(new Error(`File read aborted for ${file.name}`));
807
+ };
808
+ reader.readAsDataURL(file);
809
+ });
810
+ });
811
+ try {
812
+ const convertedFiles = await Promise.all(filePromises);
813
+ if (convertedFiles.length > 0) {
814
+ state.files = convertedFiles;
815
+ }
816
+ } catch (error) {
817
+ console.error("Failed to convert files to base64:", error);
818
+ }
819
+ }
628
820
  onSubmit(state);
821
+ setAttachedFiles([]);
629
822
  };
630
823
  const handleKeyDown = (e) => {
631
824
  if (e.key === "Enter" && !e.shiftKey) {
632
825
  e.preventDefault();
633
- handleInternalSubmit();
826
+ handleInternalSubmit().catch(console.error);
634
827
  }
635
828
  };
636
829
  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: [
@@ -646,59 +839,171 @@ function Composer({
646
839
  }
647
840
  ),
648
841
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center px-1", children: [
649
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: options.map((group) => {
650
- const selectedInGroup = group.options.filter(
651
- (o) => selectedOptions.has(o.id)
652
- );
653
- const label = selectedInGroup.length === 0 ? group.label : selectedInGroup.length === 1 ? selectedInGroup[0].label : `${group.label} (${selectedInGroup.length})`;
654
- const isSingle = group.type === "single";
655
- return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
842
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
843
+ enabled && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
656
844
  /* @__PURE__ */ jsxRuntime.jsx(
657
- DropdownMenuTrigger,
845
+ "input",
658
846
  {
659
- render: /* @__PURE__ */ jsxRuntime.jsxs(
660
- Button,
661
- {
662
- variant: "ghost",
663
- size: "sm",
664
- className: cn(
665
- selectedInGroup.length > 0 ? "text-foreground bg-muted/50" : "text-muted-foreground"
666
- ),
667
- children: [
668
- label,
669
- /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronDown, { className: "h-3 w-3 opacity-50" })
670
- ]
671
- }
672
- )
847
+ ref: fileInputRef,
848
+ type: "file",
849
+ multiple: true,
850
+ accept,
851
+ onChange: handleFileSelect,
852
+ className: "hidden",
853
+ disabled: isLoading || attachedFiles.length >= maxFiles
673
854
  }
674
855
  ),
675
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "start", className: "w-56", children: /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuGroup, { children: [
676
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuLabel, { children: group.label }),
677
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
678
- group.options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
679
- DropdownMenuCheckboxItem,
856
+ attachedFiles.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(
857
+ Button,
858
+ {
859
+ type: "button",
860
+ variant: "ghost",
861
+ size: "sm",
862
+ onClick: () => fileInputRef.current?.click(),
863
+ disabled: isLoading,
864
+ className: "text-muted-foreground",
865
+ title: "Attach file",
866
+ children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconPaperclip, { className: "h-4 w-4" })
867
+ }
868
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
869
+ /* @__PURE__ */ jsxRuntime.jsx(
870
+ DropdownMenuTrigger,
680
871
  {
681
- checked: selectedOptions.has(option.id),
682
- onCheckedChange: () => toggleOption(
683
- option.id,
684
- group.options,
685
- isSingle ? "single" : "multiple"
686
- ),
687
- onSelect: (e) => e.preventDefault(),
688
- children: option.label
689
- },
690
- option.id
691
- ))
692
- ] }) })
693
- ] }, group.id);
694
- }) }),
872
+ render: /* @__PURE__ */ jsxRuntime.jsxs(
873
+ Button,
874
+ {
875
+ type: "button",
876
+ variant: "ghost",
877
+ size: "sm",
878
+ className: "text-muted-foreground gap-2",
879
+ title: `${attachedFiles.length} files attached`,
880
+ children: [
881
+ /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconPaperclip, { className: "h-4 w-4" }),
882
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "h-[18px] min-w-[18px] px-1.5 text-[10px]", children: attachedFiles.length })
883
+ ]
884
+ }
885
+ )
886
+ }
887
+ ),
888
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuContent, { align: "start", className: "w-64", children: [
889
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuGroup, { children: [
890
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuLabel, { children: [
891
+ "Attached Files (",
892
+ attachedFiles.length,
893
+ "/",
894
+ maxFiles,
895
+ ")"
896
+ ] }),
897
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
898
+ attachedFiles.map((file, index) => /* @__PURE__ */ jsxRuntime.jsxs(
899
+ DropdownMenuItem,
900
+ {
901
+ className: "flex items-center justify-between group",
902
+ onSelect: (e) => e.preventDefault(),
903
+ children: [
904
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
905
+ /* @__PURE__ */ jsxRuntime.jsx(
906
+ "span",
907
+ {
908
+ className: "truncate text-sm",
909
+ title: file.name,
910
+ children: file.name
911
+ }
912
+ ),
913
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: formatFileSize(file.size) })
914
+ ] }),
915
+ /* @__PURE__ */ jsxRuntime.jsx(
916
+ Button,
917
+ {
918
+ type: "button",
919
+ variant: "ghost",
920
+ size: "icon",
921
+ className: "h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity",
922
+ onClick: () => handleRemoveFile(index),
923
+ children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconX, { className: "h-3 w-3" })
924
+ }
925
+ )
926
+ ]
927
+ },
928
+ index
929
+ ))
930
+ ] }),
931
+ attachedFiles.length < maxFiles && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
932
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
933
+ /* @__PURE__ */ jsxRuntime.jsxs(
934
+ DropdownMenuItem,
935
+ {
936
+ onSelect: (e) => {
937
+ e.preventDefault();
938
+ fileInputRef.current?.click();
939
+ },
940
+ className: "text-primary focus:text-primary",
941
+ children: [
942
+ /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconPlus, { className: "mr-2 h-4 w-4" }),
943
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Add more files" })
944
+ ]
945
+ }
946
+ )
947
+ ] })
948
+ ] })
949
+ ] })
950
+ ] }),
951
+ options.map((group) => {
952
+ const selectedInGroup = group.options.filter(
953
+ (o) => selectedOptions.has(o.id)
954
+ );
955
+ const label = selectedInGroup.length === 0 ? group.label : selectedInGroup.length === 1 ? selectedInGroup[0].label : group.label;
956
+ const isSingle = group.type === "single";
957
+ return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
958
+ /* @__PURE__ */ jsxRuntime.jsx(
959
+ DropdownMenuTrigger,
960
+ {
961
+ render: /* @__PURE__ */ jsxRuntime.jsxs(
962
+ Button,
963
+ {
964
+ variant: "ghost",
965
+ size: "sm",
966
+ className: cn(
967
+ "gap-2",
968
+ selectedInGroup.length > 0 ? "text-foreground bg-muted/50" : "text-muted-foreground"
969
+ ),
970
+ children: [
971
+ label,
972
+ selectedInGroup.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(Badge, { className: "h-[18px] min-w-[18px] px-1.5 text-[10px]", children: selectedInGroup.length }),
973
+ /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronDown, { className: "h-3 w-3 opacity-50" })
974
+ ]
975
+ }
976
+ )
977
+ }
978
+ ),
979
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "start", className: "w-56", children: /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuGroup, { children: [
980
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuLabel, { children: group.label }),
981
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
982
+ group.options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
983
+ DropdownMenuCheckboxItem,
984
+ {
985
+ checked: selectedOptions.has(option.id),
986
+ onCheckedChange: () => toggleOption(
987
+ option.id,
988
+ group.options,
989
+ isSingle ? "single" : "multiple"
990
+ ),
991
+ onSelect: (e) => e.preventDefault(),
992
+ children: option.label
993
+ },
994
+ option.id
995
+ ))
996
+ ] }) })
997
+ ] }, group.id);
998
+ })
999
+ ] }),
695
1000
  /* @__PURE__ */ jsxRuntime.jsx(
696
1001
  Button,
697
1002
  {
698
1003
  type: "submit",
699
- disabled: !value.trim() && !isLoading || isLoading,
1004
+ disabled: !value.trim() && attachedFiles.length === 0 && !isLoading || isLoading,
700
1005
  size: "icon-lg",
701
- onClick: handleInternalSubmit,
1006
+ onClick: () => handleInternalSubmit().catch(console.error),
702
1007
  children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLoader2, { className: "h-5 w-5 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconArrowUp, { className: "h-5 w-5" })
703
1008
  }
704
1009
  )
@@ -835,8 +1140,6 @@ var Col = ({
835
1140
  gap = "sm",
836
1141
  align = "start",
837
1142
  justify = "start",
838
- wrap = "nowrap",
839
- flex = 1,
840
1143
  width,
841
1144
  height,
842
1145
  padding,
@@ -886,13 +1189,11 @@ var Col = ({
886
1189
  gapClasses[gap] || "gap-2",
887
1190
  alignClasses[align] || "items-start",
888
1191
  justifyClasses[justify] || "justify-start",
889
- wrap === "wrap" ? "flex-wrap" : "flex-nowrap",
890
1192
  overflow && overflowClasses[overflow],
891
1193
  position && positionClasses[position],
892
1194
  className
893
1195
  ),
894
1196
  style: {
895
- flex,
896
1197
  width,
897
1198
  height,
898
1199
  padding,
@@ -1200,9 +1501,9 @@ var Image = ({
1200
1501
  className,
1201
1502
  style
1202
1503
  }) => {
1203
- const [hasError, setHasError] = React10.useState(false);
1204
- const [isLoading, setIsLoading] = React10.useState(true);
1205
- const [open, setOpen] = React10.useState(false);
1504
+ const [hasError, setHasError] = React11.useState(false);
1505
+ const [isLoading, setIsLoading] = React11.useState(true);
1506
+ const [open, setOpen] = React11.useState(false);
1206
1507
  const sizes = {
1207
1508
  sm: "h-11",
1208
1509
  md: "h-22",
@@ -1326,45 +1627,6 @@ var Icon = ({
1326
1627
  }
1327
1628
  );
1328
1629
  };
1329
- var badgeVariants = classVarianceAuthority.cva(
1330
- "h-5 gap-1 rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium transition-all has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-3! inline-flex items-center justify-center w-fit whitespace-nowrap shrink-0 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-colors overflow-hidden group/badge",
1331
- {
1332
- variants: {
1333
- variant: {
1334
- default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
1335
- secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
1336
- destructive: "bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20",
1337
- outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground bg-input/30",
1338
- ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
1339
- link: "text-primary underline-offset-4 hover:underline"
1340
- }
1341
- },
1342
- defaultVariants: {
1343
- variant: "default"
1344
- }
1345
- }
1346
- );
1347
- function Badge({
1348
- className,
1349
- variant = "default",
1350
- render,
1351
- ...props
1352
- }) {
1353
- return useRender.useRender({
1354
- defaultTagName: "span",
1355
- props: mergeProps.mergeProps(
1356
- {
1357
- className: cn(badgeVariants({ className, variant }))
1358
- },
1359
- props
1360
- ),
1361
- render,
1362
- state: {
1363
- slot: "badge",
1364
- variant
1365
- }
1366
- });
1367
- }
1368
1630
  var Badge2 = ({
1369
1631
  label,
1370
1632
  variant = "primary",
@@ -1400,7 +1662,7 @@ var Chart = ({
1400
1662
  className,
1401
1663
  style
1402
1664
  }) => {
1403
- const [tooltip, setTooltip] = React10.useState(null);
1665
+ const [tooltip, setTooltip] = React11.useState(null);
1404
1666
  if (!Array.isArray(data)) {
1405
1667
  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" });
1406
1668
  }
@@ -1953,9 +2215,9 @@ var Select2 = ({
1953
2215
  defaultValue,
1954
2216
  value,
1955
2217
  disabled,
1956
- onValueChange: handleValueChange,
2218
+ onValueChange: (value2) => handleValueChange(value2 || ""),
1957
2219
  children: [
1958
- /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: placeholder || "Select an option" }) }),
2220
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, {}) }),
1959
2221
  /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
1960
2222
  ]
1961
2223
  }
@@ -1985,7 +2247,6 @@ var Label2 = ({
1985
2247
  var Checkbox = ({
1986
2248
  label,
1987
2249
  name,
1988
- value = "on",
1989
2250
  checked,
1990
2251
  defaultChecked,
1991
2252
  disabled,
@@ -2000,46 +2261,37 @@ var Checkbox = ({
2000
2261
  ...onChangeAction,
2001
2262
  data: {
2002
2263
  name: name || "",
2003
- value,
2004
2264
  checked: e.target.checked
2005
2265
  }
2006
2266
  });
2007
2267
  }
2008
2268
  };
2009
- return /* @__PURE__ */ jsxRuntime.jsxs(
2010
- "div",
2011
- {
2012
- className: cn("flex items-center gap-2", className),
2013
- style,
2014
- children: [
2015
- /* @__PURE__ */ jsxRuntime.jsx(
2016
- "input",
2017
- {
2018
- type: "checkbox",
2019
- name,
2020
- id: name,
2021
- value,
2022
- checked,
2023
- defaultChecked,
2024
- disabled,
2025
- onChange: handleChange,
2026
- className: "h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary disabled:cursor-not-allowed disabled:opacity-50"
2027
- }
2028
- ),
2029
- label && /* @__PURE__ */ jsxRuntime.jsx(
2030
- Label2,
2031
- {
2032
- htmlFor: name,
2033
- value: label,
2034
- className: cn(
2035
- "cursor-pointer select-none text-sm font-medium leading-none",
2036
- disabled && "cursor-not-allowed opacity-50"
2037
- )
2038
- }
2269
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center gap-2", className), style, children: [
2270
+ /* @__PURE__ */ jsxRuntime.jsx(
2271
+ "input",
2272
+ {
2273
+ type: "checkbox",
2274
+ name,
2275
+ id: name,
2276
+ checked,
2277
+ defaultChecked,
2278
+ disabled,
2279
+ onChange: handleChange,
2280
+ className: "h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary disabled:cursor-not-allowed disabled:opacity-50"
2281
+ }
2282
+ ),
2283
+ label && /* @__PURE__ */ jsxRuntime.jsx(
2284
+ Label2,
2285
+ {
2286
+ htmlFor: name,
2287
+ value: label,
2288
+ className: cn(
2289
+ "cursor-pointer select-none text-sm font-medium leading-none",
2290
+ disabled && "cursor-not-allowed opacity-50"
2039
2291
  )
2040
- ]
2041
- }
2042
- );
2292
+ }
2293
+ )
2294
+ ] });
2043
2295
  };
2044
2296
  var RadioGroup = ({
2045
2297
  name,
@@ -2156,7 +2408,7 @@ var Button2 = ({
2156
2408
  };
2157
2409
  var Form = ({ children, onSubmitAction, className, style }) => {
2158
2410
  const { sendEvent } = useMelony();
2159
- const [isSubmitted, setIsSubmitted] = React10.useState(false);
2411
+ const [isSubmitted, setIsSubmitted] = React11.useState(false);
2160
2412
  const handleSubmit = (e) => {
2161
2413
  e.preventDefault();
2162
2414
  if (isSubmitted) return;
@@ -2303,7 +2555,7 @@ function MessageBubble({ message }) {
2303
2555
  );
2304
2556
  }
2305
2557
  function LoadingIndicator({ status }) {
2306
- const [isExpanded, setIsExpanded] = React10.useState(false);
2558
+ const [isExpanded, setIsExpanded] = React11.useState(false);
2307
2559
  const message = status?.message || "Processing...";
2308
2560
  const details = status?.details;
2309
2561
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
@@ -2335,7 +2587,7 @@ function MessageList({
2335
2587
  if (messages.length === 0) {
2336
2588
  return null;
2337
2589
  }
2338
- const isTextStreaming = React10.useMemo(() => {
2590
+ const isTextStreaming = React11.useMemo(() => {
2339
2591
  if (messages.length === 0 || !isLoading) return false;
2340
2592
  const lastMessage = messages[messages.length - 1];
2341
2593
  return lastMessage.content.some((event) => event.type === "text-delta");
@@ -2362,28 +2614,31 @@ function Thread({
2362
2614
  });
2363
2615
  const starterPrompts = localStarterPrompts ?? config?.starterPrompts;
2364
2616
  const options = localOptions ?? config?.options;
2365
- const allDefaultSelectedIds = React10.useMemo(() => {
2366
- const defaultSelectedIdsFromOptions = options?.flatMap(
2367
- (group) => group.defaultSelectedIds ?? []
2368
- ) ?? [];
2617
+ const fileAttachments = config?.fileAttachments;
2618
+ const allDefaultSelectedIds = React11.useMemo(() => {
2619
+ const defaultSelectedIdsFromOptions = options?.flatMap((group) => group.defaultSelectedIds ?? []) ?? [];
2369
2620
  return [
2370
- .../* @__PURE__ */ new Set([...defaultSelectedIdsFromOptions, ...defaultSelectedIds ?? []])
2621
+ .../* @__PURE__ */ new Set([
2622
+ ...defaultSelectedIdsFromOptions,
2623
+ ...defaultSelectedIds ?? []
2624
+ ])
2371
2625
  ];
2372
2626
  }, [options, defaultSelectedIds]);
2373
- const [input, setInput] = React10.useState("");
2374
- const messagesEndRef = React10.useRef(null);
2375
- React10.useEffect(() => {
2627
+ const [input, setInput] = React11.useState("");
2628
+ const messagesEndRef = React11.useRef(null);
2629
+ React11.useEffect(() => {
2376
2630
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
2377
2631
  }, [messages]);
2378
2632
  const handleSubmit = async (state, overrideInput) => {
2379
2633
  const text = (overrideInput ?? input).trim();
2380
- if (!text || isLoading) return;
2634
+ const hasFiles = state?.files && Array.isArray(state.files) && state.files.length > 0;
2635
+ if (!text && !hasFiles || isLoading) return;
2381
2636
  if (!overrideInput) setInput("");
2382
2637
  await sendEvent(
2383
2638
  {
2384
2639
  type: "text",
2385
2640
  role: "user",
2386
- data: { content: text }
2641
+ data: { content: text || "" }
2387
2642
  },
2388
2643
  { state: { ...state, threadId: activeThreadId ?? void 0 } }
2389
2644
  );
@@ -2441,7 +2696,8 @@ function Thread({
2441
2696
  isLoading,
2442
2697
  options,
2443
2698
  autoFocus,
2444
- defaultSelectedIds: allDefaultSelectedIds
2699
+ defaultSelectedIds: allDefaultSelectedIds,
2700
+ fileAttachments
2445
2701
  }
2446
2702
  ) }) })
2447
2703
  ]
@@ -2449,20 +2705,36 @@ function Thread({
2449
2705
  );
2450
2706
  }
2451
2707
  function ChatHeader({
2452
- title,
2453
2708
  leftContent,
2454
2709
  rightContent,
2455
2710
  className,
2456
- titleClassName,
2457
2711
  children
2458
2712
  }) {
2459
2713
  if (children) {
2460
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("p-4 border-b border-border h-14 flex items-center shrink-0", className), children });
2714
+ return /* @__PURE__ */ jsxRuntime.jsx(
2715
+ "div",
2716
+ {
2717
+ className: cn(
2718
+ "px-2 border-b border-border h-14 flex items-center shrink-0",
2719
+ className
2720
+ ),
2721
+ children
2722
+ }
2723
+ );
2461
2724
  }
2462
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("p-4 border-b border-border h-14 flex items-center justify-between shrink-0", className), children: [
2463
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: leftContent }),
2464
- rightContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 shrink-0 ml-2", children: rightContent })
2465
- ] });
2725
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2726
+ "div",
2727
+ {
2728
+ className: cn(
2729
+ "px-2 border-b border-border h-14 flex items-center justify-between shrink-0",
2730
+ className
2731
+ ),
2732
+ children: [
2733
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: leftContent }),
2734
+ rightContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 shrink-0 ml-2", children: rightContent })
2735
+ ]
2736
+ }
2737
+ );
2466
2738
  }
2467
2739
  var ThreadList = ({
2468
2740
  className,
@@ -2513,58 +2785,43 @@ var ThreadList = ({
2513
2785
  if (diffDays < 7) return `${diffDays}d ago`;
2514
2786
  return d.toLocaleDateString();
2515
2787
  };
2516
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full", className), children: [
2517
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxRuntime.jsxs(
2518
- Button,
2788
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col h-full", className), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto", children: isLoading && threads.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLoader2, { className: "size-5 animate-spin text-muted-foreground" }) }) : threads.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center text-muted-foreground", children: emptyState || /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
2789
+ /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconMessage, { className: "size-8 mx-auto opacity-50" }),
2790
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: "No threads yet" }),
2791
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", onClick: handleNewThread, children: "Start a conversation" })
2792
+ ] }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2 space-y-1", children: threads.map((thread) => {
2793
+ const isActive = thread.id === activeThreadId;
2794
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2795
+ "div",
2519
2796
  {
2520
- variant: "ghost",
2521
- size: "sm",
2522
- onClick: handleNewThread,
2523
- className: "w-full justify-start",
2797
+ onClick: () => handleThreadClick(thread.id),
2798
+ className: cn(
2799
+ "group relative flex items-center gap-3 px-3 py-1.5 rounded-lg cursor-pointer transition-colors",
2800
+ isActive ? "bg-muted" : "hover:bg-muted"
2801
+ ),
2524
2802
  children: [
2525
- /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconPlus, { className: "mr-2 size-4" }),
2526
- "New Thread"
2803
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
2804
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-sm font-medium truncate"), children: thread.title || `Thread ${thread.id.slice(0, 8)}` }),
2805
+ thread.updatedAt && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-xs shrink-0"), children: formatDate(thread.updatedAt) })
2806
+ ] }) }),
2807
+ /* @__PURE__ */ jsxRuntime.jsx(
2808
+ Button,
2809
+ {
2810
+ variant: "ghost",
2811
+ size: "icon-xs",
2812
+ onClick: (e) => handleDelete(e, thread.id),
2813
+ className: cn(
2814
+ "opacity-0 group-hover:opacity-100 transition-opacity shrink-0",
2815
+ isActive && "hover:bg-primary-foreground/20"
2816
+ ),
2817
+ children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconTrash, { className: "size-3" })
2818
+ }
2819
+ )
2527
2820
  ]
2528
- }
2529
- ) }),
2530
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto", children: isLoading && threads.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLoader2, { className: "size-5 animate-spin text-muted-foreground" }) }) : threads.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center text-muted-foreground", children: emptyState || /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
2531
- /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconMessage, { className: "size-8 mx-auto opacity-50" }),
2532
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: "No threads yet" }),
2533
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", onClick: handleNewThread, children: "Start a conversation" })
2534
- ] }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2 space-y-1", children: threads.map((thread) => {
2535
- const isActive = thread.id === activeThreadId;
2536
- return /* @__PURE__ */ jsxRuntime.jsxs(
2537
- "div",
2538
- {
2539
- onClick: () => handleThreadClick(thread.id),
2540
- className: cn(
2541
- "group relative flex items-center gap-3 px-3 py-1.5 rounded-lg cursor-pointer transition-colors",
2542
- isActive ? "bg-muted" : "hover:bg-muted"
2543
- ),
2544
- children: [
2545
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
2546
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-sm font-medium truncate"), children: thread.title || `Thread ${thread.id.slice(0, 8)}` }),
2547
- thread.updatedAt && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-xs shrink-0"), children: formatDate(thread.updatedAt) })
2548
- ] }) }),
2549
- /* @__PURE__ */ jsxRuntime.jsx(
2550
- Button,
2551
- {
2552
- variant: "ghost",
2553
- size: "icon-xs",
2554
- onClick: (e) => handleDelete(e, thread.id),
2555
- className: cn(
2556
- "opacity-0 group-hover:opacity-100 transition-opacity shrink-0",
2557
- isActive && "hover:bg-primary-foreground/20"
2558
- ),
2559
- children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconTrash, { className: "size-3" })
2560
- }
2561
- )
2562
- ]
2563
- },
2564
- thread.id
2565
- );
2566
- }) }) })
2567
- ] });
2821
+ },
2822
+ thread.id
2823
+ );
2824
+ }) }) }) });
2568
2825
  };
2569
2826
  function ChatPopup({
2570
2827
  title = "Chat",
@@ -2575,8 +2832,8 @@ function ChatPopup({
2575
2832
  headerProps,
2576
2833
  defaultSelectedIds
2577
2834
  }) {
2578
- const [isOpen, setIsOpen] = React10.useState(defaultOpen);
2579
- const [view, setView] = React10.useState("chat");
2835
+ const [isOpen, setIsOpen] = React11.useState(defaultOpen);
2836
+ const [view, setView] = React11.useState("chat");
2580
2837
  const { createThread } = useThreads();
2581
2838
  const handleNewChat = async () => {
2582
2839
  try {
@@ -2693,6 +2950,16 @@ function ChatSidebar({
2693
2950
  ) })
2694
2951
  ] });
2695
2952
  }
2953
+ var ChatSidebarContext = React11.createContext(
2954
+ void 0
2955
+ );
2956
+ function useChatSidebar() {
2957
+ const context = React11.useContext(ChatSidebarContext);
2958
+ if (context === void 0) {
2959
+ throw new Error("useChatSidebar must be used within a ChatSidebarProvider");
2960
+ }
2961
+ return context;
2962
+ }
2696
2963
  function ChatFull({
2697
2964
  title = "Chat",
2698
2965
  placeholder = "Message the AI",
@@ -2704,134 +2971,134 @@ function ChatFull({
2704
2971
  rightSidebar,
2705
2972
  leftSidebarClassName,
2706
2973
  rightSidebarClassName,
2707
- leftSidebarCollapsible = false,
2708
- rightSidebarCollapsible = false,
2709
- defaultLeftSidebarCollapsed = false,
2710
- defaultRightSidebarCollapsed = false,
2711
- leftSidebarCollapsed: controlledLeftCollapsed,
2712
- rightSidebarCollapsed: controlledRightCollapsed,
2713
- onLeftSidebarCollapseChange,
2714
- onRightSidebarCollapseChange,
2715
2974
  autoFocus = false,
2716
2975
  defaultSelectedIds
2717
2976
  }) {
2718
- const [internalLeftCollapsed, setInternalLeftCollapsed] = React10.useState(
2719
- defaultLeftSidebarCollapsed
2720
- );
2721
- const [internalRightCollapsed, setInternalRightCollapsed] = React10.useState(
2722
- defaultRightSidebarCollapsed
2723
- );
2724
- const leftCollapsed = controlledLeftCollapsed !== void 0 ? controlledLeftCollapsed : internalLeftCollapsed;
2725
- const rightCollapsed = controlledRightCollapsed !== void 0 ? controlledRightCollapsed : internalRightCollapsed;
2726
- const handleLeftToggle = () => {
2727
- const newCollapsed = !leftCollapsed;
2728
- if (controlledLeftCollapsed === void 0) {
2729
- setInternalLeftCollapsed(newCollapsed);
2977
+ const { isMobile, isTablet } = useScreenSize();
2978
+ const isSmallScreen = isMobile || isTablet;
2979
+ const [internalLeftCollapsed, setInternalLeftCollapsed] = React11.useState(() => {
2980
+ if (typeof window !== "undefined") {
2981
+ return window.innerWidth < 1024;
2730
2982
  }
2731
- onLeftSidebarCollapseChange?.(newCollapsed);
2732
- };
2733
- const handleRightToggle = () => {
2734
- const newCollapsed = !rightCollapsed;
2735
- if (controlledRightCollapsed === void 0) {
2736
- setInternalRightCollapsed(newCollapsed);
2983
+ return false;
2984
+ });
2985
+ const [internalRightCollapsed, setInternalRightCollapsed] = React11.useState(() => {
2986
+ if (typeof window !== "undefined") {
2987
+ return window.innerWidth < 1024;
2737
2988
  }
2738
- onRightSidebarCollapseChange?.(newCollapsed);
2739
- };
2740
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full w-full bg-background", className), children: [
2741
- title && /* @__PURE__ */ jsxRuntime.jsx(ChatHeader, { title, ...headerProps }),
2742
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-hidden flex relative", children: [
2743
- leftSidebar && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2744
- /* @__PURE__ */ jsxRuntime.jsx(
2745
- "div",
2746
- {
2747
- className: cn(
2748
- "flex-shrink-0 border-r border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
2749
- leftCollapsed && leftSidebarCollapsible ? "w-0 border-r-0 min-w-0" : "",
2750
- !leftCollapsed && leftSidebarClassName
2751
- ),
2752
- children: !leftCollapsed && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2753
- leftSidebarCollapsible && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end p-2 border-b border-border shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
2754
- Button,
2755
- {
2756
- variant: "ghost",
2757
- size: "icon-sm",
2758
- onClick: handleLeftToggle,
2759
- "aria-label": "Collapse left sidebar",
2760
- className: "h-8 w-8",
2761
- children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronLeft, { className: "h-4 w-4" })
2762
- }
2763
- ) }),
2764
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: leftSidebar })
2765
- ] })
2766
- }
2767
- ),
2768
- leftSidebarCollapsible && leftCollapsed && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 border-r border-border bg-background flex items-center justify-center w-10", children: /* @__PURE__ */ jsxRuntime.jsx(
2769
- Button,
2770
- {
2771
- variant: "ghost",
2772
- size: "icon-sm",
2773
- onClick: handleLeftToggle,
2774
- "aria-label": "Expand left sidebar",
2775
- className: "h-8 w-8",
2776
- children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronRight, { className: "h-4 w-4" })
2777
- }
2778
- ) })
2779
- ] }),
2780
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
2781
- Thread,
2782
- {
2783
- placeholder,
2784
- starterPrompts,
2785
- options,
2786
- autoFocus,
2787
- defaultSelectedIds
2788
- }
2789
- ) }),
2790
- rightSidebar && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2791
- 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(
2792
- Button,
2793
- {
2794
- variant: "ghost",
2795
- size: "icon-sm",
2796
- onClick: handleRightToggle,
2797
- "aria-label": "Expand right sidebar",
2798
- className: "h-8 w-8",
2799
- children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronLeft, { className: "h-4 w-4" })
2800
- }
2801
- ) }),
2802
- /* @__PURE__ */ jsxRuntime.jsx(
2803
- "div",
2804
- {
2805
- className: cn(
2806
- "flex-shrink-0 border-l border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
2807
- rightCollapsed && rightSidebarCollapsible ? "w-0 border-l-0 min-w-0" : "",
2808
- !rightCollapsed && rightSidebarClassName
2809
- ),
2810
- children: !rightCollapsed && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2811
- rightSidebarCollapsible && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-start p-2 border-b border-border shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
2812
- Button,
2813
- {
2814
- variant: "ghost",
2815
- size: "icon-sm",
2816
- onClick: handleRightToggle,
2817
- "aria-label": "Collapse right sidebar",
2818
- className: "h-8 w-8",
2819
- children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronRight, { className: "h-4 w-4" })
2820
- }
2821
- ) }),
2822
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: rightSidebar })
2823
- ] })
2824
- }
2825
- )
2826
- ] })
2827
- ] })
2828
- ] });
2989
+ return false;
2990
+ });
2991
+ React11.useEffect(() => {
2992
+ if (isSmallScreen) {
2993
+ setInternalLeftCollapsed(true);
2994
+ setInternalRightCollapsed(true);
2995
+ }
2996
+ }, [isSmallScreen]);
2997
+ const leftCollapsed = internalLeftCollapsed;
2998
+ const rightCollapsed = internalRightCollapsed;
2999
+ const handleLeftToggle = React11.useCallback((collapsed) => {
3000
+ setInternalLeftCollapsed(collapsed);
3001
+ }, []);
3002
+ const handleRightToggle = React11.useCallback((collapsed) => {
3003
+ setInternalRightCollapsed(collapsed);
3004
+ }, []);
3005
+ const contextValue = React11.useMemo(
3006
+ () => ({
3007
+ leftCollapsed,
3008
+ rightCollapsed,
3009
+ setLeftCollapsed: handleLeftToggle,
3010
+ setRightCollapsed: handleRightToggle,
3011
+ leftCollapsible: true,
3012
+ rightCollapsible: true
3013
+ }),
3014
+ [leftCollapsed, rightCollapsed, handleLeftToggle, handleRightToggle]
3015
+ );
3016
+ return /* @__PURE__ */ jsxRuntime.jsx(ChatSidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
3017
+ "div",
3018
+ {
3019
+ className: cn("flex flex-col h-full w-full bg-background", className),
3020
+ children: [
3021
+ title && /* @__PURE__ */ jsxRuntime.jsx(ChatHeader, { title, ...headerProps }),
3022
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-hidden flex relative", children: [
3023
+ leftSidebar && /* @__PURE__ */ jsxRuntime.jsx(
3024
+ "div",
3025
+ {
3026
+ className: cn(
3027
+ "flex-shrink-0 border-r border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
3028
+ leftCollapsed ? "w-0 border-r-0 min-w-0" : "",
3029
+ !leftCollapsed && leftSidebarClassName
3030
+ ),
3031
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: leftSidebar })
3032
+ }
3033
+ ),
3034
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
3035
+ Thread,
3036
+ {
3037
+ placeholder,
3038
+ starterPrompts,
3039
+ options,
3040
+ autoFocus,
3041
+ defaultSelectedIds
3042
+ }
3043
+ ) }),
3044
+ rightSidebar && /* @__PURE__ */ jsxRuntime.jsx(
3045
+ "div",
3046
+ {
3047
+ className: cn(
3048
+ "flex-shrink-0 border-l border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
3049
+ rightCollapsed ? "w-0 border-l-0 min-w-0" : "",
3050
+ !rightCollapsed && rightSidebarClassName
3051
+ ),
3052
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: rightSidebar })
3053
+ }
3054
+ )
3055
+ ] })
3056
+ ]
3057
+ }
3058
+ ) });
3059
+ }
3060
+ function SidebarToggle({ side, className }) {
3061
+ const {
3062
+ leftCollapsed,
3063
+ rightCollapsed,
3064
+ setLeftCollapsed,
3065
+ setRightCollapsed,
3066
+ leftCollapsible,
3067
+ rightCollapsible
3068
+ } = useChatSidebar();
3069
+ if (side === "left") {
3070
+ if (!leftCollapsible) return null;
3071
+ return /* @__PURE__ */ jsxRuntime.jsx(
3072
+ Button,
3073
+ {
3074
+ variant: "ghost",
3075
+ onClick: () => setLeftCollapsed(!leftCollapsed),
3076
+ "aria-label": leftCollapsed ? "Expand left sidebar" : "Collapse left sidebar",
3077
+ className: cn("", className),
3078
+ children: leftCollapsed ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLayoutSidebarLeftExpand, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLayoutSidebarLeftCollapse, { className: "h-4 w-4" })
3079
+ }
3080
+ );
3081
+ }
3082
+ if (side === "right") {
3083
+ if (!rightCollapsible) return null;
3084
+ return /* @__PURE__ */ jsxRuntime.jsx(
3085
+ Button,
3086
+ {
3087
+ variant: "ghost",
3088
+ onClick: () => setRightCollapsed(!rightCollapsed),
3089
+ "aria-label": rightCollapsed ? "Expand right sidebar" : "Collapse right sidebar",
3090
+ className: cn("", className),
3091
+ children: rightCollapsed ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLayoutSidebarRightExpand, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLayoutSidebarRightCollapse, { className: "h-4 w-4" })
3092
+ }
3093
+ );
3094
+ }
3095
+ return null;
2829
3096
  }
2830
- var PopoverContext = React10__namespace.createContext(
3097
+ var PopoverContext = React11__namespace.createContext(
2831
3098
  void 0
2832
3099
  );
2833
3100
  function usePopoverContext() {
2834
- const context = React10__namespace.useContext(PopoverContext);
3101
+ const context = React11__namespace.useContext(PopoverContext);
2835
3102
  if (!context) {
2836
3103
  throw new Error("Popover components must be used within a Popover");
2837
3104
  }
@@ -2843,10 +3110,10 @@ function Popover({
2843
3110
  open: controlledOpen,
2844
3111
  onOpenChange
2845
3112
  }) {
2846
- const [internalOpen, setInternalOpen] = React10__namespace.useState(defaultOpen);
2847
- const triggerRef = React10__namespace.useRef(null);
3113
+ const [internalOpen, setInternalOpen] = React11__namespace.useState(defaultOpen);
3114
+ const triggerRef = React11__namespace.useRef(null);
2848
3115
  const open = controlledOpen ?? internalOpen;
2849
- const setOpen = React10__namespace.useCallback(
3116
+ const setOpen = React11__namespace.useCallback(
2850
3117
  (newOpen) => {
2851
3118
  if (controlledOpen === void 0) {
2852
3119
  setInternalOpen(newOpen);
@@ -2855,7 +3122,7 @@ function Popover({
2855
3122
  },
2856
3123
  [controlledOpen, onOpenChange]
2857
3124
  );
2858
- const value = React10__namespace.useMemo(
3125
+ const value = React11__namespace.useMemo(
2859
3126
  () => ({
2860
3127
  open,
2861
3128
  setOpen,
@@ -2865,15 +3132,15 @@ function Popover({
2865
3132
  );
2866
3133
  return /* @__PURE__ */ jsxRuntime.jsx(PopoverContext.Provider, { value, children });
2867
3134
  }
2868
- var PopoverTrigger = React10__namespace.forwardRef(
3135
+ var PopoverTrigger = React11__namespace.forwardRef(
2869
3136
  ({ asChild, className, children, ...props }, ref) => {
2870
3137
  const { setOpen, triggerRef } = usePopoverContext();
2871
3138
  const handleClick = (e) => {
2872
3139
  setOpen(true);
2873
3140
  props.onClick?.(e);
2874
3141
  };
2875
- if (asChild && React10__namespace.isValidElement(children)) {
2876
- return React10__namespace.cloneElement(children, {
3142
+ if (asChild && React11__namespace.isValidElement(children)) {
3143
+ return React11__namespace.cloneElement(children, {
2877
3144
  ref: (node) => {
2878
3145
  triggerRef.current = node;
2879
3146
  if (typeof children.ref === "function") {
@@ -2905,7 +3172,7 @@ var PopoverTrigger = React10__namespace.forwardRef(
2905
3172
  }
2906
3173
  );
2907
3174
  PopoverTrigger.displayName = "PopoverTrigger";
2908
- var PopoverContent = React10__namespace.forwardRef(
3175
+ var PopoverContent = React11__namespace.forwardRef(
2909
3176
  ({
2910
3177
  className,
2911
3178
  side = "bottom",
@@ -2916,9 +3183,9 @@ var PopoverContent = React10__namespace.forwardRef(
2916
3183
  ...props
2917
3184
  }, ref) => {
2918
3185
  const { open, setOpen, triggerRef } = usePopoverContext();
2919
- const [position, setPosition] = React10__namespace.useState({ top: 0, left: 0 });
2920
- const contentRef = React10__namespace.useRef(null);
2921
- React10__namespace.useEffect(() => {
3186
+ const [position, setPosition] = React11__namespace.useState({ top: 0, left: 0 });
3187
+ const contentRef = React11__namespace.useRef(null);
3188
+ React11__namespace.useEffect(() => {
2922
3189
  if (!open || !triggerRef.current) return;
2923
3190
  const updatePosition = () => {
2924
3191
  if (!triggerRef.current || !contentRef.current) return;
@@ -2979,7 +3246,7 @@ var PopoverContent = React10__namespace.forwardRef(
2979
3246
  window.removeEventListener("scroll", updatePosition, true);
2980
3247
  };
2981
3248
  }, [open, side, align, sideOffset, alignOffset, triggerRef]);
2982
- React10__namespace.useEffect(() => {
3249
+ React11__namespace.useEffect(() => {
2983
3250
  if (!open) return;
2984
3251
  const handleClickOutside = (event) => {
2985
3252
  if (contentRef.current && !contentRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
@@ -3035,7 +3302,7 @@ var ThreadPopover = ({
3035
3302
  emptyState,
3036
3303
  onThreadSelect
3037
3304
  }) => {
3038
- const [isOpen, setIsOpen] = React10__namespace.useState(false);
3305
+ const [isOpen, setIsOpen] = React11__namespace.useState(false);
3039
3306
  reactHotkeysHook.useHotkeys(
3040
3307
  "h",
3041
3308
  (e) => {
@@ -3090,7 +3357,7 @@ var CreateThreadButton = ({
3090
3357
  onThreadCreated
3091
3358
  }) => {
3092
3359
  const { createThread } = useThreads();
3093
- const [isCreating, setIsCreating] = React10__namespace.useState(false);
3360
+ const [isCreating, setIsCreating] = React11__namespace.useState(false);
3094
3361
  const handleCreateThread = async () => {
3095
3362
  if (isCreating) return;
3096
3363
  try {
@@ -3216,10 +3483,10 @@ var AccountDialog = ({
3216
3483
  size
3217
3484
  }) => {
3218
3485
  const { isLoading, isAuthenticated, user, login, logout } = useAuth();
3219
- const [open, setOpen] = React10__namespace.useState(false);
3220
- const [accountInfoOpen, setAccountInfoOpen] = React10__namespace.useState(false);
3221
- const [error, setError] = React10__namespace.useState(null);
3222
- const initials = React10__namespace.useMemo(() => {
3486
+ const [open, setOpen] = React11__namespace.useState(false);
3487
+ const [accountInfoOpen, setAccountInfoOpen] = React11__namespace.useState(false);
3488
+ const [error, setError] = React11__namespace.useState(null);
3489
+ const initials = React11__namespace.useMemo(() => {
3223
3490
  const name = user?.displayName || user?.name;
3224
3491
  if (!name) return "";
3225
3492
  return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
@@ -3395,14 +3662,37 @@ function ThemeToggle() {
3395
3662
  exports.AccountDialog = AccountDialog;
3396
3663
  exports.AuthContext = AuthContext;
3397
3664
  exports.AuthProvider = AuthProvider;
3665
+ exports.Badge = Badge2;
3666
+ exports.Box = Box;
3667
+ exports.Button = Button2;
3668
+ exports.Card = Card2;
3669
+ exports.Chart = Chart;
3398
3670
  exports.ChatFull = ChatFull;
3399
3671
  exports.ChatHeader = ChatHeader;
3400
3672
  exports.ChatPopup = ChatPopup;
3401
3673
  exports.ChatSidebar = ChatSidebar;
3674
+ exports.ChatSidebarContext = ChatSidebarContext;
3675
+ exports.Checkbox = Checkbox;
3676
+ exports.Col = Col;
3402
3677
  exports.Composer = Composer;
3403
3678
  exports.CreateThreadButton = CreateThreadButton;
3679
+ exports.Divider = Divider;
3680
+ exports.Form = Form;
3681
+ exports.Heading = Heading;
3682
+ exports.Image = Image;
3683
+ exports.Input = Input2;
3684
+ exports.Label = Label2;
3685
+ exports.List = List;
3686
+ exports.ListItem = ListItem;
3404
3687
  exports.MelonyClientProvider = MelonyClientProvider;
3405
3688
  exports.MelonyContext = MelonyContext;
3689
+ exports.RadioGroup = RadioGroup;
3690
+ exports.Row = Row;
3691
+ exports.Select = Select2;
3692
+ exports.SidebarToggle = SidebarToggle;
3693
+ exports.Spacer = Spacer;
3694
+ exports.Text = Text;
3695
+ exports.Textarea = Textarea2;
3406
3696
  exports.ThemeProvider = ThemeProvider;
3407
3697
  exports.ThemeToggle = ThemeToggle;
3408
3698
  exports.Thread = Thread;
@@ -3413,7 +3703,9 @@ exports.ThreadProvider = ThreadProvider;
3413
3703
  exports.UIRenderer = UIRenderer;
3414
3704
  exports.groupEventsToMessages = groupEventsToMessages;
3415
3705
  exports.useAuth = useAuth;
3706
+ exports.useChatSidebar = useChatSidebar;
3416
3707
  exports.useMelony = useMelony;
3708
+ exports.useScreenSize = useScreenSize;
3417
3709
  exports.useTheme = useTheme;
3418
3710
  exports.useThreads = useThreads;
3419
3711
  //# sourceMappingURL=index.cjs.map