@melony/react 0.1.25 → 0.1.27

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.js CHANGED
@@ -1,18 +1,18 @@
1
1
  import * as React11 from 'react';
2
- import React11__default, { createContext, useState, useCallback, useEffect, useMemo, useContext, useRef } from 'react';
2
+ import React11__default, { createContext, useState, useContext, useCallback, useMemo, useEffect, useRef } from 'react';
3
3
  import { NuqsAdapter } from 'nuqs/adapters/react';
4
4
  import { QueryClient, QueryClientProvider, useQueryClient, useQuery, useMutation } from '@tanstack/react-query';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
- import { generateId } from 'melony/client';
7
- import { useQueryState, parseAsString } from 'nuqs';
8
- import { clsx } from 'clsx';
9
- import { twMerge } from 'tailwind-merge';
10
6
  import { Button as Button$1 } from '@base-ui/react/button';
11
7
  import { cva } from 'class-variance-authority';
8
+ import { clsx } from 'clsx';
9
+ import { twMerge } from 'tailwind-merge';
10
+ import * as ICONS from '@tabler/icons-react';
11
+ import { IconBrandGoogle, IconFileText, IconFile, IconX, IconPaperclip, IconChevronDown, IconLoader2, IconArrowUp, IconMessage, IconDotsVertical, IconTrash, IconHistory, IconPlus, IconArrowLeft, IconLayoutSidebarLeftExpand, IconLayoutSidebarLeftCollapse, IconLayoutSidebarRightExpand, IconLayoutSidebarRightCollapse, IconUser, IconLogout, IconDeviceDesktop, IconMoon, IconSun, IconCheck, IconSelector, IconChevronUp } from '@tabler/icons-react';
12
+ import { generateId } from 'melony/client';
13
+ import { useQueryState, parseAsString } from 'nuqs';
12
14
  import { mergeProps } from '@base-ui/react/merge-props';
13
15
  import { useRender } from '@base-ui/react/use-render';
14
- import * as ICONS from '@tabler/icons-react';
15
- import { IconPaperclip, IconX, IconPlus, IconChevronDown, IconLoader2, IconArrowUp, IconMessage, IconTrash, IconHistory, IconArrowLeft, IconLayoutSidebarLeftExpand, IconLayoutSidebarLeftCollapse, IconLayoutSidebarRightExpand, IconLayoutSidebarRightCollapse, IconUser, IconLogout, IconBrandGoogle, IconDeviceDesktop, IconMoon, IconSun, IconCheck, IconSelector, IconChevronUp } from '@tabler/icons-react';
16
16
  import { Menu } from '@base-ui/react/menu';
17
17
  import { Separator as Separator$1 } from '@base-ui/react/separator';
18
18
  import { Dialog as Dialog$1 } from '@base-ui/react/dialog';
@@ -167,49 +167,215 @@ var MelonyClientProvider = ({
167
167
  }
168
168
  ) }) });
169
169
  };
170
+ function cn(...inputs) {
171
+ return twMerge(clsx(inputs));
172
+ }
173
+ var buttonVariants = cva(
174
+ "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-4xl border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-[3px] aria-invalid:ring-[3px] [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none",
175
+ {
176
+ variants: {
177
+ variant: {
178
+ default: "bg-primary text-primary-foreground hover:bg-primary/80",
179
+ outline: "border-border bg-input/30 hover:bg-input/50 hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground",
180
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
181
+ ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
182
+ destructive: "bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30",
183
+ link: "text-primary underline-offset-4 hover:underline"
184
+ },
185
+ size: {
186
+ default: "h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5",
187
+ xs: "h-6 gap-1 px-2.5 text-xs has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 [&_svg:not([class*='size-'])]:size-3",
188
+ sm: "h-8 gap-1 px-3 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
189
+ lg: "h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
190
+ icon: "size-9",
191
+ "icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
192
+ "icon-sm": "size-8",
193
+ "icon-lg": "size-10"
194
+ }
195
+ },
196
+ defaultVariants: {
197
+ variant: "default",
198
+ size: "default"
199
+ }
200
+ }
201
+ );
202
+ function Button({
203
+ className,
204
+ variant = "default",
205
+ size = "default",
206
+ ...props
207
+ }) {
208
+ return /* @__PURE__ */ jsx(
209
+ Button$1,
210
+ {
211
+ "data-slot": "button",
212
+ className: cn(buttonVariants({ variant, size, className })),
213
+ ...props
214
+ }
215
+ );
216
+ }
217
+ var useAuth = () => {
218
+ const context = useContext(AuthContext);
219
+ if (context === void 0) {
220
+ throw new Error("useAuth must be used within an AuthProvider");
221
+ }
222
+ return context;
223
+ };
224
+ function WelcomeScreen({
225
+ title = "Welcome to Melony",
226
+ description = "The most powerful AI agent framework for building modern applications. Connect your tools, build your brain, and ship faster.",
227
+ features = [
228
+ {
229
+ title: "Context Aware",
230
+ description: "Built-in state management for complex LLM flows."
231
+ },
232
+ {
233
+ title: "Extensible",
234
+ description: "Plugin architecture for easy integrations."
235
+ },
236
+ {
237
+ title: "Real-time",
238
+ description: "Streaming responses and live state updates."
239
+ },
240
+ {
241
+ title: "Tool-ready",
242
+ description: "Ready-to-use actions for common tasks."
243
+ }
244
+ ],
245
+ className,
246
+ onLoginClick,
247
+ termsUrl = "#",
248
+ privacyUrl = "#",
249
+ imageUrl,
250
+ imageAlt = "Product screenshot"
251
+ }) {
252
+ const { login, isLoading } = useAuth();
253
+ const handleLogin = () => {
254
+ if (onLoginClick) {
255
+ onLoginClick();
256
+ } else {
257
+ login();
258
+ }
259
+ };
260
+ return /* @__PURE__ */ jsxs(
261
+ "div",
262
+ {
263
+ className: cn(
264
+ "flex min-h-[600px] h-full w-full flex-col md:flex-row bg-background overflow-hidden",
265
+ className
266
+ ),
267
+ children: [
268
+ /* @__PURE__ */ jsxs("div", { className: "flex w-8/12 flex-col bg-sidebar text-foreground relative overflow-hidden", children: [
269
+ /* @__PURE__ */ jsx("div", { className: "absolute -top-24 -left-24 size-96 bg-primary/5 rounded-full blur-3xl" }),
270
+ /* @__PURE__ */ jsx("div", { className: "absolute -bottom-24 -right-24 size-96 bg-primary/5 rounded-full blur-3xl" }),
271
+ /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto overflow-x-hidden relative z-10 flex flex-col p-8 md:p-12 lg:p-20", children: /* @__PURE__ */ jsxs("div", { className: "max-w-xl mx-auto w-full my-auto", children: [
272
+ /* @__PURE__ */ jsx("h1", { className: "mb-6 text-4xl font-bold tracking-tight md:text-5xl lg:text-6xl text-foreground", children: title }),
273
+ /* @__PURE__ */ jsx("p", { className: "mb-12 text-lg text-muted-foreground md:text-xl leading-relaxed", children: description }),
274
+ imageUrl && /* @__PURE__ */ jsxs("div", { className: "mb-12 relative group", children: [
275
+ /* @__PURE__ */ jsx("div", { className: "absolute -inset-1 bg-gradient-to-r from-primary/20 to-primary/10 rounded-xl blur opacity-25 group-hover:opacity-50 transition duration-1000 group-hover:duration-200" }),
276
+ /* @__PURE__ */ jsx(
277
+ "img",
278
+ {
279
+ src: imageUrl,
280
+ alt: imageAlt,
281
+ className: "relative rounded-xl border border-border/50 shadow-2xl transition-transform duration-500 hover:scale-[1.02] w-full"
282
+ }
283
+ )
284
+ ] }),
285
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-x-8 gap-y-10 sm:grid-cols-2", children: features.map((feature, i) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
286
+ /* @__PURE__ */ jsx("h3", { className: "font-bold text-lg text-foreground", children: feature.title }),
287
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground leading-relaxed", children: feature.description })
288
+ ] }, i)) })
289
+ ] }) })
290
+ ] }),
291
+ /* @__PURE__ */ jsx("div", { className: "flex w-4/12 flex-col overflow-y-auto p-8 md:p-12 lg:p-20 bg-background transition-colors duration-300", children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-sm space-y-8 my-auto mx-auto", children: [
292
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3 text-center md:text-left", children: [
293
+ /* @__PURE__ */ jsx("h2", { className: "text-3xl font-bold tracking-tight text-foreground", children: "Get Started" }),
294
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-lg", children: "Sign in to your account to continue" })
295
+ ] }),
296
+ /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
297
+ /* @__PURE__ */ jsxs(
298
+ Button,
299
+ {
300
+ size: "lg",
301
+ variant: "outline",
302
+ className: "w-full h-16 text-lg shadow-sm hover:shadow-md transition-all flex items-center justify-center gap-3 border-2 font-medium bg-background text-foreground hover:bg-accent",
303
+ onClick: handleLogin,
304
+ disabled: isLoading,
305
+ children: [
306
+ /* @__PURE__ */ jsx(IconBrandGoogle, { className: "size-6" }),
307
+ isLoading ? "Signing in..." : "Continue with Google"
308
+ ]
309
+ }
310
+ ),
311
+ /* @__PURE__ */ jsxs("div", { className: "relative py-4", children: [
312
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ jsx("span", { className: "w-full border-t border-border" }) }),
313
+ /* @__PURE__ */ jsx("div", { className: "relative flex justify-center text-xs uppercase", children: /* @__PURE__ */ jsx("span", { className: "bg-background px-3 text-muted-foreground tracking-widest font-medium", children: "Secure access" }) })
314
+ ] })
315
+ ] }),
316
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground leading-relaxed text-center md:text-left", children: [
317
+ "By continuing, you agree to our ",
318
+ /* @__PURE__ */ jsx("br", { className: "hidden md:block" }),
319
+ /* @__PURE__ */ jsx(
320
+ "a",
321
+ {
322
+ href: termsUrl,
323
+ target: "_blank",
324
+ rel: "noopener noreferrer",
325
+ className: "underline underline-offset-4 hover:text-primary transition-colors font-medium",
326
+ children: "Terms of Service"
327
+ }
328
+ ),
329
+ " ",
330
+ "and",
331
+ " ",
332
+ /* @__PURE__ */ jsx(
333
+ "a",
334
+ {
335
+ href: privacyUrl,
336
+ target: "_blank",
337
+ rel: "noopener noreferrer",
338
+ className: "underline underline-offset-4 hover:text-primary transition-colors font-medium",
339
+ children: "Privacy Policy"
340
+ }
341
+ ),
342
+ "."
343
+ ] })
344
+ ] }) })
345
+ ]
346
+ }
347
+ );
348
+ }
170
349
  var AuthContext = createContext(
171
350
  void 0
172
351
  );
173
352
  var AuthProvider = ({
174
353
  children,
175
- service
354
+ service,
355
+ welcomeScreenProps
176
356
  }) => {
177
- const [user, setUser] = useState(null);
178
- const [isLoading, setIsLoading] = useState(true);
179
- const fetchMe = useCallback(async () => {
180
- setIsLoading(true);
181
- try {
182
- const userData = await service.getMe();
183
- setUser(userData);
184
- } catch (error) {
185
- console.error("Failed to fetch user:", error);
186
- setUser(null);
187
- } finally {
188
- setIsLoading(false);
357
+ const queryClient = useQueryClient();
358
+ const { data: user, isLoading } = useQuery({
359
+ queryKey: ["auth-user", service],
360
+ queryFn: () => service.getMe(),
361
+ retry: false
362
+ });
363
+ const logoutMutation = useMutation({
364
+ mutationFn: () => service.logout(),
365
+ onSuccess: () => {
366
+ queryClient.setQueryData(["auth-user", service], null);
189
367
  }
190
- }, [service]);
191
- useEffect(() => {
192
- fetchMe();
193
- }, [fetchMe]);
368
+ });
194
369
  const login = useCallback(() => {
195
370
  service.login();
196
371
  }, [service]);
197
372
  const logout = useCallback(async () => {
198
373
  try {
199
- await service.logout();
200
- setUser(null);
374
+ await logoutMutation.mutateAsync();
201
375
  } catch (error) {
202
376
  console.error("Failed to logout:", error);
203
377
  }
204
- }, [service]);
205
- const value = {
206
- user,
207
- isAuthenticated: !!user,
208
- isLoading,
209
- login,
210
- logout,
211
- getToken: service.getToken
212
- };
378
+ }, [logoutMutation]);
213
379
  if (isLoading) {
214
380
  return /* @__PURE__ */ jsx(
215
381
  "div",
@@ -228,7 +394,15 @@ var AuthProvider = ({
228
394
  }
229
395
  );
230
396
  }
231
- return /* @__PURE__ */ jsx(AuthContext.Provider, { value, children });
397
+ const value = {
398
+ user: user || null,
399
+ isAuthenticated: !!user,
400
+ isLoading,
401
+ login,
402
+ logout,
403
+ getToken: service.getToken
404
+ };
405
+ return /* @__PURE__ */ jsx(AuthContext.Provider, { value, children: !value.isAuthenticated && welcomeScreenProps ? /* @__PURE__ */ jsx(WelcomeScreen, { ...welcomeScreenProps }) : children });
232
406
  };
233
407
  var ThreadContext = createContext(
234
408
  void 0
@@ -325,6 +499,103 @@ var ThreadProvider = ({
325
499
  );
326
500
  return /* @__PURE__ */ jsx(ThreadContext.Provider, { value, children });
327
501
  };
502
+ function useScreenSize(mobileBreakpoint = 768, tabletBreakpoint = 1024) {
503
+ const [screenSize, setScreenSize] = useState(() => {
504
+ if (typeof window === "undefined") {
505
+ return {
506
+ width: 1024,
507
+ height: 768,
508
+ isMobile: false,
509
+ isTablet: false,
510
+ isDesktop: true
511
+ };
512
+ }
513
+ const width = window.innerWidth;
514
+ return {
515
+ width,
516
+ height: window.innerHeight,
517
+ isMobile: width < mobileBreakpoint,
518
+ isTablet: width >= mobileBreakpoint && width < tabletBreakpoint,
519
+ isDesktop: width >= tabletBreakpoint
520
+ };
521
+ });
522
+ useEffect(() => {
523
+ if (typeof window === "undefined") return;
524
+ const updateScreenSize = () => {
525
+ const width = window.innerWidth;
526
+ const height = window.innerHeight;
527
+ setScreenSize({
528
+ width,
529
+ height,
530
+ isMobile: width < mobileBreakpoint,
531
+ isTablet: width >= mobileBreakpoint && width < tabletBreakpoint,
532
+ isDesktop: width >= tabletBreakpoint
533
+ });
534
+ };
535
+ updateScreenSize();
536
+ window.addEventListener("resize", updateScreenSize);
537
+ return () => {
538
+ window.removeEventListener("resize", updateScreenSize);
539
+ };
540
+ }, [mobileBreakpoint, tabletBreakpoint]);
541
+ return screenSize;
542
+ }
543
+ var SidebarContext = createContext(
544
+ void 0
545
+ );
546
+ function useSidebar() {
547
+ const context = useContext(SidebarContext);
548
+ if (context === void 0) {
549
+ throw new Error("useSidebar must be used within a SidebarProvider");
550
+ }
551
+ return context;
552
+ }
553
+ function SidebarProvider({
554
+ children,
555
+ defaultLeftCollapsed,
556
+ defaultRightCollapsed
557
+ }) {
558
+ const { isMobile, isTablet } = useScreenSize();
559
+ const isSmallScreen = isMobile || isTablet;
560
+ const [leftCollapsed, setLeftCollapsed] = useState(() => {
561
+ if (defaultLeftCollapsed !== void 0) return defaultLeftCollapsed;
562
+ if (typeof window !== "undefined") {
563
+ return window.innerWidth < 1024;
564
+ }
565
+ return false;
566
+ });
567
+ const [rightCollapsed, setRightCollapsed] = useState(() => {
568
+ if (defaultRightCollapsed !== void 0) return defaultRightCollapsed;
569
+ if (typeof window !== "undefined") {
570
+ return window.innerWidth < 1024;
571
+ }
572
+ return false;
573
+ });
574
+ useEffect(() => {
575
+ if (isSmallScreen) {
576
+ setLeftCollapsed(true);
577
+ setRightCollapsed(true);
578
+ }
579
+ }, [isSmallScreen]);
580
+ const handleLeftToggle = useCallback((collapsed) => {
581
+ setLeftCollapsed(collapsed);
582
+ }, []);
583
+ const handleRightToggle = useCallback((collapsed) => {
584
+ setRightCollapsed(collapsed);
585
+ }, []);
586
+ const contextValue = useMemo(
587
+ () => ({
588
+ leftCollapsed,
589
+ rightCollapsed,
590
+ setLeftCollapsed: handleLeftToggle,
591
+ setRightCollapsed: handleRightToggle,
592
+ leftCollapsible: true,
593
+ rightCollapsible: true
594
+ }),
595
+ [leftCollapsed, rightCollapsed, handleLeftToggle, handleRightToggle]
596
+ );
597
+ return /* @__PURE__ */ jsx(SidebarContext.Provider, { value: contextValue, children });
598
+ }
328
599
  var ThemeContext = createContext(void 0);
329
600
  function ThemeProvider({ children }) {
330
601
  const [theme, setThemeState] = useState("system");
@@ -398,13 +669,6 @@ var useMelony = (options) => {
398
669
  }, [client, initialEvents, reset]);
399
670
  return context;
400
671
  };
401
- var useAuth = () => {
402
- const context = useContext(AuthContext);
403
- if (context === void 0) {
404
- throw new Error("useAuth must be used within an AuthProvider");
405
- }
406
- return context;
407
- };
408
672
  var useThreads = () => {
409
673
  const context = useContext(ThreadContext);
410
674
  if (context === void 0) {
@@ -412,94 +676,6 @@ var useThreads = () => {
412
676
  }
413
677
  return context;
414
678
  };
415
- function useScreenSize(mobileBreakpoint = 768, tabletBreakpoint = 1024) {
416
- const [screenSize, setScreenSize] = useState(() => {
417
- if (typeof window === "undefined") {
418
- return {
419
- width: 1024,
420
- height: 768,
421
- isMobile: false,
422
- isTablet: false,
423
- isDesktop: true
424
- };
425
- }
426
- const width = window.innerWidth;
427
- return {
428
- width,
429
- height: window.innerHeight,
430
- isMobile: width < mobileBreakpoint,
431
- isTablet: width >= mobileBreakpoint && width < tabletBreakpoint,
432
- isDesktop: width >= tabletBreakpoint
433
- };
434
- });
435
- useEffect(() => {
436
- if (typeof window === "undefined") return;
437
- const updateScreenSize = () => {
438
- const width = window.innerWidth;
439
- const height = window.innerHeight;
440
- setScreenSize({
441
- width,
442
- height,
443
- isMobile: width < mobileBreakpoint,
444
- isTablet: width >= mobileBreakpoint && width < tabletBreakpoint,
445
- isDesktop: width >= tabletBreakpoint
446
- });
447
- };
448
- updateScreenSize();
449
- window.addEventListener("resize", updateScreenSize);
450
- return () => {
451
- window.removeEventListener("resize", updateScreenSize);
452
- };
453
- }, [mobileBreakpoint, tabletBreakpoint]);
454
- return screenSize;
455
- }
456
- function cn(...inputs) {
457
- return twMerge(clsx(inputs));
458
- }
459
- var buttonVariants = cva(
460
- "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-4xl border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-[3px] aria-invalid:ring-[3px] [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none",
461
- {
462
- variants: {
463
- variant: {
464
- default: "bg-primary text-primary-foreground hover:bg-primary/80",
465
- outline: "border-border bg-input/30 hover:bg-input/50 hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground",
466
- secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
467
- ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
468
- destructive: "bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30",
469
- link: "text-primary underline-offset-4 hover:underline"
470
- },
471
- size: {
472
- default: "h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5",
473
- xs: "h-6 gap-1 px-2.5 text-xs has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 [&_svg:not([class*='size-'])]:size-3",
474
- sm: "h-8 gap-1 px-3 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
475
- lg: "h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
476
- icon: "size-9",
477
- "icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
478
- "icon-sm": "size-8",
479
- "icon-lg": "size-10"
480
- }
481
- },
482
- defaultVariants: {
483
- variant: "default",
484
- size: "default"
485
- }
486
- }
487
- );
488
- function Button({
489
- className,
490
- variant = "default",
491
- size = "default",
492
- ...props
493
- }) {
494
- return /* @__PURE__ */ jsx(
495
- Button$1,
496
- {
497
- "data-slot": "button",
498
- className: cn(buttonVariants({ variant, size, className })),
499
- ...props
500
- }
501
- );
502
- }
503
679
  function Textarea({ className, ...props }) {
504
680
  return /* @__PURE__ */ jsx(
505
681
  "textarea",
@@ -689,7 +865,22 @@ function Composer({
689
865
  () => new Set(defaultSelectedIds)
690
866
  );
691
867
  const [attachedFiles, setAttachedFiles] = React11__default.useState([]);
868
+ const [previews, setPreviews] = React11__default.useState([]);
692
869
  const fileInputRef = React11__default.useRef(null);
870
+ React11__default.useEffect(() => {
871
+ const newPreviews = attachedFiles.map((file) => ({
872
+ name: file.name,
873
+ type: file.type,
874
+ size: file.size,
875
+ url: file.type.startsWith("image/") ? URL.createObjectURL(file) : ""
876
+ }));
877
+ setPreviews(newPreviews);
878
+ return () => {
879
+ newPreviews.forEach((p) => {
880
+ if (p.url) URL.revokeObjectURL(p.url);
881
+ });
882
+ };
883
+ }, [attachedFiles]);
693
884
  const toggleOption = (id, groupOptions, type = "multiple") => {
694
885
  const next = new Set(selectedOptions);
695
886
  if (type === "single") {
@@ -735,11 +926,6 @@ function Composer({
735
926
  const handleRemoveFile = (index) => {
736
927
  setAttachedFiles((prev) => prev.filter((_, i) => i !== index));
737
928
  };
738
- const formatFileSize = (bytes) => {
739
- if (bytes < 1024) return bytes + " B";
740
- if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + " KB";
741
- return (bytes / (1024 * 1024)).toFixed(1) + " MB";
742
- };
743
929
  const handleInternalSubmit = async () => {
744
930
  const state = {};
745
931
  options.forEach((group) => {
@@ -805,13 +991,56 @@ function Composer({
805
991
  handleInternalSubmit().catch(console.error);
806
992
  }
807
993
  };
994
+ const handlePaste = (e) => {
995
+ if (!enabled) return;
996
+ const items = Array.from(e.clipboardData.items);
997
+ const files = items.map((item) => item.getAsFile()).filter((file) => file !== null);
998
+ if (files.length > 0) {
999
+ const remainingSlots = maxFiles - attachedFiles.length;
1000
+ const validFiles = files.filter((f) => f.size <= maxFileSize);
1001
+ const filesToAdd = validFiles.slice(0, remainingSlots);
1002
+ if (filesToAdd.length > 0) {
1003
+ setAttachedFiles((prev) => [...prev, ...filesToAdd]);
1004
+ }
1005
+ }
1006
+ };
808
1007
  return /* @__PURE__ */ jsx("div", { className: cn("relative flex flex-col w-full", className), children: /* @__PURE__ */ 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: [
1008
+ previews.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-3 p-2 px-3 pb-3", children: previews.map((preview, index) => /* @__PURE__ */ jsxs(
1009
+ "div",
1010
+ {
1011
+ className: "group relative flex flex-col items-center justify-center w-20 h-20 rounded-xl border bg-muted/30 overflow-hidden shadow-sm",
1012
+ children: [
1013
+ preview.type.startsWith("image/") ? /* @__PURE__ */ jsx(
1014
+ "img",
1015
+ {
1016
+ src: preview.url,
1017
+ alt: preview.name,
1018
+ className: "w-full h-full object-cover"
1019
+ }
1020
+ ) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center p-2 text-center", children: [
1021
+ preview.type.includes("text") || preview.type.includes("pdf") ? /* @__PURE__ */ jsx(IconFileText, { className: "h-8 w-8 text-muted-foreground" }) : /* @__PURE__ */ jsx(IconFile, { className: "h-8 w-8 text-muted-foreground" }),
1022
+ /* @__PURE__ */ jsx("span", { className: "text-[9px] truncate w-full px-1 mt-1 text-muted-foreground", children: preview.name })
1023
+ ] }),
1024
+ /* @__PURE__ */ jsx(
1025
+ "button",
1026
+ {
1027
+ type: "button",
1028
+ onClick: () => handleRemoveFile(index),
1029
+ className: "absolute top-1 right-1 p-1 rounded-full bg-foreground/10 hover:bg-foreground/20 backdrop-blur-md opacity-0 group-hover:opacity-100 transition-opacity",
1030
+ children: /* @__PURE__ */ jsx(IconX, { className: "h-3 w-3" })
1031
+ }
1032
+ )
1033
+ ]
1034
+ },
1035
+ index
1036
+ )) }),
809
1037
  /* @__PURE__ */ jsx(
810
1038
  Textarea,
811
1039
  {
812
1040
  value,
813
1041
  onChange: (e) => onChange(e.target.value),
814
1042
  onKeyDown: handleKeyDown,
1043
+ onPaste: handlePaste,
815
1044
  placeholder,
816
1045
  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",
817
1046
  autoFocus
@@ -832,100 +1061,22 @@ function Composer({
832
1061
  disabled: isLoading || attachedFiles.length >= maxFiles
833
1062
  }
834
1063
  ),
835
- attachedFiles.length === 0 ? /* @__PURE__ */ jsx(
1064
+ /* @__PURE__ */ jsxs(
836
1065
  Button,
837
1066
  {
838
1067
  type: "button",
839
1068
  variant: "ghost",
840
1069
  size: "sm",
841
1070
  onClick: () => fileInputRef.current?.click(),
842
- disabled: isLoading,
1071
+ disabled: isLoading || attachedFiles.length >= maxFiles,
843
1072
  className: "text-muted-foreground",
844
1073
  title: "Attach file",
845
- children: /* @__PURE__ */ jsx(IconPaperclip, { className: "h-4 w-4" })
1074
+ children: [
1075
+ /* @__PURE__ */ jsx(IconPaperclip, { className: "h-4 w-4" }),
1076
+ attachedFiles.length > 0 && /* @__PURE__ */ jsx(Badge, { className: "ml-1 h-[18px] min-w-[18px] px-1.5 text-[10px]", children: attachedFiles.length })
1077
+ ]
846
1078
  }
847
- ) : /* @__PURE__ */ jsxs(DropdownMenu, { children: [
848
- /* @__PURE__ */ jsx(
849
- DropdownMenuTrigger,
850
- {
851
- render: /* @__PURE__ */ jsxs(
852
- Button,
853
- {
854
- type: "button",
855
- variant: "ghost",
856
- size: "sm",
857
- className: "text-muted-foreground gap-2",
858
- title: `${attachedFiles.length} files attached`,
859
- children: [
860
- /* @__PURE__ */ jsx(IconPaperclip, { className: "h-4 w-4" }),
861
- /* @__PURE__ */ jsx(Badge, { className: "h-[18px] min-w-[18px] px-1.5 text-[10px]", children: attachedFiles.length })
862
- ]
863
- }
864
- )
865
- }
866
- ),
867
- /* @__PURE__ */ jsxs(DropdownMenuContent, { align: "start", className: "w-64", children: [
868
- /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
869
- /* @__PURE__ */ jsxs(DropdownMenuLabel, { children: [
870
- "Attached Files (",
871
- attachedFiles.length,
872
- "/",
873
- maxFiles,
874
- ")"
875
- ] }),
876
- /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
877
- attachedFiles.map((file, index) => /* @__PURE__ */ jsxs(
878
- DropdownMenuItem,
879
- {
880
- className: "flex items-center justify-between group",
881
- onSelect: (e) => e.preventDefault(),
882
- children: [
883
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
884
- /* @__PURE__ */ jsx(
885
- "span",
886
- {
887
- className: "truncate text-sm",
888
- title: file.name,
889
- children: file.name
890
- }
891
- ),
892
- /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: formatFileSize(file.size) })
893
- ] }),
894
- /* @__PURE__ */ jsx(
895
- Button,
896
- {
897
- type: "button",
898
- variant: "ghost",
899
- size: "icon",
900
- className: "h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity",
901
- onClick: () => handleRemoveFile(index),
902
- children: /* @__PURE__ */ jsx(IconX, { className: "h-3 w-3" })
903
- }
904
- )
905
- ]
906
- },
907
- index
908
- ))
909
- ] }),
910
- attachedFiles.length < maxFiles && /* @__PURE__ */ jsxs(Fragment, { children: [
911
- /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
912
- /* @__PURE__ */ jsxs(
913
- DropdownMenuItem,
914
- {
915
- onSelect: (e) => {
916
- e.preventDefault();
917
- fileInputRef.current?.click();
918
- },
919
- className: "text-primary focus:text-primary",
920
- children: [
921
- /* @__PURE__ */ jsx(IconPlus, { className: "mr-2 h-4 w-4" }),
922
- /* @__PURE__ */ jsx("span", { children: "Add more files" })
923
- ]
924
- }
925
- )
926
- ] })
927
- ] })
928
- ] })
1079
+ )
929
1080
  ] }),
930
1081
  options.map((group) => {
931
1082
  const selectedInGroup = group.options.filter(
@@ -2720,55 +2871,31 @@ var ThreadList = ({
2720
2871
  emptyState,
2721
2872
  onThreadSelect
2722
2873
  }) => {
2723
- const {
2724
- threads,
2725
- activeThreadId,
2726
- selectThread,
2727
- createThread,
2728
- deleteThread,
2729
- isLoading
2730
- } = useThreads();
2874
+ const { threads, activeThreadId, selectThread, deleteThread, isLoading } = useThreads();
2875
+ const sortedThreads = React11.useMemo(() => {
2876
+ return [...threads].sort((a, b) => {
2877
+ const dateA = a.updatedAt ? new Date(a.updatedAt).getTime() : 0;
2878
+ const dateB = b.updatedAt ? new Date(b.updatedAt).getTime() : 0;
2879
+ return dateB - dateA;
2880
+ });
2881
+ }, [threads]);
2731
2882
  const handleThreadClick = (threadId) => {
2732
2883
  if (threadId !== activeThreadId) {
2733
2884
  selectThread(threadId);
2734
2885
  }
2735
2886
  onThreadSelect?.(threadId);
2736
2887
  };
2737
- const handleDelete = async (e, threadId) => {
2738
- e.stopPropagation();
2888
+ const handleDelete = async (threadId) => {
2739
2889
  try {
2740
2890
  await deleteThread(threadId);
2741
2891
  } catch (error) {
2742
2892
  console.error("Failed to delete thread:", error);
2743
2893
  }
2744
2894
  };
2745
- const handleNewThread = async () => {
2746
- try {
2747
- await createThread();
2748
- } catch (error) {
2749
- console.error("Failed to create thread:", error);
2750
- }
2751
- };
2752
- const formatDate = (date) => {
2753
- if (!date) return "";
2754
- const d = typeof date === "string" ? new Date(date) : date;
2755
- if (isNaN(d.getTime())) return "";
2756
- const now = /* @__PURE__ */ new Date();
2757
- const diffMs = now.getTime() - d.getTime();
2758
- const diffMins = Math.floor(diffMs / 6e4);
2759
- const diffHours = Math.floor(diffMs / 36e5);
2760
- const diffDays = Math.floor(diffMs / 864e5);
2761
- if (diffMins < 1) return "Just now";
2762
- if (diffMins < 60) return `${diffMins}m ago`;
2763
- if (diffHours < 24) return `${diffHours}h ago`;
2764
- if (diffDays < 7) return `${diffDays}d ago`;
2765
- return d.toLocaleDateString();
2766
- };
2767
2895
  return /* @__PURE__ */ jsx("div", { className: cn("flex flex-col h-full", className), children: /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto", children: isLoading && threads.length === 0 ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsx(IconLoader2, { className: "size-5 animate-spin text-muted-foreground" }) }) : threads.length === 0 ? /* @__PURE__ */ jsx("div", { className: "p-4 text-center text-muted-foreground", children: emptyState || /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
2768
2896
  /* @__PURE__ */ jsx(IconMessage, { className: "size-8 mx-auto opacity-50" }),
2769
- /* @__PURE__ */ jsx("p", { className: "text-sm", children: "No threads yet" }),
2770
- /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: handleNewThread, children: "Start a conversation" })
2771
- ] }) }) : /* @__PURE__ */ jsx("div", { className: "p-2 space-y-1", children: threads.map((thread) => {
2897
+ /* @__PURE__ */ jsx("p", { className: "text-sm", children: "No threads yet" })
2898
+ ] }) }) : /* @__PURE__ */ jsx("div", { className: "p-2 space-y-1", children: sortedThreads.map((thread) => {
2772
2899
  const isActive = thread.id === activeThreadId;
2773
2900
  return /* @__PURE__ */ jsxs(
2774
2901
  "div",
@@ -2776,33 +2903,51 @@ var ThreadList = ({
2776
2903
  onClick: () => handleThreadClick(thread.id),
2777
2904
  className: cn(
2778
2905
  "group relative flex items-center gap-3 px-3 py-1.5 rounded-lg cursor-pointer transition-colors",
2779
- isActive ? "bg-muted" : "hover:bg-muted"
2906
+ isActive ? "bg-muted text-foreground" : "hover:bg-muted/50 text-muted-foreground hover:text-foreground"
2780
2907
  ),
2781
2908
  children: [
2782
- /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
2783
- /* @__PURE__ */ jsx("p", { className: cn("text-sm font-medium truncate"), children: thread.title || `Thread ${thread.id.slice(0, 8)}` }),
2784
- thread.updatedAt && /* @__PURE__ */ jsx("span", { className: cn("text-xs shrink-0"), children: formatDate(thread.updatedAt) })
2785
- ] }) }),
2786
- /* @__PURE__ */ jsx(
2787
- Button,
2788
- {
2789
- variant: "ghost",
2790
- size: "icon-xs",
2791
- onClick: (e) => handleDelete(e, thread.id),
2792
- className: cn(
2793
- "opacity-0 group-hover:opacity-100 transition-opacity shrink-0",
2794
- isActive && "hover:bg-primary-foreground/20"
2795
- ),
2796
- children: /* @__PURE__ */ jsx(IconTrash, { className: "size-3" })
2797
- }
2798
- )
2909
+ /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium truncate", children: thread.title || `Thread ${thread.id.slice(0, 8)}` }) }),
2910
+ /* @__PURE__ */ jsx("div", { className: "shrink-0 flex items-center opacity-0 group-hover:opacity-100 transition-opacity", children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
2911
+ /* @__PURE__ */ jsx(
2912
+ DropdownMenuTrigger,
2913
+ {
2914
+ render: (props) => /* @__PURE__ */ jsx(
2915
+ Button,
2916
+ {
2917
+ variant: "ghost",
2918
+ size: "icon-xs",
2919
+ ...props,
2920
+ onClick: (e) => {
2921
+ e.stopPropagation();
2922
+ props.onClick?.(e);
2923
+ },
2924
+ children: /* @__PURE__ */ jsx(IconDotsVertical, { className: "size-3.5" })
2925
+ }
2926
+ )
2927
+ }
2928
+ ),
2929
+ /* @__PURE__ */ jsx(DropdownMenuContent, { align: "start", className: "w-32", children: /* @__PURE__ */ jsxs(
2930
+ DropdownMenuItem,
2931
+ {
2932
+ variant: "destructive",
2933
+ onClick: (e) => {
2934
+ e.stopPropagation();
2935
+ handleDelete(thread.id);
2936
+ },
2937
+ children: [
2938
+ /* @__PURE__ */ jsx(IconTrash, { className: "size-4 mr-2" }),
2939
+ /* @__PURE__ */ jsx("span", { children: "Delete" })
2940
+ ]
2941
+ }
2942
+ ) })
2943
+ ] }) })
2799
2944
  ]
2800
2945
  },
2801
2946
  thread.id
2802
2947
  );
2803
2948
  }) }) }) });
2804
2949
  };
2805
- function ChatPopup({
2950
+ function PopupChat({
2806
2951
  title = "Chat",
2807
2952
  placeholder = "Message the AI",
2808
2953
  starterPrompts,
@@ -2906,136 +3051,46 @@ function ChatPopup({
2906
3051
  )
2907
3052
  ] });
2908
3053
  }
2909
- function ChatSidebar({
3054
+ function Sidebar({ side, children, className }) {
3055
+ const { leftCollapsed, rightCollapsed } = useSidebar();
3056
+ const collapsed = side === "left" ? leftCollapsed : rightCollapsed;
3057
+ return /* @__PURE__ */ jsx(
3058
+ "div",
3059
+ {
3060
+ className: cn(
3061
+ "flex-shrink-0 border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
3062
+ side === "left" ? "border-r" : "border-l",
3063
+ collapsed ? "w-0 border-r-0 border-l-0 min-w-0" : "",
3064
+ !collapsed && className
3065
+ ),
3066
+ children: /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden min-h-0", children })
3067
+ }
3068
+ );
3069
+ }
3070
+ function FullChat({
2910
3071
  title = "Chat",
2911
- placeholder = "Message the AI",
3072
+ placeholder,
2912
3073
  starterPrompts,
2913
3074
  options,
2914
3075
  className,
2915
3076
  headerProps,
3077
+ autoFocus = false,
2916
3078
  defaultSelectedIds
2917
3079
  }) {
2918
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col h-full border-r bg-background w-80", className), children: [
2919
- /* @__PURE__ */ jsx(ChatHeader, { title, ...headerProps }),
2920
- /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
3080
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col h-full w-full bg-background", className), children: [
3081
+ title && /* @__PURE__ */ jsx(ChatHeader, { title, ...headerProps }),
3082
+ /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden flex relative", children: /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden min-w-0", children: /* @__PURE__ */ jsx(
2921
3083
  Thread,
2922
3084
  {
2923
3085
  placeholder,
2924
3086
  starterPrompts,
2925
3087
  options,
2926
- className: "h-full",
3088
+ autoFocus,
2927
3089
  defaultSelectedIds
2928
3090
  }
2929
- ) })
3091
+ ) }) })
2930
3092
  ] });
2931
3093
  }
2932
- var ChatSidebarContext = createContext(
2933
- void 0
2934
- );
2935
- function useChatSidebar() {
2936
- const context = useContext(ChatSidebarContext);
2937
- if (context === void 0) {
2938
- throw new Error("useChatSidebar must be used within a ChatSidebarProvider");
2939
- }
2940
- return context;
2941
- }
2942
- function ChatFull({
2943
- title = "Chat",
2944
- placeholder = "Message the AI",
2945
- starterPrompts,
2946
- options,
2947
- className,
2948
- headerProps,
2949
- leftSidebar,
2950
- rightSidebar,
2951
- leftSidebarClassName,
2952
- rightSidebarClassName,
2953
- autoFocus = false,
2954
- defaultSelectedIds
2955
- }) {
2956
- const { isMobile, isTablet } = useScreenSize();
2957
- const isSmallScreen = isMobile || isTablet;
2958
- const [internalLeftCollapsed, setInternalLeftCollapsed] = useState(() => {
2959
- if (typeof window !== "undefined") {
2960
- return window.innerWidth < 1024;
2961
- }
2962
- return false;
2963
- });
2964
- const [internalRightCollapsed, setInternalRightCollapsed] = useState(() => {
2965
- if (typeof window !== "undefined") {
2966
- return window.innerWidth < 1024;
2967
- }
2968
- return false;
2969
- });
2970
- useEffect(() => {
2971
- if (isSmallScreen) {
2972
- setInternalLeftCollapsed(true);
2973
- setInternalRightCollapsed(true);
2974
- }
2975
- }, [isSmallScreen]);
2976
- const leftCollapsed = internalLeftCollapsed;
2977
- const rightCollapsed = internalRightCollapsed;
2978
- const handleLeftToggle = useCallback((collapsed) => {
2979
- setInternalLeftCollapsed(collapsed);
2980
- }, []);
2981
- const handleRightToggle = useCallback((collapsed) => {
2982
- setInternalRightCollapsed(collapsed);
2983
- }, []);
2984
- const contextValue = useMemo(
2985
- () => ({
2986
- leftCollapsed,
2987
- rightCollapsed,
2988
- setLeftCollapsed: handleLeftToggle,
2989
- setRightCollapsed: handleRightToggle,
2990
- leftCollapsible: true,
2991
- rightCollapsible: true
2992
- }),
2993
- [leftCollapsed, rightCollapsed, handleLeftToggle, handleRightToggle]
2994
- );
2995
- return /* @__PURE__ */ jsx(ChatSidebarContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs(
2996
- "div",
2997
- {
2998
- className: cn("flex flex-col h-full w-full bg-background", className),
2999
- children: [
3000
- title && /* @__PURE__ */ jsx(ChatHeader, { title, ...headerProps }),
3001
- /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-hidden flex relative", children: [
3002
- leftSidebar && /* @__PURE__ */ jsx(
3003
- "div",
3004
- {
3005
- className: cn(
3006
- "flex-shrink-0 border-r border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
3007
- leftCollapsed ? "w-0 border-r-0 min-w-0" : "",
3008
- !leftCollapsed && leftSidebarClassName
3009
- ),
3010
- children: /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: leftSidebar })
3011
- }
3012
- ),
3013
- /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden min-w-0", children: /* @__PURE__ */ jsx(
3014
- Thread,
3015
- {
3016
- placeholder,
3017
- starterPrompts,
3018
- options,
3019
- autoFocus,
3020
- defaultSelectedIds
3021
- }
3022
- ) }),
3023
- rightSidebar && /* @__PURE__ */ jsx(
3024
- "div",
3025
- {
3026
- className: cn(
3027
- "flex-shrink-0 border-l border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
3028
- rightCollapsed ? "w-0 border-l-0 min-w-0" : "",
3029
- !rightCollapsed && rightSidebarClassName
3030
- ),
3031
- children: /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: rightSidebar })
3032
- }
3033
- )
3034
- ] })
3035
- ]
3036
- }
3037
- ) });
3038
- }
3039
3094
  function SidebarToggle({ side, className }) {
3040
3095
  const {
3041
3096
  leftCollapsed,
@@ -3044,13 +3099,14 @@ function SidebarToggle({ side, className }) {
3044
3099
  setRightCollapsed,
3045
3100
  leftCollapsible,
3046
3101
  rightCollapsible
3047
- } = useChatSidebar();
3102
+ } = useSidebar();
3048
3103
  if (side === "left") {
3049
3104
  if (!leftCollapsible) return null;
3050
3105
  return /* @__PURE__ */ jsx(
3051
3106
  Button,
3052
3107
  {
3053
3108
  variant: "ghost",
3109
+ size: "icon",
3054
3110
  onClick: () => setLeftCollapsed(!leftCollapsed),
3055
3111
  "aria-label": leftCollapsed ? "Expand left sidebar" : "Collapse left sidebar",
3056
3112
  className: cn("", className),
@@ -3064,6 +3120,7 @@ function SidebarToggle({ side, className }) {
3064
3120
  Button,
3065
3121
  {
3066
3122
  variant: "ghost",
3123
+ size: "icon",
3067
3124
  onClick: () => setRightCollapsed(!rightCollapsed),
3068
3125
  "aria-label": rightCollapsed ? "Expand right sidebar" : "Collapse right sidebar",
3069
3126
  className: cn("", className),
@@ -3331,7 +3388,7 @@ var ThreadPopover = ({
3331
3388
  var CreateThreadButton = ({
3332
3389
  className,
3333
3390
  variant = "ghost",
3334
- size = "icon",
3391
+ size = "default",
3335
3392
  children,
3336
3393
  onThreadCreated
3337
3394
  }) => {
@@ -3362,7 +3419,7 @@ var CreateThreadButton = ({
3362
3419
  // Don't trigger in contenteditable elements
3363
3420
  }
3364
3421
  );
3365
- return /* @__PURE__ */ jsx(
3422
+ return /* @__PURE__ */ jsxs(
3366
3423
  Button,
3367
3424
  {
3368
3425
  variant,
@@ -3370,7 +3427,10 @@ var CreateThreadButton = ({
3370
3427
  onClick: handleCreateThread,
3371
3428
  disabled: isCreating,
3372
3429
  className: cn(className),
3373
- children: /* @__PURE__ */ jsx(IconPlus, { className: "size-4" })
3430
+ children: [
3431
+ /* @__PURE__ */ jsx(IconPlus, { className: "size-4" }),
3432
+ "New chat"
3433
+ ]
3374
3434
  }
3375
3435
  );
3376
3436
  };
@@ -3564,17 +3624,14 @@ var AccountDialog = ({
3564
3624
  ] });
3565
3625
  }
3566
3626
  return /* @__PURE__ */ jsxs(Fragment, { children: [
3567
- /* @__PURE__ */ jsxs(
3627
+ /* @__PURE__ */ jsx(
3568
3628
  Button,
3569
3629
  {
3570
3630
  variant,
3571
3631
  size,
3572
3632
  onClick: () => setOpen(true),
3573
3633
  className,
3574
- children: [
3575
- /* @__PURE__ */ jsx(IconBrandGoogle, { className: "mr-2 size-4" }),
3576
- "Sign in with Google"
3577
- ]
3634
+ children: "Sign in"
3578
3635
  }
3579
3636
  ),
3580
3637
  /* @__PURE__ */ jsx(AlertDialog, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs(AlertDialogContent, { className: "sm:max-w-md", children: [
@@ -3638,6 +3695,6 @@ function ThemeToggle() {
3638
3695
  );
3639
3696
  }
3640
3697
 
3641
- export { AccountDialog, AuthContext, AuthProvider, Badge2 as Badge, Box, Button2 as Button, Card2 as Card, Chart, ChatFull, ChatHeader, ChatPopup, ChatSidebar, ChatSidebarContext, Checkbox, Col, Composer, CreateThreadButton, Divider, Form, Heading, Image, Input2 as Input, Label2 as Label, List, ListItem, MelonyClientProvider, MelonyContext, RadioGroup, Row, Select2 as Select, SidebarToggle, Spacer, Text, Textarea2 as Textarea, ThemeProvider, ThemeToggle, Thread, ThreadContext, ThreadList, ThreadPopover, ThreadProvider, UIRenderer, groupEventsToMessages, useAuth, useChatSidebar, useMelony, useScreenSize, useTheme, useThreads };
3698
+ export { AccountDialog, AuthContext, AuthProvider, Badge2 as Badge, Box, Button2 as Button, Card2 as Card, Chart, ChatHeader, Checkbox, Col, Composer, CreateThreadButton, Divider, Form, FullChat, Heading, Image, Input2 as Input, Label2 as Label, List, ListItem, MelonyClientProvider, MelonyContext, PopupChat, RadioGroup, Row, Select2 as Select, Sidebar, SidebarContext, SidebarProvider, SidebarToggle, Spacer, Text, Textarea2 as Textarea, ThemeProvider, ThemeToggle, Thread, ThreadContext, ThreadList, ThreadPopover, ThreadProvider, UIRenderer, WelcomeScreen, groupEventsToMessages, useAuth, useMelony, useScreenSize, useSidebar, useTheme, useThreads };
3642
3699
  //# sourceMappingURL=index.js.map
3643
3700
  //# sourceMappingURL=index.js.map