@melony/react 0.1.24 → 0.1.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs 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
  }
@@ -585,21 +700,17 @@ function Composer({
585
700
  options = [],
586
701
  autoFocus = false,
587
702
  defaultSelectedIds = [],
588
- fileAttachments,
589
- // Legacy props for backward compatibility
590
- accept: legacyAccept,
591
- maxFiles: legacyMaxFiles,
592
- maxFileSize: legacyMaxFileSize
703
+ fileAttachments
593
704
  }) {
594
- const enabled = fileAttachments?.enabled !== false;
595
- const accept = fileAttachments?.accept ?? legacyAccept;
596
- const maxFiles = fileAttachments?.maxFiles ?? legacyMaxFiles ?? 10;
597
- const maxFileSize = fileAttachments?.maxFileSize ?? legacyMaxFileSize ?? 10 * 1024 * 1024;
598
- 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(
599
710
  () => new Set(defaultSelectedIds)
600
711
  );
601
- const [attachedFiles, setAttachedFiles] = React10__namespace.default.useState([]);
602
- const fileInputRef = React10__namespace.default.useRef(null);
712
+ const [attachedFiles, setAttachedFiles] = React11__namespace.default.useState([]);
713
+ const fileInputRef = React11__namespace.default.useRef(null);
603
714
  const toggleOption = (id, groupOptions, type = "multiple") => {
604
715
  const next = new Set(selectedOptions);
605
716
  if (type === "single") {
@@ -623,7 +734,9 @@ function Composer({
623
734
  const files = Array.from(e.target.files || []);
624
735
  const validFiles = files.filter((file) => {
625
736
  if (file.size > maxFileSize) {
626
- console.warn(`File ${file.name} exceeds maximum size of ${maxFileSize} bytes`);
737
+ console.warn(
738
+ `File ${file.name} exceeds maximum size of ${maxFileSize} bytes`
739
+ );
627
740
  return false;
628
741
  }
629
742
  return true;
@@ -631,7 +744,9 @@ function Composer({
631
744
  const remainingSlots = maxFiles - attachedFiles.length;
632
745
  const filesToAdd = validFiles.slice(0, remainingSlots);
633
746
  if (filesToAdd.length < validFiles.length) {
634
- console.warn(`Only ${filesToAdd.length} files can be added (max: ${maxFiles})`);
747
+ console.warn(
748
+ `Only ${filesToAdd.length} files can be added (max: ${maxFiles})`
749
+ );
635
750
  }
636
751
  setAttachedFiles((prev) => [...prev, ...filesToAdd]);
637
752
  if (fileInputRef.current) {
@@ -674,12 +789,11 @@ function Composer({
674
789
  reject(new Error("FileReader returned empty result"));
675
790
  return;
676
791
  }
677
- const base64Data = base64.includes(",") ? base64.split(",")[1] : base64;
678
792
  resolve({
679
793
  name: file.name,
680
794
  type: file.type,
681
795
  size: file.size,
682
- data: base64Data
796
+ data: base64
683
797
  });
684
798
  } catch (error) {
685
799
  reject(error);
@@ -712,129 +826,189 @@ function Composer({
712
826
  handleInternalSubmit().catch(console.error);
713
827
  }
714
828
  };
715
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative flex flex-col w-full", className), children: [
716
- enabled && attachedFiles.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2 flex flex-wrap gap-2", children: attachedFiles.map((file, index) => /* @__PURE__ */ jsxRuntime.jsxs(
717
- "div",
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: [
830
+ /* @__PURE__ */ jsxRuntime.jsx(
831
+ Textarea,
718
832
  {
719
- className: "flex items-center gap-2 px-3 py-1.5 bg-muted rounded-lg text-sm",
720
- children: [
721
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate max-w-[200px]", title: file.name, children: file.name }),
722
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs", children: formatFileSize(file.size) }),
833
+ value,
834
+ onChange: (e) => onChange(e.target.value),
835
+ onKeyDown: handleKeyDown,
836
+ placeholder,
837
+ 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",
838
+ autoFocus
839
+ }
840
+ ),
841
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center px-1", children: [
842
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
843
+ enabled && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
723
844
  /* @__PURE__ */ jsxRuntime.jsx(
724
- "button",
845
+ "input",
846
+ {
847
+ ref: fileInputRef,
848
+ type: "file",
849
+ multiple: true,
850
+ accept,
851
+ onChange: handleFileSelect,
852
+ className: "hidden",
853
+ disabled: isLoading || attachedFiles.length >= maxFiles
854
+ }
855
+ ),
856
+ attachedFiles.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(
857
+ Button,
725
858
  {
726
859
  type: "button",
727
- onClick: () => handleRemoveFile(index),
728
- className: "ml-1 hover:bg-muted-foreground/20 rounded p-0.5 transition-colors",
729
- "aria-label": "Remove file",
730
- children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconX, { className: "h-3.5 w-3.5" })
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" })
731
867
  }
732
- )
733
- ]
734
- },
735
- index
736
- )) }),
737
- /* @__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: [
738
- /* @__PURE__ */ jsxRuntime.jsx(
739
- Textarea,
740
- {
741
- value,
742
- onChange: (e) => onChange(e.target.value),
743
- onKeyDown: handleKeyDown,
744
- placeholder,
745
- 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",
746
- autoFocus
747
- }
748
- ),
749
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center px-1", children: [
750
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
751
- enabled && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
868
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
752
869
  /* @__PURE__ */ jsxRuntime.jsx(
753
- "input",
870
+ DropdownMenuTrigger,
754
871
  {
755
- ref: fileInputRef,
756
- type: "file",
757
- multiple: true,
758
- accept,
759
- onChange: handleFileSelect,
760
- className: "hidden",
761
- disabled: isLoading || attachedFiles.length >= maxFiles
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
+ )
762
886
  }
763
887
  ),
764
- /* @__PURE__ */ jsxRuntime.jsx(
765
- Button,
766
- {
767
- type: "button",
768
- variant: "ghost",
769
- size: "sm",
770
- onClick: () => fileInputRef.current?.click(),
771
- disabled: isLoading || attachedFiles.length >= maxFiles,
772
- className: "text-muted-foreground",
773
- title: attachedFiles.length >= maxFiles ? `Maximum ${maxFiles} files allowed` : "Attach file",
774
- children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconPaperclip, { className: "h-4 w-4" })
775
- }
776
- )
777
- ] }),
778
- options.map((group) => {
779
- const selectedInGroup = group.options.filter(
780
- (o) => selectedOptions.has(o.id)
781
- );
782
- const label = selectedInGroup.length === 0 ? group.label : selectedInGroup.length === 1 ? selectedInGroup[0].label : `${group.label} (${selectedInGroup.length})`;
783
- const isSingle = group.type === "single";
784
- return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
785
- /* @__PURE__ */ jsxRuntime.jsx(
786
- DropdownMenuTrigger,
787
- {
788
- render: /* @__PURE__ */ jsxRuntime.jsxs(
789
- Button,
790
- {
791
- variant: "ghost",
792
- size: "sm",
793
- className: cn(
794
- selectedInGroup.length > 0 ? "text-foreground bg-muted/50" : "text-muted-foreground"
795
- ),
796
- children: [
797
- label,
798
- /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronDown, { className: "h-3 w-3 opacity-50" })
799
- ]
800
- }
801
- )
802
- }
803
- ),
804
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "start", className: "w-56", children: /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuGroup, { children: [
805
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuLabel, { children: group.label }),
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
+ ] }),
806
897
  /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
807
- group.options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
808
- DropdownMenuCheckboxItem,
898
+ attachedFiles.map((file, index) => /* @__PURE__ */ jsxRuntime.jsxs(
899
+ DropdownMenuItem,
809
900
  {
810
- checked: selectedOptions.has(option.id),
811
- onCheckedChange: () => toggleOption(
812
- option.id,
813
- group.options,
814
- isSingle ? "single" : "multiple"
815
- ),
901
+ className: "flex items-center justify-between group",
816
902
  onSelect: (e) => e.preventDefault(),
817
- children: option.label
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
+ ]
818
927
  },
819
- option.id
928
+ index
820
929
  ))
821
- ] }) })
822
- ] }, group.id);
823
- })
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
+ ] })
824
950
  ] }),
825
- /* @__PURE__ */ jsxRuntime.jsx(
826
- Button,
827
- {
828
- type: "submit",
829
- disabled: !value.trim() && attachedFiles.length === 0 && !isLoading || isLoading,
830
- size: "icon-lg",
831
- onClick: () => handleInternalSubmit().catch(console.error),
832
- children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLoader2, { className: "h-5 w-5 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconArrowUp, { className: "h-5 w-5" })
833
- }
834
- )
835
- ] })
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
+ ] }),
1000
+ /* @__PURE__ */ jsxRuntime.jsx(
1001
+ Button,
1002
+ {
1003
+ type: "submit",
1004
+ disabled: !value.trim() && attachedFiles.length === 0 && !isLoading || isLoading,
1005
+ size: "icon-lg",
1006
+ onClick: () => handleInternalSubmit().catch(console.error),
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" })
1008
+ }
1009
+ )
836
1010
  ] })
837
- ] });
1011
+ ] }) });
838
1012
  }
839
1013
  function Card({
840
1014
  className,
@@ -966,8 +1140,6 @@ var Col = ({
966
1140
  gap = "sm",
967
1141
  align = "start",
968
1142
  justify = "start",
969
- wrap = "nowrap",
970
- flex = 1,
971
1143
  width,
972
1144
  height,
973
1145
  padding,
@@ -1017,13 +1189,11 @@ var Col = ({
1017
1189
  gapClasses[gap] || "gap-2",
1018
1190
  alignClasses[align] || "items-start",
1019
1191
  justifyClasses[justify] || "justify-start",
1020
- wrap === "wrap" ? "flex-wrap" : "flex-nowrap",
1021
1192
  overflow && overflowClasses[overflow],
1022
1193
  position && positionClasses[position],
1023
1194
  className
1024
1195
  ),
1025
1196
  style: {
1026
- flex,
1027
1197
  width,
1028
1198
  height,
1029
1199
  padding,
@@ -1331,9 +1501,9 @@ var Image = ({
1331
1501
  className,
1332
1502
  style
1333
1503
  }) => {
1334
- const [hasError, setHasError] = React10.useState(false);
1335
- const [isLoading, setIsLoading] = React10.useState(true);
1336
- 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);
1337
1507
  const sizes = {
1338
1508
  sm: "h-11",
1339
1509
  md: "h-22",
@@ -1457,45 +1627,6 @@ var Icon = ({
1457
1627
  }
1458
1628
  );
1459
1629
  };
1460
- var badgeVariants = classVarianceAuthority.cva(
1461
- "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",
1462
- {
1463
- variants: {
1464
- variant: {
1465
- default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
1466
- secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
1467
- 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",
1468
- outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground bg-input/30",
1469
- ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
1470
- link: "text-primary underline-offset-4 hover:underline"
1471
- }
1472
- },
1473
- defaultVariants: {
1474
- variant: "default"
1475
- }
1476
- }
1477
- );
1478
- function Badge({
1479
- className,
1480
- variant = "default",
1481
- render,
1482
- ...props
1483
- }) {
1484
- return useRender.useRender({
1485
- defaultTagName: "span",
1486
- props: mergeProps.mergeProps(
1487
- {
1488
- className: cn(badgeVariants({ className, variant }))
1489
- },
1490
- props
1491
- ),
1492
- render,
1493
- state: {
1494
- slot: "badge",
1495
- variant
1496
- }
1497
- });
1498
- }
1499
1630
  var Badge2 = ({
1500
1631
  label,
1501
1632
  variant = "primary",
@@ -1531,7 +1662,7 @@ var Chart = ({
1531
1662
  className,
1532
1663
  style
1533
1664
  }) => {
1534
- const [tooltip, setTooltip] = React10.useState(null);
1665
+ const [tooltip, setTooltip] = React11.useState(null);
1535
1666
  if (!Array.isArray(data)) {
1536
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" });
1537
1668
  }
@@ -2084,9 +2215,9 @@ var Select2 = ({
2084
2215
  defaultValue,
2085
2216
  value,
2086
2217
  disabled,
2087
- onValueChange: handleValueChange,
2218
+ onValueChange: (value2) => handleValueChange(value2 || ""),
2088
2219
  children: [
2089
- /* @__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, {}) }),
2090
2221
  /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
2091
2222
  ]
2092
2223
  }
@@ -2116,7 +2247,6 @@ var Label2 = ({
2116
2247
  var Checkbox = ({
2117
2248
  label,
2118
2249
  name,
2119
- value = "on",
2120
2250
  checked,
2121
2251
  defaultChecked,
2122
2252
  disabled,
@@ -2131,46 +2261,37 @@ var Checkbox = ({
2131
2261
  ...onChangeAction,
2132
2262
  data: {
2133
2263
  name: name || "",
2134
- value,
2135
2264
  checked: e.target.checked
2136
2265
  }
2137
2266
  });
2138
2267
  }
2139
2268
  };
2140
- return /* @__PURE__ */ jsxRuntime.jsxs(
2141
- "div",
2142
- {
2143
- className: cn("flex items-center gap-2", className),
2144
- style,
2145
- children: [
2146
- /* @__PURE__ */ jsxRuntime.jsx(
2147
- "input",
2148
- {
2149
- type: "checkbox",
2150
- name,
2151
- id: name,
2152
- value,
2153
- checked,
2154
- defaultChecked,
2155
- disabled,
2156
- onChange: handleChange,
2157
- className: "h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary disabled:cursor-not-allowed disabled:opacity-50"
2158
- }
2159
- ),
2160
- label && /* @__PURE__ */ jsxRuntime.jsx(
2161
- Label2,
2162
- {
2163
- htmlFor: name,
2164
- value: label,
2165
- className: cn(
2166
- "cursor-pointer select-none text-sm font-medium leading-none",
2167
- disabled && "cursor-not-allowed opacity-50"
2168
- )
2169
- }
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"
2170
2291
  )
2171
- ]
2172
- }
2173
- );
2292
+ }
2293
+ )
2294
+ ] });
2174
2295
  };
2175
2296
  var RadioGroup = ({
2176
2297
  name,
@@ -2287,7 +2408,7 @@ var Button2 = ({
2287
2408
  };
2288
2409
  var Form = ({ children, onSubmitAction, className, style }) => {
2289
2410
  const { sendEvent } = useMelony();
2290
- const [isSubmitted, setIsSubmitted] = React10.useState(false);
2411
+ const [isSubmitted, setIsSubmitted] = React11.useState(false);
2291
2412
  const handleSubmit = (e) => {
2292
2413
  e.preventDefault();
2293
2414
  if (isSubmitted) return;
@@ -2434,7 +2555,7 @@ function MessageBubble({ message }) {
2434
2555
  );
2435
2556
  }
2436
2557
  function LoadingIndicator({ status }) {
2437
- const [isExpanded, setIsExpanded] = React10.useState(false);
2558
+ const [isExpanded, setIsExpanded] = React11.useState(false);
2438
2559
  const message = status?.message || "Processing...";
2439
2560
  const details = status?.details;
2440
2561
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
@@ -2466,7 +2587,7 @@ function MessageList({
2466
2587
  if (messages.length === 0) {
2467
2588
  return null;
2468
2589
  }
2469
- const isTextStreaming = React10.useMemo(() => {
2590
+ const isTextStreaming = React11.useMemo(() => {
2470
2591
  if (messages.length === 0 || !isLoading) return false;
2471
2592
  const lastMessage = messages[messages.length - 1];
2472
2593
  return lastMessage.content.some((event) => event.type === "text-delta");
@@ -2493,17 +2614,19 @@ function Thread({
2493
2614
  });
2494
2615
  const starterPrompts = localStarterPrompts ?? config?.starterPrompts;
2495
2616
  const options = localOptions ?? config?.options;
2496
- const allDefaultSelectedIds = React10.useMemo(() => {
2497
- const defaultSelectedIdsFromOptions = options?.flatMap(
2498
- (group) => group.defaultSelectedIds ?? []
2499
- ) ?? [];
2617
+ const fileAttachments = config?.fileAttachments;
2618
+ const allDefaultSelectedIds = React11.useMemo(() => {
2619
+ const defaultSelectedIdsFromOptions = options?.flatMap((group) => group.defaultSelectedIds ?? []) ?? [];
2500
2620
  return [
2501
- .../* @__PURE__ */ new Set([...defaultSelectedIdsFromOptions, ...defaultSelectedIds ?? []])
2621
+ .../* @__PURE__ */ new Set([
2622
+ ...defaultSelectedIdsFromOptions,
2623
+ ...defaultSelectedIds ?? []
2624
+ ])
2502
2625
  ];
2503
2626
  }, [options, defaultSelectedIds]);
2504
- const [input, setInput] = React10.useState("");
2505
- const messagesEndRef = React10.useRef(null);
2506
- React10.useEffect(() => {
2627
+ const [input, setInput] = React11.useState("");
2628
+ const messagesEndRef = React11.useRef(null);
2629
+ React11.useEffect(() => {
2507
2630
  messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
2508
2631
  }, [messages]);
2509
2632
  const handleSubmit = async (state, overrideInput) => {
@@ -2574,7 +2697,7 @@ function Thread({
2574
2697
  options,
2575
2698
  autoFocus,
2576
2699
  defaultSelectedIds: allDefaultSelectedIds,
2577
- fileAttachments: config?.fileAttachments
2700
+ fileAttachments
2578
2701
  }
2579
2702
  ) }) })
2580
2703
  ]
@@ -2582,20 +2705,36 @@ function Thread({
2582
2705
  );
2583
2706
  }
2584
2707
  function ChatHeader({
2585
- title,
2586
2708
  leftContent,
2587
2709
  rightContent,
2588
2710
  className,
2589
- titleClassName,
2590
2711
  children
2591
2712
  }) {
2592
2713
  if (children) {
2593
- 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
+ );
2594
2724
  }
2595
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("p-4 border-b border-border h-14 flex items-center justify-between shrink-0", className), children: [
2596
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: leftContent }),
2597
- rightContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 shrink-0 ml-2", children: rightContent })
2598
- ] });
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
+ );
2599
2738
  }
2600
2739
  var ThreadList = ({
2601
2740
  className,
@@ -2646,58 +2785,43 @@ var ThreadList = ({
2646
2785
  if (diffDays < 7) return `${diffDays}d ago`;
2647
2786
  return d.toLocaleDateString();
2648
2787
  };
2649
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full", className), children: [
2650
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxRuntime.jsxs(
2651
- 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",
2652
2796
  {
2653
- variant: "ghost",
2654
- size: "sm",
2655
- onClick: handleNewThread,
2656
- 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
+ ),
2657
2802
  children: [
2658
- /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconPlus, { className: "mr-2 size-4" }),
2659
- "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
+ )
2660
2820
  ]
2661
- }
2662
- ) }),
2663
- /* @__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: [
2664
- /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconMessage, { className: "size-8 mx-auto opacity-50" }),
2665
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: "No threads yet" }),
2666
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "sm", onClick: handleNewThread, children: "Start a conversation" })
2667
- ] }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2 space-y-1", children: threads.map((thread) => {
2668
- const isActive = thread.id === activeThreadId;
2669
- return /* @__PURE__ */ jsxRuntime.jsxs(
2670
- "div",
2671
- {
2672
- onClick: () => handleThreadClick(thread.id),
2673
- className: cn(
2674
- "group relative flex items-center gap-3 px-3 py-1.5 rounded-lg cursor-pointer transition-colors",
2675
- isActive ? "bg-muted" : "hover:bg-muted"
2676
- ),
2677
- children: [
2678
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
2679
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-sm font-medium truncate"), children: thread.title || `Thread ${thread.id.slice(0, 8)}` }),
2680
- thread.updatedAt && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-xs shrink-0"), children: formatDate(thread.updatedAt) })
2681
- ] }) }),
2682
- /* @__PURE__ */ jsxRuntime.jsx(
2683
- Button,
2684
- {
2685
- variant: "ghost",
2686
- size: "icon-xs",
2687
- onClick: (e) => handleDelete(e, thread.id),
2688
- className: cn(
2689
- "opacity-0 group-hover:opacity-100 transition-opacity shrink-0",
2690
- isActive && "hover:bg-primary-foreground/20"
2691
- ),
2692
- children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconTrash, { className: "size-3" })
2693
- }
2694
- )
2695
- ]
2696
- },
2697
- thread.id
2698
- );
2699
- }) }) })
2700
- ] });
2821
+ },
2822
+ thread.id
2823
+ );
2824
+ }) }) }) });
2701
2825
  };
2702
2826
  function ChatPopup({
2703
2827
  title = "Chat",
@@ -2708,8 +2832,8 @@ function ChatPopup({
2708
2832
  headerProps,
2709
2833
  defaultSelectedIds
2710
2834
  }) {
2711
- const [isOpen, setIsOpen] = React10.useState(defaultOpen);
2712
- const [view, setView] = React10.useState("chat");
2835
+ const [isOpen, setIsOpen] = React11.useState(defaultOpen);
2836
+ const [view, setView] = React11.useState("chat");
2713
2837
  const { createThread } = useThreads();
2714
2838
  const handleNewChat = async () => {
2715
2839
  try {
@@ -2826,6 +2950,16 @@ function ChatSidebar({
2826
2950
  ) })
2827
2951
  ] });
2828
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
+ }
2829
2963
  function ChatFull({
2830
2964
  title = "Chat",
2831
2965
  placeholder = "Message the AI",
@@ -2837,134 +2971,134 @@ function ChatFull({
2837
2971
  rightSidebar,
2838
2972
  leftSidebarClassName,
2839
2973
  rightSidebarClassName,
2840
- leftSidebarCollapsible = false,
2841
- rightSidebarCollapsible = false,
2842
- defaultLeftSidebarCollapsed = false,
2843
- defaultRightSidebarCollapsed = false,
2844
- leftSidebarCollapsed: controlledLeftCollapsed,
2845
- rightSidebarCollapsed: controlledRightCollapsed,
2846
- onLeftSidebarCollapseChange,
2847
- onRightSidebarCollapseChange,
2848
2974
  autoFocus = false,
2849
2975
  defaultSelectedIds
2850
2976
  }) {
2851
- const [internalLeftCollapsed, setInternalLeftCollapsed] = React10.useState(
2852
- defaultLeftSidebarCollapsed
2853
- );
2854
- const [internalRightCollapsed, setInternalRightCollapsed] = React10.useState(
2855
- defaultRightSidebarCollapsed
2856
- );
2857
- const leftCollapsed = controlledLeftCollapsed !== void 0 ? controlledLeftCollapsed : internalLeftCollapsed;
2858
- const rightCollapsed = controlledRightCollapsed !== void 0 ? controlledRightCollapsed : internalRightCollapsed;
2859
- const handleLeftToggle = () => {
2860
- const newCollapsed = !leftCollapsed;
2861
- if (controlledLeftCollapsed === void 0) {
2862
- 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;
2863
2982
  }
2864
- onLeftSidebarCollapseChange?.(newCollapsed);
2865
- };
2866
- const handleRightToggle = () => {
2867
- const newCollapsed = !rightCollapsed;
2868
- if (controlledRightCollapsed === void 0) {
2869
- setInternalRightCollapsed(newCollapsed);
2983
+ return false;
2984
+ });
2985
+ const [internalRightCollapsed, setInternalRightCollapsed] = React11.useState(() => {
2986
+ if (typeof window !== "undefined") {
2987
+ return window.innerWidth < 1024;
2870
2988
  }
2871
- onRightSidebarCollapseChange?.(newCollapsed);
2872
- };
2873
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full w-full bg-background", className), children: [
2874
- title && /* @__PURE__ */ jsxRuntime.jsx(ChatHeader, { title, ...headerProps }),
2875
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-hidden flex relative", children: [
2876
- leftSidebar && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2877
- /* @__PURE__ */ jsxRuntime.jsx(
2878
- "div",
2879
- {
2880
- className: cn(
2881
- "flex-shrink-0 border-r border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
2882
- leftCollapsed && leftSidebarCollapsible ? "w-0 border-r-0 min-w-0" : "",
2883
- !leftCollapsed && leftSidebarClassName
2884
- ),
2885
- children: !leftCollapsed && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2886
- leftSidebarCollapsible && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end p-2 border-b border-border shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
2887
- Button,
2888
- {
2889
- variant: "ghost",
2890
- size: "icon-sm",
2891
- onClick: handleLeftToggle,
2892
- "aria-label": "Collapse left sidebar",
2893
- className: "h-8 w-8",
2894
- children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronLeft, { className: "h-4 w-4" })
2895
- }
2896
- ) }),
2897
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: leftSidebar })
2898
- ] })
2899
- }
2900
- ),
2901
- 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(
2902
- Button,
2903
- {
2904
- variant: "ghost",
2905
- size: "icon-sm",
2906
- onClick: handleLeftToggle,
2907
- "aria-label": "Expand left sidebar",
2908
- className: "h-8 w-8",
2909
- children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronRight, { className: "h-4 w-4" })
2910
- }
2911
- ) })
2912
- ] }),
2913
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
2914
- Thread,
2915
- {
2916
- placeholder,
2917
- starterPrompts,
2918
- options,
2919
- autoFocus,
2920
- defaultSelectedIds
2921
- }
2922
- ) }),
2923
- rightSidebar && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2924
- 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(
2925
- Button,
2926
- {
2927
- variant: "ghost",
2928
- size: "icon-sm",
2929
- onClick: handleRightToggle,
2930
- "aria-label": "Expand right sidebar",
2931
- className: "h-8 w-8",
2932
- children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronLeft, { className: "h-4 w-4" })
2933
- }
2934
- ) }),
2935
- /* @__PURE__ */ jsxRuntime.jsx(
2936
- "div",
2937
- {
2938
- className: cn(
2939
- "flex-shrink-0 border-l border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
2940
- rightCollapsed && rightSidebarCollapsible ? "w-0 border-l-0 min-w-0" : "",
2941
- !rightCollapsed && rightSidebarClassName
2942
- ),
2943
- children: !rightCollapsed && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2944
- rightSidebarCollapsible && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-start p-2 border-b border-border shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
2945
- Button,
2946
- {
2947
- variant: "ghost",
2948
- size: "icon-sm",
2949
- onClick: handleRightToggle,
2950
- "aria-label": "Collapse right sidebar",
2951
- className: "h-8 w-8",
2952
- children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronRight, { className: "h-4 w-4" })
2953
- }
2954
- ) }),
2955
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: rightSidebar })
2956
- ] })
2957
- }
2958
- )
2959
- ] })
2960
- ] })
2961
- ] });
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;
2962
3096
  }
2963
- var PopoverContext = React10__namespace.createContext(
3097
+ var PopoverContext = React11__namespace.createContext(
2964
3098
  void 0
2965
3099
  );
2966
3100
  function usePopoverContext() {
2967
- const context = React10__namespace.useContext(PopoverContext);
3101
+ const context = React11__namespace.useContext(PopoverContext);
2968
3102
  if (!context) {
2969
3103
  throw new Error("Popover components must be used within a Popover");
2970
3104
  }
@@ -2976,10 +3110,10 @@ function Popover({
2976
3110
  open: controlledOpen,
2977
3111
  onOpenChange
2978
3112
  }) {
2979
- const [internalOpen, setInternalOpen] = React10__namespace.useState(defaultOpen);
2980
- const triggerRef = React10__namespace.useRef(null);
3113
+ const [internalOpen, setInternalOpen] = React11__namespace.useState(defaultOpen);
3114
+ const triggerRef = React11__namespace.useRef(null);
2981
3115
  const open = controlledOpen ?? internalOpen;
2982
- const setOpen = React10__namespace.useCallback(
3116
+ const setOpen = React11__namespace.useCallback(
2983
3117
  (newOpen) => {
2984
3118
  if (controlledOpen === void 0) {
2985
3119
  setInternalOpen(newOpen);
@@ -2988,7 +3122,7 @@ function Popover({
2988
3122
  },
2989
3123
  [controlledOpen, onOpenChange]
2990
3124
  );
2991
- const value = React10__namespace.useMemo(
3125
+ const value = React11__namespace.useMemo(
2992
3126
  () => ({
2993
3127
  open,
2994
3128
  setOpen,
@@ -2998,15 +3132,15 @@ function Popover({
2998
3132
  );
2999
3133
  return /* @__PURE__ */ jsxRuntime.jsx(PopoverContext.Provider, { value, children });
3000
3134
  }
3001
- var PopoverTrigger = React10__namespace.forwardRef(
3135
+ var PopoverTrigger = React11__namespace.forwardRef(
3002
3136
  ({ asChild, className, children, ...props }, ref) => {
3003
3137
  const { setOpen, triggerRef } = usePopoverContext();
3004
3138
  const handleClick = (e) => {
3005
3139
  setOpen(true);
3006
3140
  props.onClick?.(e);
3007
3141
  };
3008
- if (asChild && React10__namespace.isValidElement(children)) {
3009
- return React10__namespace.cloneElement(children, {
3142
+ if (asChild && React11__namespace.isValidElement(children)) {
3143
+ return React11__namespace.cloneElement(children, {
3010
3144
  ref: (node) => {
3011
3145
  triggerRef.current = node;
3012
3146
  if (typeof children.ref === "function") {
@@ -3038,7 +3172,7 @@ var PopoverTrigger = React10__namespace.forwardRef(
3038
3172
  }
3039
3173
  );
3040
3174
  PopoverTrigger.displayName = "PopoverTrigger";
3041
- var PopoverContent = React10__namespace.forwardRef(
3175
+ var PopoverContent = React11__namespace.forwardRef(
3042
3176
  ({
3043
3177
  className,
3044
3178
  side = "bottom",
@@ -3049,9 +3183,9 @@ var PopoverContent = React10__namespace.forwardRef(
3049
3183
  ...props
3050
3184
  }, ref) => {
3051
3185
  const { open, setOpen, triggerRef } = usePopoverContext();
3052
- const [position, setPosition] = React10__namespace.useState({ top: 0, left: 0 });
3053
- const contentRef = React10__namespace.useRef(null);
3054
- 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(() => {
3055
3189
  if (!open || !triggerRef.current) return;
3056
3190
  const updatePosition = () => {
3057
3191
  if (!triggerRef.current || !contentRef.current) return;
@@ -3112,7 +3246,7 @@ var PopoverContent = React10__namespace.forwardRef(
3112
3246
  window.removeEventListener("scroll", updatePosition, true);
3113
3247
  };
3114
3248
  }, [open, side, align, sideOffset, alignOffset, triggerRef]);
3115
- React10__namespace.useEffect(() => {
3249
+ React11__namespace.useEffect(() => {
3116
3250
  if (!open) return;
3117
3251
  const handleClickOutside = (event) => {
3118
3252
  if (contentRef.current && !contentRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
@@ -3168,7 +3302,7 @@ var ThreadPopover = ({
3168
3302
  emptyState,
3169
3303
  onThreadSelect
3170
3304
  }) => {
3171
- const [isOpen, setIsOpen] = React10__namespace.useState(false);
3305
+ const [isOpen, setIsOpen] = React11__namespace.useState(false);
3172
3306
  reactHotkeysHook.useHotkeys(
3173
3307
  "h",
3174
3308
  (e) => {
@@ -3223,7 +3357,7 @@ var CreateThreadButton = ({
3223
3357
  onThreadCreated
3224
3358
  }) => {
3225
3359
  const { createThread } = useThreads();
3226
- const [isCreating, setIsCreating] = React10__namespace.useState(false);
3360
+ const [isCreating, setIsCreating] = React11__namespace.useState(false);
3227
3361
  const handleCreateThread = async () => {
3228
3362
  if (isCreating) return;
3229
3363
  try {
@@ -3349,10 +3483,10 @@ var AccountDialog = ({
3349
3483
  size
3350
3484
  }) => {
3351
3485
  const { isLoading, isAuthenticated, user, login, logout } = useAuth();
3352
- const [open, setOpen] = React10__namespace.useState(false);
3353
- const [accountInfoOpen, setAccountInfoOpen] = React10__namespace.useState(false);
3354
- const [error, setError] = React10__namespace.useState(null);
3355
- 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(() => {
3356
3490
  const name = user?.displayName || user?.name;
3357
3491
  if (!name) return "";
3358
3492
  return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
@@ -3528,14 +3662,37 @@ function ThemeToggle() {
3528
3662
  exports.AccountDialog = AccountDialog;
3529
3663
  exports.AuthContext = AuthContext;
3530
3664
  exports.AuthProvider = AuthProvider;
3665
+ exports.Badge = Badge2;
3666
+ exports.Box = Box;
3667
+ exports.Button = Button2;
3668
+ exports.Card = Card2;
3669
+ exports.Chart = Chart;
3531
3670
  exports.ChatFull = ChatFull;
3532
3671
  exports.ChatHeader = ChatHeader;
3533
3672
  exports.ChatPopup = ChatPopup;
3534
3673
  exports.ChatSidebar = ChatSidebar;
3674
+ exports.ChatSidebarContext = ChatSidebarContext;
3675
+ exports.Checkbox = Checkbox;
3676
+ exports.Col = Col;
3535
3677
  exports.Composer = Composer;
3536
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;
3537
3687
  exports.MelonyClientProvider = MelonyClientProvider;
3538
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;
3539
3696
  exports.ThemeProvider = ThemeProvider;
3540
3697
  exports.ThemeToggle = ThemeToggle;
3541
3698
  exports.Thread = Thread;
@@ -3546,7 +3703,9 @@ exports.ThreadProvider = ThreadProvider;
3546
3703
  exports.UIRenderer = UIRenderer;
3547
3704
  exports.groupEventsToMessages = groupEventsToMessages;
3548
3705
  exports.useAuth = useAuth;
3706
+ exports.useChatSidebar = useChatSidebar;
3549
3707
  exports.useMelony = useMelony;
3708
+ exports.useScreenSize = useScreenSize;
3550
3709
  exports.useTheme = useTheme;
3551
3710
  exports.useThreads = useThreads;
3552
3711
  //# sourceMappingURL=index.cjs.map