@melony/react 0.1.12 → 0.1.15
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/README.md +55 -194
- package/dist/index.cjs +1409 -415
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +181 -12
- package/dist/index.d.ts +181 -12
- package/dist/index.js +1358 -371
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React11 = require('react');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var client = require('melony/client');
|
|
4
6
|
var clsx = require('clsx');
|
|
5
7
|
var tailwindMerge = require('tailwind-merge');
|
|
6
|
-
var
|
|
7
|
-
var
|
|
8
|
-
var separator = require('@base-ui/react/separator');
|
|
8
|
+
var button = require('@base-ui/react/button');
|
|
9
|
+
var classVarianceAuthority = require('class-variance-authority');
|
|
9
10
|
var ICONS = require('@tabler/icons-react');
|
|
11
|
+
var menu = require('@base-ui/react/menu');
|
|
12
|
+
var separator = require('@base-ui/react/separator');
|
|
13
|
+
var dialog = require('@base-ui/react/dialog');
|
|
10
14
|
var mergeProps = require('@base-ui/react/merge-props');
|
|
11
15
|
var useRender = require('@base-ui/react/use-render');
|
|
12
|
-
var classVarianceAuthority = require('class-variance-authority');
|
|
13
16
|
var input = require('@base-ui/react/input');
|
|
14
17
|
var select = require('@base-ui/react/select');
|
|
15
|
-
var
|
|
18
|
+
var reactDom = require('react-dom');
|
|
19
|
+
var reactHotkeysHook = require('react-hotkeys-hook');
|
|
16
20
|
var alertDialog = require('@base-ui/react/alert-dialog');
|
|
17
|
-
var menu = require('@base-ui/react/menu');
|
|
18
21
|
|
|
19
22
|
function _interopNamespace(e) {
|
|
20
23
|
if (e && e.__esModule) return e;
|
|
@@ -34,13 +37,12 @@ function _interopNamespace(e) {
|
|
|
34
37
|
return Object.freeze(n);
|
|
35
38
|
}
|
|
36
39
|
|
|
37
|
-
var
|
|
40
|
+
var React11__namespace = /*#__PURE__*/_interopNamespace(React11);
|
|
38
41
|
var ICONS__namespace = /*#__PURE__*/_interopNamespace(ICONS);
|
|
39
42
|
|
|
40
43
|
// src/providers/melony-provider.tsx
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
+
|
|
45
|
+
// src/lib/group-events-to-messages.ts
|
|
44
46
|
function groupEventsToMessages(events) {
|
|
45
47
|
if (events.length === 0) return [];
|
|
46
48
|
const messages = [];
|
|
@@ -64,7 +66,7 @@ function groupEventsToMessages(events) {
|
|
|
64
66
|
}
|
|
65
67
|
return messages;
|
|
66
68
|
}
|
|
67
|
-
var MelonyContext =
|
|
69
|
+
var MelonyContext = React11.createContext(
|
|
68
70
|
void 0
|
|
69
71
|
);
|
|
70
72
|
var MelonyClientProvider = ({
|
|
@@ -72,20 +74,20 @@ var MelonyClientProvider = ({
|
|
|
72
74
|
client,
|
|
73
75
|
initialEvents
|
|
74
76
|
}) => {
|
|
75
|
-
const [state, setState] =
|
|
76
|
-
|
|
77
|
+
const [state, setState] = React11.useState(client.getState());
|
|
78
|
+
React11.useEffect(() => {
|
|
77
79
|
if (initialEvents && initialEvents.length > 0 && client.getState().events.length === 0) {
|
|
78
80
|
client.reset(initialEvents);
|
|
79
81
|
}
|
|
80
82
|
}, [client, initialEvents]);
|
|
81
|
-
|
|
83
|
+
React11.useEffect(() => {
|
|
82
84
|
setState(client.getState());
|
|
83
85
|
const unsubscribe = client.subscribe(setState);
|
|
84
86
|
return () => {
|
|
85
87
|
unsubscribe();
|
|
86
88
|
};
|
|
87
89
|
}, [client]);
|
|
88
|
-
const sendEvent =
|
|
90
|
+
const sendEvent = React11.useCallback(
|
|
89
91
|
async (event, options) => {
|
|
90
92
|
const generator = client.sendEvent(event, options);
|
|
91
93
|
for await (const _ of generator) {
|
|
@@ -93,11 +95,11 @@ var MelonyClientProvider = ({
|
|
|
93
95
|
},
|
|
94
96
|
[client]
|
|
95
97
|
);
|
|
96
|
-
const reset =
|
|
98
|
+
const reset = React11.useCallback(
|
|
97
99
|
(events) => client.reset(events),
|
|
98
100
|
[client]
|
|
99
101
|
);
|
|
100
|
-
const value =
|
|
102
|
+
const value = React11.useMemo(
|
|
101
103
|
() => ({
|
|
102
104
|
...state,
|
|
103
105
|
messages: groupEventsToMessages(state.events),
|
|
@@ -109,16 +111,16 @@ var MelonyClientProvider = ({
|
|
|
109
111
|
);
|
|
110
112
|
return /* @__PURE__ */ jsxRuntime.jsx(MelonyContext.Provider, { value, children });
|
|
111
113
|
};
|
|
112
|
-
var AuthContext =
|
|
114
|
+
var AuthContext = React11.createContext(
|
|
113
115
|
void 0
|
|
114
116
|
);
|
|
115
117
|
var AuthProvider = ({
|
|
116
118
|
children,
|
|
117
119
|
service
|
|
118
120
|
}) => {
|
|
119
|
-
const [user, setUser] =
|
|
120
|
-
const [isLoading, setIsLoading] =
|
|
121
|
-
const fetchMe =
|
|
121
|
+
const [user, setUser] = React11.useState(null);
|
|
122
|
+
const [isLoading, setIsLoading] = React11.useState(true);
|
|
123
|
+
const fetchMe = React11.useCallback(async () => {
|
|
122
124
|
setIsLoading(true);
|
|
123
125
|
try {
|
|
124
126
|
const userData = await service.getMe();
|
|
@@ -130,13 +132,13 @@ var AuthProvider = ({
|
|
|
130
132
|
setIsLoading(false);
|
|
131
133
|
}
|
|
132
134
|
}, [service]);
|
|
133
|
-
|
|
135
|
+
React11.useEffect(() => {
|
|
134
136
|
fetchMe();
|
|
135
137
|
}, [fetchMe]);
|
|
136
|
-
const login =
|
|
138
|
+
const login = React11.useCallback(() => {
|
|
137
139
|
service.login();
|
|
138
140
|
}, [service]);
|
|
139
|
-
const logout =
|
|
141
|
+
const logout = React11.useCallback(async () => {
|
|
140
142
|
try {
|
|
141
143
|
await service.logout();
|
|
142
144
|
setUser(null);
|
|
@@ -172,7 +174,7 @@ var AuthProvider = ({
|
|
|
172
174
|
}
|
|
173
175
|
return /* @__PURE__ */ jsxRuntime.jsx(AuthContext.Provider, { value, children });
|
|
174
176
|
};
|
|
175
|
-
var ThreadContext =
|
|
177
|
+
var ThreadContext = React11.createContext(
|
|
176
178
|
void 0
|
|
177
179
|
);
|
|
178
180
|
var ThreadProvider = ({
|
|
@@ -180,17 +182,17 @@ var ThreadProvider = ({
|
|
|
180
182
|
service,
|
|
181
183
|
initialThreadId: providedInitialThreadId
|
|
182
184
|
}) => {
|
|
183
|
-
const defaultInitialThreadId =
|
|
185
|
+
const defaultInitialThreadId = React11.useMemo(() => client.generateId(), []);
|
|
184
186
|
const initialThreadId = providedInitialThreadId || defaultInitialThreadId;
|
|
185
|
-
const [threads, setThreads] =
|
|
186
|
-
const [activeThreadId, setActiveThreadId] =
|
|
187
|
+
const [threads, setThreads] = React11.useState([]);
|
|
188
|
+
const [activeThreadId, setActiveThreadId] = React11.useState(
|
|
187
189
|
initialThreadId
|
|
188
190
|
);
|
|
189
|
-
const [isLoading, setIsLoading] =
|
|
190
|
-
const [error, setError] =
|
|
191
|
-
const [threadEvents, setThreadEvents] =
|
|
192
|
-
const [isLoadingEvents, setIsLoadingEvents] =
|
|
193
|
-
const fetchThreads =
|
|
191
|
+
const [isLoading, setIsLoading] = React11.useState(true);
|
|
192
|
+
const [error, setError] = React11.useState(null);
|
|
193
|
+
const [threadEvents, setThreadEvents] = React11.useState([]);
|
|
194
|
+
const [isLoadingEvents, setIsLoadingEvents] = React11.useState(false);
|
|
195
|
+
const fetchThreads = React11.useCallback(async () => {
|
|
194
196
|
setIsLoading(true);
|
|
195
197
|
setError(null);
|
|
196
198
|
try {
|
|
@@ -204,13 +206,13 @@ var ThreadProvider = ({
|
|
|
204
206
|
setIsLoading(false);
|
|
205
207
|
}
|
|
206
208
|
}, [service]);
|
|
207
|
-
|
|
209
|
+
React11.useEffect(() => {
|
|
208
210
|
fetchThreads();
|
|
209
211
|
}, [fetchThreads]);
|
|
210
|
-
const selectThread =
|
|
212
|
+
const selectThread = React11.useCallback((threadId) => {
|
|
211
213
|
setActiveThreadId(threadId);
|
|
212
214
|
}, []);
|
|
213
|
-
const createThread =
|
|
215
|
+
const createThread = React11.useCallback(async () => {
|
|
214
216
|
const newId = service.createThread ? await service.createThread() : client.generateId();
|
|
215
217
|
const newThread = {
|
|
216
218
|
id: newId,
|
|
@@ -220,7 +222,7 @@ var ThreadProvider = ({
|
|
|
220
222
|
setActiveThreadId(newId);
|
|
221
223
|
return newId;
|
|
222
224
|
}, [service]);
|
|
223
|
-
const deleteThread =
|
|
225
|
+
const deleteThread = React11.useCallback(
|
|
224
226
|
async (threadId) => {
|
|
225
227
|
try {
|
|
226
228
|
await service.deleteThread(threadId);
|
|
@@ -242,10 +244,10 @@ var ThreadProvider = ({
|
|
|
242
244
|
},
|
|
243
245
|
[service]
|
|
244
246
|
);
|
|
245
|
-
const refreshThreads =
|
|
247
|
+
const refreshThreads = React11.useCallback(async () => {
|
|
246
248
|
await fetchThreads();
|
|
247
249
|
}, [fetchThreads]);
|
|
248
|
-
|
|
250
|
+
React11.useEffect(() => {
|
|
249
251
|
if (!activeThreadId) {
|
|
250
252
|
setThreadEvents([]);
|
|
251
253
|
setIsLoadingEvents(false);
|
|
@@ -275,7 +277,7 @@ var ThreadProvider = ({
|
|
|
275
277
|
cancelled = true;
|
|
276
278
|
};
|
|
277
279
|
}, [activeThreadId, service]);
|
|
278
|
-
const value =
|
|
280
|
+
const value = React11.useMemo(
|
|
279
281
|
() => ({
|
|
280
282
|
threads,
|
|
281
283
|
activeThreadId,
|
|
@@ -303,14 +305,66 @@ var ThreadProvider = ({
|
|
|
303
305
|
);
|
|
304
306
|
return /* @__PURE__ */ jsxRuntime.jsx(ThreadContext.Provider, { value, children });
|
|
305
307
|
};
|
|
308
|
+
var ThemeContext = React11.createContext(void 0);
|
|
309
|
+
function ThemeProvider({ children }) {
|
|
310
|
+
const [theme, setThemeState] = React11.useState("system");
|
|
311
|
+
const [resolvedTheme, setResolvedTheme] = React11.useState("light");
|
|
312
|
+
React11.useEffect(() => {
|
|
313
|
+
if (typeof window !== "undefined") {
|
|
314
|
+
const stored = localStorage.getItem("theme");
|
|
315
|
+
if (stored) {
|
|
316
|
+
setThemeState(stored);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}, []);
|
|
320
|
+
React11.useEffect(() => {
|
|
321
|
+
if (typeof window !== "undefined") {
|
|
322
|
+
if (theme === "system") {
|
|
323
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
324
|
+
const updateResolvedTheme = () => {
|
|
325
|
+
setResolvedTheme(mediaQuery.matches ? "dark" : "light");
|
|
326
|
+
};
|
|
327
|
+
updateResolvedTheme();
|
|
328
|
+
mediaQuery.addEventListener("change", updateResolvedTheme);
|
|
329
|
+
return () => mediaQuery.removeEventListener("change", updateResolvedTheme);
|
|
330
|
+
} else {
|
|
331
|
+
setResolvedTheme(theme);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}, [theme]);
|
|
335
|
+
React11.useEffect(() => {
|
|
336
|
+
if (typeof window !== "undefined") {
|
|
337
|
+
const root = document.documentElement;
|
|
338
|
+
if (resolvedTheme === "dark") {
|
|
339
|
+
root.classList.add("dark");
|
|
340
|
+
} else {
|
|
341
|
+
root.classList.remove("dark");
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}, [resolvedTheme]);
|
|
345
|
+
const setTheme = (newTheme) => {
|
|
346
|
+
setThemeState(newTheme);
|
|
347
|
+
if (typeof window !== "undefined") {
|
|
348
|
+
localStorage.setItem("theme", newTheme);
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value: { theme, setTheme, resolvedTheme }, children });
|
|
352
|
+
}
|
|
353
|
+
function useTheme() {
|
|
354
|
+
const context = React11.useContext(ThemeContext);
|
|
355
|
+
if (context === void 0) {
|
|
356
|
+
throw new Error("useTheme must be used within a ThemeProvider");
|
|
357
|
+
}
|
|
358
|
+
return context;
|
|
359
|
+
}
|
|
306
360
|
var useMelony = (options) => {
|
|
307
|
-
const context =
|
|
361
|
+
const context = React11.useContext(MelonyContext);
|
|
308
362
|
if (context === void 0) {
|
|
309
363
|
throw new Error("useMelony must be used within a MelonyClientProvider");
|
|
310
364
|
}
|
|
311
365
|
const { client, reset } = context;
|
|
312
366
|
const { initialEvents } = options || {};
|
|
313
|
-
|
|
367
|
+
React11.useEffect(() => {
|
|
314
368
|
if (initialEvents && initialEvents.length > 0 && client.getState().events.length === 0) {
|
|
315
369
|
reset(initialEvents);
|
|
316
370
|
}
|
|
@@ -318,19 +372,326 @@ var useMelony = (options) => {
|
|
|
318
372
|
return context;
|
|
319
373
|
};
|
|
320
374
|
var useAuth = () => {
|
|
321
|
-
const context =
|
|
375
|
+
const context = React11.useContext(AuthContext);
|
|
322
376
|
if (context === void 0) {
|
|
323
377
|
throw new Error("useAuth must be used within an AuthProvider");
|
|
324
378
|
}
|
|
325
379
|
return context;
|
|
326
380
|
};
|
|
327
381
|
var useThreads = () => {
|
|
328
|
-
const context =
|
|
382
|
+
const context = React11.useContext(ThreadContext);
|
|
329
383
|
if (context === void 0) {
|
|
330
384
|
throw new Error("useThreads must be used within a ThreadProvider");
|
|
331
385
|
}
|
|
332
386
|
return context;
|
|
333
387
|
};
|
|
388
|
+
function cn(...inputs) {
|
|
389
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
390
|
+
}
|
|
391
|
+
var buttonVariants = classVarianceAuthority.cva(
|
|
392
|
+
"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",
|
|
393
|
+
{
|
|
394
|
+
variants: {
|
|
395
|
+
variant: {
|
|
396
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
|
397
|
+
outline: "border-border bg-input/30 hover:bg-input/50 hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
398
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
|
399
|
+
ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
400
|
+
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",
|
|
401
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
402
|
+
},
|
|
403
|
+
size: {
|
|
404
|
+
default: "h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5",
|
|
405
|
+
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",
|
|
406
|
+
sm: "h-8 gap-1 px-3 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
407
|
+
lg: "h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
|
|
408
|
+
icon: "size-9",
|
|
409
|
+
"icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
|
|
410
|
+
"icon-sm": "size-8",
|
|
411
|
+
"icon-lg": "size-10"
|
|
412
|
+
}
|
|
413
|
+
},
|
|
414
|
+
defaultVariants: {
|
|
415
|
+
variant: "default",
|
|
416
|
+
size: "default"
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
);
|
|
420
|
+
function Button({
|
|
421
|
+
className,
|
|
422
|
+
variant = "default",
|
|
423
|
+
size = "default",
|
|
424
|
+
...props
|
|
425
|
+
}) {
|
|
426
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
427
|
+
button.Button,
|
|
428
|
+
{
|
|
429
|
+
"data-slot": "button",
|
|
430
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
431
|
+
...props
|
|
432
|
+
}
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
function Textarea({ className, ...props }) {
|
|
436
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
437
|
+
"textarea",
|
|
438
|
+
{
|
|
439
|
+
"data-slot": "textarea",
|
|
440
|
+
className: cn(
|
|
441
|
+
"border-input bg-input/30 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 resize-none rounded-xl border px-3 py-3 text-base transition-colors focus-visible:ring-[3px] aria-invalid:ring-[3px] md:text-sm placeholder:text-muted-foreground flex field-sizing-content min-h-16 w-full outline-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
442
|
+
className
|
|
443
|
+
),
|
|
444
|
+
...props
|
|
445
|
+
}
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
function DropdownMenu({ ...props }) {
|
|
449
|
+
return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Root, { "data-slot": "dropdown-menu", ...props });
|
|
450
|
+
}
|
|
451
|
+
function DropdownMenuTrigger({ ...props }) {
|
|
452
|
+
return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
453
|
+
}
|
|
454
|
+
function DropdownMenuContent({
|
|
455
|
+
align = "start",
|
|
456
|
+
alignOffset = 0,
|
|
457
|
+
side = "bottom",
|
|
458
|
+
sideOffset = 4,
|
|
459
|
+
className,
|
|
460
|
+
...props
|
|
461
|
+
}) {
|
|
462
|
+
return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
463
|
+
menu.Menu.Positioner,
|
|
464
|
+
{
|
|
465
|
+
className: "isolate z-50 outline-none",
|
|
466
|
+
align,
|
|
467
|
+
alignOffset,
|
|
468
|
+
side,
|
|
469
|
+
sideOffset,
|
|
470
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
471
|
+
menu.Menu.Popup,
|
|
472
|
+
{
|
|
473
|
+
"data-slot": "dropdown-menu-content",
|
|
474
|
+
className: cn("data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/5 bg-popover text-popover-foreground min-w-48 rounded-2xl p-1 shadow-2xl ring-1 duration-100 z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto outline-none data-closed:overflow-hidden", className),
|
|
475
|
+
...props
|
|
476
|
+
}
|
|
477
|
+
)
|
|
478
|
+
}
|
|
479
|
+
) });
|
|
480
|
+
}
|
|
481
|
+
function DropdownMenuGroup({ ...props }) {
|
|
482
|
+
return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Group, { "data-slot": "dropdown-menu-group", ...props });
|
|
483
|
+
}
|
|
484
|
+
function DropdownMenuLabel({
|
|
485
|
+
className,
|
|
486
|
+
inset,
|
|
487
|
+
...props
|
|
488
|
+
}) {
|
|
489
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
490
|
+
menu.Menu.GroupLabel,
|
|
491
|
+
{
|
|
492
|
+
"data-slot": "dropdown-menu-label",
|
|
493
|
+
"data-inset": inset,
|
|
494
|
+
className: cn("text-muted-foreground px-3 py-2.5 text-xs data-[inset]:pl-8", className),
|
|
495
|
+
...props
|
|
496
|
+
}
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
function DropdownMenuItem({
|
|
500
|
+
className,
|
|
501
|
+
inset,
|
|
502
|
+
variant = "default",
|
|
503
|
+
...props
|
|
504
|
+
}) {
|
|
505
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
506
|
+
menu.Menu.Item,
|
|
507
|
+
{
|
|
508
|
+
"data-slot": "dropdown-menu-item",
|
|
509
|
+
"data-inset": inset,
|
|
510
|
+
"data-variant": variant,
|
|
511
|
+
className: cn(
|
|
512
|
+
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2.5 rounded-xl px-3 py-2 text-sm [&_svg:not([class*='size-'])]:size-4 group/dropdown-menu-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
513
|
+
className
|
|
514
|
+
),
|
|
515
|
+
...props
|
|
516
|
+
}
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
function DropdownMenuCheckboxItem({
|
|
520
|
+
className,
|
|
521
|
+
children,
|
|
522
|
+
checked,
|
|
523
|
+
...props
|
|
524
|
+
}) {
|
|
525
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
526
|
+
menu.Menu.CheckboxItem,
|
|
527
|
+
{
|
|
528
|
+
"data-slot": "dropdown-menu-checkbox-item",
|
|
529
|
+
className: cn(
|
|
530
|
+
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-2.5 rounded-xl py-2 pr-8 pl-3 text-sm [&_svg:not([class*='size-'])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
531
|
+
className
|
|
532
|
+
),
|
|
533
|
+
checked,
|
|
534
|
+
...props,
|
|
535
|
+
children: [
|
|
536
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
537
|
+
"span",
|
|
538
|
+
{
|
|
539
|
+
className: "pointer-events-none absolute right-2 flex items-center justify-center pointer-events-none",
|
|
540
|
+
"data-slot": "dropdown-menu-checkbox-item-indicator",
|
|
541
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.CheckboxItemIndicator, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
542
|
+
ICONS.IconCheck,
|
|
543
|
+
{}
|
|
544
|
+
) })
|
|
545
|
+
}
|
|
546
|
+
),
|
|
547
|
+
children
|
|
548
|
+
]
|
|
549
|
+
}
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
function DropdownMenuSeparator({
|
|
553
|
+
className,
|
|
554
|
+
...props
|
|
555
|
+
}) {
|
|
556
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
557
|
+
menu.Menu.Separator,
|
|
558
|
+
{
|
|
559
|
+
"data-slot": "dropdown-menu-separator",
|
|
560
|
+
className: cn("bg-border/50 -mx-1 my-1 h-px", className),
|
|
561
|
+
...props
|
|
562
|
+
}
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
function Composer({
|
|
566
|
+
value,
|
|
567
|
+
onChange,
|
|
568
|
+
onSubmit,
|
|
569
|
+
placeholder = "Type a message...",
|
|
570
|
+
isLoading,
|
|
571
|
+
className,
|
|
572
|
+
options = [],
|
|
573
|
+
autoFocus = false,
|
|
574
|
+
defaultSelectedIds = []
|
|
575
|
+
}) {
|
|
576
|
+
const [selectedOptions, setSelectedOptions] = React11__namespace.default.useState(
|
|
577
|
+
() => new Set(defaultSelectedIds)
|
|
578
|
+
);
|
|
579
|
+
const toggleOption = (id, groupOptions, type = "multiple") => {
|
|
580
|
+
const next = new Set(selectedOptions);
|
|
581
|
+
if (type === "single") {
|
|
582
|
+
const isAlreadySelected = next.has(id);
|
|
583
|
+
if (groupOptions) {
|
|
584
|
+
groupOptions.forEach((o) => next.delete(o.id));
|
|
585
|
+
}
|
|
586
|
+
if (!isAlreadySelected) {
|
|
587
|
+
next.add(id);
|
|
588
|
+
}
|
|
589
|
+
} else {
|
|
590
|
+
if (next.has(id)) {
|
|
591
|
+
next.delete(id);
|
|
592
|
+
} else {
|
|
593
|
+
next.add(id);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
setSelectedOptions(next);
|
|
597
|
+
};
|
|
598
|
+
const handleInternalSubmit = () => {
|
|
599
|
+
const state = {};
|
|
600
|
+
options.forEach((group) => {
|
|
601
|
+
const selectedInGroup = group.options.filter(
|
|
602
|
+
(o) => selectedOptions.has(o.id)
|
|
603
|
+
);
|
|
604
|
+
if (selectedInGroup.length > 0) {
|
|
605
|
+
if (group.type === "single") {
|
|
606
|
+
state[group.id] = selectedInGroup[0].value;
|
|
607
|
+
} else {
|
|
608
|
+
state[group.id] = selectedInGroup.map((o) => ({
|
|
609
|
+
id: o.id,
|
|
610
|
+
value: o.value
|
|
611
|
+
}));
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
});
|
|
615
|
+
onSubmit(state);
|
|
616
|
+
};
|
|
617
|
+
const handleKeyDown = (e) => {
|
|
618
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
619
|
+
e.preventDefault();
|
|
620
|
+
handleInternalSubmit();
|
|
621
|
+
}
|
|
622
|
+
};
|
|
623
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("relative flex flex-col w-full", className), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-col w-full border-input border-[1.5px] rounded-3xl bg-background shadow-sm focus-within:border-ring transition-all p-2", children: [
|
|
624
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
625
|
+
Textarea,
|
|
626
|
+
{
|
|
627
|
+
value,
|
|
628
|
+
onChange: (e) => onChange(e.target.value),
|
|
629
|
+
onKeyDown: handleKeyDown,
|
|
630
|
+
placeholder,
|
|
631
|
+
className: "min-h-[44px] max-h-[200px] border-none bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 px-3 py-2 text-[15px] resize-none",
|
|
632
|
+
autoFocus
|
|
633
|
+
}
|
|
634
|
+
),
|
|
635
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center px-1", children: [
|
|
636
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: options.map((group) => {
|
|
637
|
+
const selectedInGroup = group.options.filter(
|
|
638
|
+
(o) => selectedOptions.has(o.id)
|
|
639
|
+
);
|
|
640
|
+
const label = selectedInGroup.length === 0 ? group.label : selectedInGroup.length === 1 ? selectedInGroup[0].label : `${group.label} (${selectedInGroup.length})`;
|
|
641
|
+
const isSingle = group.type === "single";
|
|
642
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
|
|
643
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
644
|
+
DropdownMenuTrigger,
|
|
645
|
+
{
|
|
646
|
+
render: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
647
|
+
Button,
|
|
648
|
+
{
|
|
649
|
+
variant: "ghost",
|
|
650
|
+
size: "sm",
|
|
651
|
+
className: cn(
|
|
652
|
+
selectedInGroup.length > 0 ? "text-foreground bg-muted/50" : "text-muted-foreground"
|
|
653
|
+
),
|
|
654
|
+
children: [
|
|
655
|
+
label,
|
|
656
|
+
/* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronDown, { className: "h-3 w-3 opacity-50" })
|
|
657
|
+
]
|
|
658
|
+
}
|
|
659
|
+
)
|
|
660
|
+
}
|
|
661
|
+
),
|
|
662
|
+
/* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "start", className: "w-56", children: /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuGroup, { children: [
|
|
663
|
+
/* @__PURE__ */ jsxRuntime.jsx(DropdownMenuLabel, { children: group.label }),
|
|
664
|
+
/* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
|
|
665
|
+
group.options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
666
|
+
DropdownMenuCheckboxItem,
|
|
667
|
+
{
|
|
668
|
+
checked: selectedOptions.has(option.id),
|
|
669
|
+
onCheckedChange: () => toggleOption(
|
|
670
|
+
option.id,
|
|
671
|
+
group.options,
|
|
672
|
+
isSingle ? "single" : "multiple"
|
|
673
|
+
),
|
|
674
|
+
onSelect: (e) => e.preventDefault(),
|
|
675
|
+
children: option.label
|
|
676
|
+
},
|
|
677
|
+
option.id
|
|
678
|
+
))
|
|
679
|
+
] }) })
|
|
680
|
+
] }, group.id);
|
|
681
|
+
}) }),
|
|
682
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
683
|
+
Button,
|
|
684
|
+
{
|
|
685
|
+
type: "submit",
|
|
686
|
+
disabled: !value.trim() && !isLoading || isLoading,
|
|
687
|
+
size: "icon-lg",
|
|
688
|
+
onClick: handleInternalSubmit,
|
|
689
|
+
children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLoader2, { className: "h-5 w-5 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconArrowUp, { className: "h-5 w-5" })
|
|
690
|
+
}
|
|
691
|
+
)
|
|
692
|
+
] })
|
|
693
|
+
] }) });
|
|
694
|
+
}
|
|
334
695
|
function Card({
|
|
335
696
|
className,
|
|
336
697
|
size = "default",
|
|
@@ -399,7 +760,7 @@ var Card2 = ({
|
|
|
399
760
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
400
761
|
Card,
|
|
401
762
|
{
|
|
402
|
-
className: cn("
|
|
763
|
+
className: cn("min-w-96", className),
|
|
403
764
|
style,
|
|
404
765
|
children: [
|
|
405
766
|
(title || subtitle) && /* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "pb-3", children: [
|
|
@@ -714,31 +1075,137 @@ var ListItem = ({
|
|
|
714
1075
|
}
|
|
715
1076
|
);
|
|
716
1077
|
};
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
1078
|
+
function Dialog({ ...props }) {
|
|
1079
|
+
return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
1080
|
+
}
|
|
1081
|
+
function DialogTrigger({ ...props }) {
|
|
1082
|
+
return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog.Trigger, { "data-slot": "dialog-trigger", ...props });
|
|
1083
|
+
}
|
|
1084
|
+
function DialogPortal({ ...props }) {
|
|
1085
|
+
return /* @__PURE__ */ jsxRuntime.jsx(dialog.Dialog.Portal, { "data-slot": "dialog-portal", ...props });
|
|
1086
|
+
}
|
|
1087
|
+
function DialogOverlay({
|
|
721
1088
|
className,
|
|
722
|
-
|
|
723
|
-
})
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
1089
|
+
...props
|
|
1090
|
+
}) {
|
|
1091
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1092
|
+
dialog.Dialog.Backdrop,
|
|
1093
|
+
{
|
|
1094
|
+
"data-slot": "dialog-overlay",
|
|
1095
|
+
className: cn(
|
|
1096
|
+
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 bg-black/80 duration-200 supports-backdrop-filter:backdrop-blur-sm fixed inset-0 isolate z-50",
|
|
1097
|
+
className
|
|
1098
|
+
),
|
|
1099
|
+
...props
|
|
1100
|
+
}
|
|
1101
|
+
);
|
|
1102
|
+
}
|
|
1103
|
+
function DialogContent({
|
|
1104
|
+
className,
|
|
1105
|
+
...props
|
|
1106
|
+
}) {
|
|
1107
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { children: [
|
|
1108
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
|
|
1109
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1110
|
+
dialog.Dialog.Popup,
|
|
1111
|
+
{
|
|
1112
|
+
"data-slot": "dialog-content",
|
|
1113
|
+
className: cn(
|
|
1114
|
+
"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 sm:rounded-lg outline-none",
|
|
1115
|
+
className
|
|
1116
|
+
),
|
|
1117
|
+
...props
|
|
1118
|
+
}
|
|
1119
|
+
)
|
|
1120
|
+
] });
|
|
1121
|
+
}
|
|
1122
|
+
function DialogClose({
|
|
1123
|
+
className,
|
|
1124
|
+
...props
|
|
1125
|
+
}) {
|
|
1126
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1127
|
+
dialog.Dialog.Close,
|
|
1128
|
+
{
|
|
1129
|
+
"data-slot": "dialog-close",
|
|
1130
|
+
className: cn(
|
|
1131
|
+
"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",
|
|
1132
|
+
className
|
|
1133
|
+
),
|
|
1134
|
+
...props
|
|
1135
|
+
}
|
|
1136
|
+
);
|
|
1137
|
+
}
|
|
1138
|
+
function DialogHeader({
|
|
1139
|
+
className,
|
|
1140
|
+
...props
|
|
1141
|
+
}) {
|
|
1142
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1143
|
+
"div",
|
|
1144
|
+
{
|
|
1145
|
+
"data-slot": "dialog-header",
|
|
1146
|
+
className: cn(
|
|
1147
|
+
"flex flex-col space-y-1.5 text-center sm:text-left",
|
|
1148
|
+
className
|
|
1149
|
+
),
|
|
1150
|
+
...props
|
|
1151
|
+
}
|
|
1152
|
+
);
|
|
1153
|
+
}
|
|
1154
|
+
function DialogTitle({
|
|
1155
|
+
className,
|
|
1156
|
+
...props
|
|
1157
|
+
}) {
|
|
1158
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1159
|
+
dialog.Dialog.Title,
|
|
1160
|
+
{
|
|
1161
|
+
"data-slot": "dialog-title",
|
|
1162
|
+
className: cn(
|
|
1163
|
+
"text-lg font-semibold leading-none tracking-tight",
|
|
1164
|
+
className
|
|
1165
|
+
),
|
|
1166
|
+
...props
|
|
1167
|
+
}
|
|
1168
|
+
);
|
|
1169
|
+
}
|
|
1170
|
+
function DialogDescription({
|
|
1171
|
+
className,
|
|
1172
|
+
...props
|
|
1173
|
+
}) {
|
|
1174
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1175
|
+
dialog.Dialog.Description,
|
|
1176
|
+
{
|
|
1177
|
+
"data-slot": "dialog-description",
|
|
1178
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
1179
|
+
...props
|
|
1180
|
+
}
|
|
1181
|
+
);
|
|
1182
|
+
}
|
|
1183
|
+
var Image = ({
|
|
1184
|
+
src,
|
|
1185
|
+
alt,
|
|
1186
|
+
size = "sm",
|
|
1187
|
+
className,
|
|
1188
|
+
style
|
|
1189
|
+
}) => {
|
|
1190
|
+
const [hasError, setHasError] = React11.useState(false);
|
|
1191
|
+
const [isLoading, setIsLoading] = React11.useState(true);
|
|
1192
|
+
const [open, setOpen] = React11.useState(false);
|
|
1193
|
+
const sizes = {
|
|
1194
|
+
sm: "h-11",
|
|
1195
|
+
md: "h-22",
|
|
1196
|
+
lg: "h-44"
|
|
1197
|
+
};
|
|
1198
|
+
const handleError = () => {
|
|
1199
|
+
setHasError(true);
|
|
1200
|
+
setIsLoading(false);
|
|
1201
|
+
};
|
|
1202
|
+
const handleLoad = () => {
|
|
1203
|
+
setIsLoading(false);
|
|
1204
|
+
};
|
|
1205
|
+
if (hasError) {
|
|
1206
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1207
|
+
"div",
|
|
1208
|
+
{
|
|
742
1209
|
className: cn(
|
|
743
1210
|
"flex items-center justify-center rounded-md border bg-muted text-muted-foreground",
|
|
744
1211
|
sizes[size] || "h-11 w-11",
|
|
@@ -749,22 +1216,67 @@ var Image = ({
|
|
|
749
1216
|
}
|
|
750
1217
|
);
|
|
751
1218
|
}
|
|
752
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1219
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Dialog, { open, onOpenChange: setOpen, children: [
|
|
1220
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogTrigger, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1221
|
+
"div",
|
|
1222
|
+
{
|
|
1223
|
+
className: cn("relative overflow-hidden rounded-md border cursor-pointer", className),
|
|
1224
|
+
style,
|
|
1225
|
+
children: [
|
|
1226
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1227
|
+
"img",
|
|
1228
|
+
{
|
|
1229
|
+
src,
|
|
1230
|
+
alt,
|
|
1231
|
+
onError: handleError,
|
|
1232
|
+
onLoad: handleLoad,
|
|
1233
|
+
className: cn(
|
|
1234
|
+
"block h-auto w-full transition-opacity duration-200 hover:opacity-90",
|
|
1235
|
+
isLoading ? "opacity-0" : "opacity-100",
|
|
1236
|
+
sizes[size]
|
|
1237
|
+
)
|
|
1238
|
+
}
|
|
1239
|
+
),
|
|
1240
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-muted animate-pulse" })
|
|
1241
|
+
]
|
|
1242
|
+
}
|
|
1243
|
+
) }),
|
|
753
1244
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
754
|
-
|
|
1245
|
+
DialogContent,
|
|
755
1246
|
{
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
1247
|
+
className: "max-w-[90vw] max-h-[90vh] p-0 bg-transparent border-none shadow-none",
|
|
1248
|
+
onClick: (e) => e.stopPropagation(),
|
|
1249
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-center justify-center", children: [
|
|
1250
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogClose, { className: "absolute -top-10 right-0 text-white hover:text-gray-300 transition-colors z-10 bg-black/50 rounded-full p-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1251
|
+
"svg",
|
|
1252
|
+
{
|
|
1253
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1254
|
+
className: "h-5 w-5",
|
|
1255
|
+
fill: "none",
|
|
1256
|
+
viewBox: "0 0 24 24",
|
|
1257
|
+
stroke: "currentColor",
|
|
1258
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1259
|
+
"path",
|
|
1260
|
+
{
|
|
1261
|
+
strokeLinecap: "round",
|
|
1262
|
+
strokeLinejoin: "round",
|
|
1263
|
+
strokeWidth: 2,
|
|
1264
|
+
d: "M6 18L18 6M6 6l12 12"
|
|
1265
|
+
}
|
|
1266
|
+
)
|
|
1267
|
+
}
|
|
1268
|
+
) }),
|
|
1269
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1270
|
+
"img",
|
|
1271
|
+
{
|
|
1272
|
+
src,
|
|
1273
|
+
alt: alt || "Enlarged image",
|
|
1274
|
+
className: "max-w-full max-h-[90vh] object-contain rounded-lg"
|
|
1275
|
+
}
|
|
1276
|
+
)
|
|
1277
|
+
] })
|
|
765
1278
|
}
|
|
766
|
-
)
|
|
767
|
-
isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-muted animate-pulse" })
|
|
1279
|
+
)
|
|
768
1280
|
] });
|
|
769
1281
|
};
|
|
770
1282
|
var Icon = ({
|
|
@@ -875,7 +1387,7 @@ var Chart = ({
|
|
|
875
1387
|
className,
|
|
876
1388
|
style
|
|
877
1389
|
}) => {
|
|
878
|
-
const [tooltip, setTooltip] =
|
|
1390
|
+
const [tooltip, setTooltip] = React11.useState(null);
|
|
879
1391
|
if (!Array.isArray(data)) {
|
|
880
1392
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-destructive border border-destructive/20 rounded-md bg-destructive/5", children: "Error: Chart data must be an array" });
|
|
881
1393
|
}
|
|
@@ -1220,19 +1732,6 @@ var Input2 = ({
|
|
|
1220
1732
|
)
|
|
1221
1733
|
] });
|
|
1222
1734
|
};
|
|
1223
|
-
function Textarea({ className, ...props }) {
|
|
1224
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1225
|
-
"textarea",
|
|
1226
|
-
{
|
|
1227
|
-
"data-slot": "textarea",
|
|
1228
|
-
className: cn(
|
|
1229
|
-
"border-input bg-input/30 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 resize-none rounded-xl border px-3 py-3 text-base transition-colors focus-visible:ring-[3px] aria-invalid:ring-[3px] md:text-sm placeholder:text-muted-foreground flex field-sizing-content min-h-16 w-full outline-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
1230
|
-
className
|
|
1231
|
-
),
|
|
1232
|
-
...props
|
|
1233
|
-
}
|
|
1234
|
-
);
|
|
1235
|
-
}
|
|
1236
1735
|
var Textarea2 = ({
|
|
1237
1736
|
placeholder,
|
|
1238
1737
|
defaultValue,
|
|
@@ -1604,50 +2103,6 @@ var RadioGroup = ({
|
|
|
1604
2103
|
)
|
|
1605
2104
|
] });
|
|
1606
2105
|
};
|
|
1607
|
-
var buttonVariants = classVarianceAuthority.cva(
|
|
1608
|
-
"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",
|
|
1609
|
-
{
|
|
1610
|
-
variants: {
|
|
1611
|
-
variant: {
|
|
1612
|
-
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
|
1613
|
-
outline: "border-border bg-input/30 hover:bg-input/50 hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
1614
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
|
1615
|
-
ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
1616
|
-
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",
|
|
1617
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
1618
|
-
},
|
|
1619
|
-
size: {
|
|
1620
|
-
default: "h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5",
|
|
1621
|
-
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",
|
|
1622
|
-
sm: "h-8 gap-1 px-3 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
1623
|
-
lg: "h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
|
|
1624
|
-
icon: "size-9",
|
|
1625
|
-
"icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
|
|
1626
|
-
"icon-sm": "size-8",
|
|
1627
|
-
"icon-lg": "size-10"
|
|
1628
|
-
}
|
|
1629
|
-
},
|
|
1630
|
-
defaultVariants: {
|
|
1631
|
-
variant: "default",
|
|
1632
|
-
size: "default"
|
|
1633
|
-
}
|
|
1634
|
-
}
|
|
1635
|
-
);
|
|
1636
|
-
function Button({
|
|
1637
|
-
className,
|
|
1638
|
-
variant = "default",
|
|
1639
|
-
size = "default",
|
|
1640
|
-
...props
|
|
1641
|
-
}) {
|
|
1642
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1643
|
-
button.Button,
|
|
1644
|
-
{
|
|
1645
|
-
"data-slot": "button",
|
|
1646
|
-
className: cn(buttonVariants({ variant, size, className })),
|
|
1647
|
-
...props
|
|
1648
|
-
}
|
|
1649
|
-
);
|
|
1650
|
-
}
|
|
1651
2106
|
var Button2 = ({
|
|
1652
2107
|
label,
|
|
1653
2108
|
variant = "primary",
|
|
@@ -1664,6 +2119,8 @@ var Button2 = ({
|
|
|
1664
2119
|
secondary: "secondary",
|
|
1665
2120
|
danger: "destructive",
|
|
1666
2121
|
outline: "outline",
|
|
2122
|
+
ghost: "ghost",
|
|
2123
|
+
link: "link",
|
|
1667
2124
|
success: "default"
|
|
1668
2125
|
// Success doesn't have a direct shadcn mapping in base variant, default is usually primary
|
|
1669
2126
|
};
|
|
@@ -1686,7 +2143,7 @@ var Button2 = ({
|
|
|
1686
2143
|
};
|
|
1687
2144
|
var Form = ({ children, onSubmitAction, className, style }) => {
|
|
1688
2145
|
const { sendEvent } = useMelony();
|
|
1689
|
-
const [isSubmitted, setIsSubmitted] =
|
|
2146
|
+
const [isSubmitted, setIsSubmitted] = React11.useState(false);
|
|
1690
2147
|
const handleSubmit = (e) => {
|
|
1691
2148
|
e.preventDefault();
|
|
1692
2149
|
if (isSubmitted) return;
|
|
@@ -1732,6 +2189,32 @@ var Form = ({ children, onSubmitAction, className, style }) => {
|
|
|
1732
2189
|
}
|
|
1733
2190
|
);
|
|
1734
2191
|
};
|
|
2192
|
+
function StarterPrompts({
|
|
2193
|
+
prompts,
|
|
2194
|
+
onPromptClick
|
|
2195
|
+
}) {
|
|
2196
|
+
if (!prompts || prompts.length === 0) {
|
|
2197
|
+
return null;
|
|
2198
|
+
}
|
|
2199
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col space-y-4 animate-in fade-in slide-in-from-bottom-4 duration-500 mt-auto max-w-2xl", children: [
|
|
2200
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold tracking-tight", children: "What can I help with today?" }) }),
|
|
2201
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2 w-full", children: prompts.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2202
|
+
Button2,
|
|
2203
|
+
{
|
|
2204
|
+
label: item.label,
|
|
2205
|
+
variant: "ghost",
|
|
2206
|
+
size: "lg",
|
|
2207
|
+
onClickAction: {
|
|
2208
|
+
type: "text",
|
|
2209
|
+
role: "user",
|
|
2210
|
+
data: { content: item.prompt }
|
|
2211
|
+
},
|
|
2212
|
+
className: "w-full justify-start"
|
|
2213
|
+
},
|
|
2214
|
+
index
|
|
2215
|
+
)) })
|
|
2216
|
+
] });
|
|
2217
|
+
}
|
|
1735
2218
|
function UIRenderer({ node }) {
|
|
1736
2219
|
const { type, props, children } = node;
|
|
1737
2220
|
const typeMap = {
|
|
@@ -1770,69 +2253,108 @@ function UIRenderer({ node }) {
|
|
|
1770
2253
|
const componentProps = { ...props };
|
|
1771
2254
|
return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...componentProps, children: renderedChildren });
|
|
1772
2255
|
}
|
|
1773
|
-
function
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
placeholder = "Type a message...",
|
|
1778
|
-
isLoading,
|
|
1779
|
-
className
|
|
1780
|
-
}) {
|
|
1781
|
-
const handleKeyDown = (e) => {
|
|
1782
|
-
if (e.key === "Enter" && !e.shiftKey) {
|
|
1783
|
-
e.preventDefault();
|
|
1784
|
-
onSubmit();
|
|
2256
|
+
function MessageContent({ events }) {
|
|
2257
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: events.map((event, index) => {
|
|
2258
|
+
if (event.type === "text-delta") {
|
|
2259
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { children: event.data?.delta }, index);
|
|
1785
2260
|
}
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
{
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
2261
|
+
if (event.type === "text") {
|
|
2262
|
+
return /* @__PURE__ */ jsxRuntime.jsx("p", { children: event.data?.content || event.data?.text }, index);
|
|
2263
|
+
}
|
|
2264
|
+
if (event.ui) {
|
|
2265
|
+
return /* @__PURE__ */ jsxRuntime.jsx(UIRenderer, { node: event.ui }, index);
|
|
2266
|
+
}
|
|
2267
|
+
return null;
|
|
2268
|
+
}) });
|
|
2269
|
+
}
|
|
2270
|
+
function MessageBubble({ message }) {
|
|
2271
|
+
const isUser = message.role === "user";
|
|
2272
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2273
|
+
"div",
|
|
2274
|
+
{
|
|
2275
|
+
className: cn(
|
|
2276
|
+
"flex flex-col",
|
|
2277
|
+
isUser ? "items-end" : "items-start"
|
|
2278
|
+
),
|
|
2279
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2280
|
+
"div",
|
|
2281
|
+
{
|
|
2282
|
+
className: cn(
|
|
2283
|
+
"flex flex-col items-start max-w-[85%] rounded-2xl px-4 py-2 space-y-4 whitespace-pre-wrap",
|
|
2284
|
+
isUser ? "bg-primary text-primary-foreground" : "px-0 py-0 text-foreground"
|
|
2285
|
+
),
|
|
2286
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(MessageContent, { events: message.content })
|
|
2287
|
+
}
|
|
2288
|
+
)
|
|
2289
|
+
}
|
|
2290
|
+
);
|
|
2291
|
+
}
|
|
2292
|
+
function LoadingIndicator({ status }) {
|
|
2293
|
+
const [isExpanded, setIsExpanded] = React11.useState(false);
|
|
2294
|
+
const message = status?.message || "Processing...";
|
|
2295
|
+
const details = status?.details;
|
|
2296
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
2297
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-muted-foreground group", children: [
|
|
2298
|
+
/* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLoader2, { className: "size-3.5 animate-spin" }),
|
|
2299
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-pulse", children: message }),
|
|
2300
|
+
details && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2301
|
+
"button",
|
|
2302
|
+
{
|
|
2303
|
+
onClick: () => setIsExpanded(!isExpanded),
|
|
2304
|
+
className: "p-0.5 hover:bg-muted rounded-sm transition-colors flex items-center justify-center",
|
|
2305
|
+
title: isExpanded ? "Hide details" : "Show details",
|
|
2306
|
+
children: isExpanded ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronUp, { className: "size-3.5 opacity-50 group-hover:opacity-100" }) : /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronDown, { className: "size-3.5 opacity-50 group-hover:opacity-100" })
|
|
2307
|
+
}
|
|
2308
|
+
)
|
|
2309
|
+
] }),
|
|
2310
|
+
isExpanded && details && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] leading-relaxed font-mono bg-muted/30 p-2.5 rounded border border-border/50 max-h-64 overflow-y-auto whitespace-pre-wrap text-muted-foreground shadow-sm", children: details })
|
|
2311
|
+
] });
|
|
2312
|
+
}
|
|
2313
|
+
function ErrorDisplay({ error }) {
|
|
2314
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-destructive p-2 border border-destructive rounded-md bg-destructive/10", children: error.message });
|
|
2315
|
+
}
|
|
2316
|
+
function MessageList({ messages, isLoading, error, loadingStatus }) {
|
|
2317
|
+
if (messages.length === 0) {
|
|
2318
|
+
return null;
|
|
2319
|
+
}
|
|
2320
|
+
const isTextStreaming = React11.useMemo(() => {
|
|
2321
|
+
if (messages.length === 0 || !isLoading) return false;
|
|
2322
|
+
const lastMessage = messages[messages.length - 1];
|
|
2323
|
+
return lastMessage.content.some((event) => event.type === "text-delta");
|
|
2324
|
+
}, [messages, isLoading]);
|
|
2325
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
2326
|
+
messages.map((message, index) => /* @__PURE__ */ jsxRuntime.jsx(MessageBubble, { message }, index)),
|
|
2327
|
+
isLoading && !isTextStreaming && /* @__PURE__ */ jsxRuntime.jsx(LoadingIndicator, { status: loadingStatus }),
|
|
2328
|
+
error && /* @__PURE__ */ jsxRuntime.jsx(ErrorDisplay, { error })
|
|
2329
|
+
] });
|
|
1813
2330
|
}
|
|
1814
2331
|
function Thread({
|
|
1815
2332
|
className,
|
|
1816
2333
|
placeholder = "Type a message...",
|
|
1817
2334
|
starterPrompts,
|
|
1818
|
-
onStarterPromptClick
|
|
2335
|
+
onStarterPromptClick,
|
|
2336
|
+
options,
|
|
2337
|
+
autoFocus = false,
|
|
2338
|
+
defaultSelectedIds
|
|
1819
2339
|
}) {
|
|
1820
|
-
const { messages, isLoading, error, sendEvent } = useMelony();
|
|
1821
|
-
const [input, setInput] =
|
|
1822
|
-
const messagesEndRef =
|
|
1823
|
-
|
|
2340
|
+
const { messages, isLoading, error, sendEvent, loadingStatus } = useMelony();
|
|
2341
|
+
const [input, setInput] = React11.useState("");
|
|
2342
|
+
const messagesEndRef = React11.useRef(null);
|
|
2343
|
+
React11.useEffect(() => {
|
|
1824
2344
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
1825
2345
|
}, [messages]);
|
|
1826
|
-
const handleSubmit = async (
|
|
1827
|
-
e?.preventDefault();
|
|
2346
|
+
const handleSubmit = async (state, overrideInput) => {
|
|
1828
2347
|
const text = (overrideInput ?? input).trim();
|
|
1829
2348
|
if (!text || isLoading) return;
|
|
1830
2349
|
if (!overrideInput) setInput("");
|
|
1831
|
-
await sendEvent(
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
2350
|
+
await sendEvent(
|
|
2351
|
+
{
|
|
2352
|
+
type: "text",
|
|
2353
|
+
role: "user",
|
|
2354
|
+
data: { content: text }
|
|
2355
|
+
},
|
|
2356
|
+
{ state }
|
|
2357
|
+
);
|
|
1836
2358
|
};
|
|
1837
2359
|
const handleStarterPromptClick = (prompt) => {
|
|
1838
2360
|
if (onStarterPromptClick) {
|
|
@@ -1841,66 +2363,73 @@ function Thread({
|
|
|
1841
2363
|
handleSubmit(void 0, prompt);
|
|
1842
2364
|
}
|
|
1843
2365
|
};
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
2366
|
+
const showStarterPrompts = messages.length === 0 && starterPrompts && starterPrompts.length > 0;
|
|
2367
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2368
|
+
"div",
|
|
2369
|
+
{
|
|
2370
|
+
className: cn("relative flex flex-col h-full bg-background", className),
|
|
2371
|
+
children: [
|
|
2372
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto p-4 pb-36", children: [
|
|
2373
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2374
|
+
"div",
|
|
1851
2375
|
{
|
|
1852
|
-
|
|
1853
|
-
|
|
2376
|
+
className: cn(
|
|
2377
|
+
"max-w-4xl mx-auto w-full p-4",
|
|
2378
|
+
showStarterPrompts && "min-h-full flex flex-col"
|
|
2379
|
+
),
|
|
1854
2380
|
children: [
|
|
1855
|
-
|
|
1856
|
-
|
|
2381
|
+
showStarterPrompts && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2382
|
+
StarterPrompts,
|
|
2383
|
+
{
|
|
2384
|
+
prompts: starterPrompts,
|
|
2385
|
+
onPromptClick: handleStarterPromptClick
|
|
2386
|
+
}
|
|
2387
|
+
),
|
|
2388
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2389
|
+
MessageList,
|
|
2390
|
+
{
|
|
2391
|
+
messages,
|
|
2392
|
+
isLoading,
|
|
2393
|
+
error,
|
|
2394
|
+
loadingStatus
|
|
2395
|
+
}
|
|
2396
|
+
)
|
|
1857
2397
|
]
|
|
1858
|
-
}
|
|
1859
|
-
|
|
1860
|
-
|
|
2398
|
+
}
|
|
2399
|
+
),
|
|
2400
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: messagesEndRef })
|
|
1861
2401
|
] }),
|
|
1862
|
-
|
|
1863
|
-
|
|
2402
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 p-4 w-full", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-4xl mx-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2403
|
+
Composer,
|
|
1864
2404
|
{
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
] }),
|
|
1894
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 border-t w-full", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-4xl mx-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1895
|
-
Composer,
|
|
1896
|
-
{
|
|
1897
|
-
value: input,
|
|
1898
|
-
onChange: setInput,
|
|
1899
|
-
onSubmit: handleSubmit,
|
|
1900
|
-
placeholder,
|
|
1901
|
-
isLoading
|
|
1902
|
-
}
|
|
1903
|
-
) }) })
|
|
2405
|
+
value: input,
|
|
2406
|
+
onChange: setInput,
|
|
2407
|
+
onSubmit: handleSubmit,
|
|
2408
|
+
placeholder,
|
|
2409
|
+
isLoading,
|
|
2410
|
+
options,
|
|
2411
|
+
autoFocus,
|
|
2412
|
+
defaultSelectedIds
|
|
2413
|
+
}
|
|
2414
|
+
) }) })
|
|
2415
|
+
]
|
|
2416
|
+
}
|
|
2417
|
+
);
|
|
2418
|
+
}
|
|
2419
|
+
function ChatHeader({
|
|
2420
|
+
title,
|
|
2421
|
+
leftContent,
|
|
2422
|
+
rightContent,
|
|
2423
|
+
className,
|
|
2424
|
+
titleClassName,
|
|
2425
|
+
children
|
|
2426
|
+
}) {
|
|
2427
|
+
if (children) {
|
|
2428
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("p-4 border-b border-border h-14 flex items-center shrink-0", className), children });
|
|
2429
|
+
}
|
|
2430
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("p-4 border-b border-border h-14 flex items-center justify-between shrink-0", className), children: [
|
|
2431
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: leftContent }),
|
|
2432
|
+
rightContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 shrink-0 ml-2", children: rightContent })
|
|
1904
2433
|
] });
|
|
1905
2434
|
}
|
|
1906
2435
|
var ThreadList = ({
|
|
@@ -1908,13 +2437,7 @@ var ThreadList = ({
|
|
|
1908
2437
|
emptyState,
|
|
1909
2438
|
onThreadSelect
|
|
1910
2439
|
}) => {
|
|
1911
|
-
const {
|
|
1912
|
-
threads,
|
|
1913
|
-
activeThreadId,
|
|
1914
|
-
selectThread,
|
|
1915
|
-
createThread,
|
|
1916
|
-
deleteThread
|
|
1917
|
-
} = useThreads();
|
|
2440
|
+
const { threads, activeThreadId, selectThread, createThread, deleteThread } = useThreads();
|
|
1918
2441
|
const handleThreadClick = (threadId) => {
|
|
1919
2442
|
if (threadId !== activeThreadId) {
|
|
1920
2443
|
selectThread(threadId);
|
|
@@ -1952,10 +2475,10 @@ var ThreadList = ({
|
|
|
1952
2475
|
return d.toLocaleDateString();
|
|
1953
2476
|
};
|
|
1954
2477
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full", className), children: [
|
|
1955
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2
|
|
2478
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1956
2479
|
Button,
|
|
1957
2480
|
{
|
|
1958
|
-
variant: "
|
|
2481
|
+
variant: "ghost",
|
|
1959
2482
|
size: "sm",
|
|
1960
2483
|
onClick: handleNewThread,
|
|
1961
2484
|
className: "w-full justify-start",
|
|
@@ -1976,31 +2499,13 @@ var ThreadList = ({
|
|
|
1976
2499
|
{
|
|
1977
2500
|
onClick: () => handleThreadClick(thread.id),
|
|
1978
2501
|
className: cn(
|
|
1979
|
-
"group relative flex items-center gap-3
|
|
1980
|
-
isActive ? "bg-
|
|
2502
|
+
"group relative flex items-center gap-3 px-3 py-1.5 rounded-lg cursor-pointer transition-colors",
|
|
2503
|
+
isActive ? "bg-muted" : "hover:bg-muted"
|
|
1981
2504
|
),
|
|
1982
2505
|
children: [
|
|
1983
2506
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1984
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1985
|
-
|
|
1986
|
-
{
|
|
1987
|
-
className: cn(
|
|
1988
|
-
"text-sm font-medium truncate",
|
|
1989
|
-
isActive && "text-primary-foreground"
|
|
1990
|
-
),
|
|
1991
|
-
children: thread.title || `Thread ${thread.id.slice(0, 8)}`
|
|
1992
|
-
}
|
|
1993
|
-
),
|
|
1994
|
-
thread.updatedAt && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1995
|
-
"span",
|
|
1996
|
-
{
|
|
1997
|
-
className: cn(
|
|
1998
|
-
"text-xs shrink-0",
|
|
1999
|
-
isActive ? "text-primary-foreground/70" : "text-muted-foreground"
|
|
2000
|
-
),
|
|
2001
|
-
children: formatDate(thread.updatedAt)
|
|
2002
|
-
}
|
|
2003
|
-
)
|
|
2507
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-sm font-medium truncate"), children: thread.title || `Thread ${thread.id.slice(0, 8)}` }),
|
|
2508
|
+
thread.updatedAt && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-xs shrink-0"), children: formatDate(thread.updatedAt) })
|
|
2004
2509
|
] }) }),
|
|
2005
2510
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2006
2511
|
Button,
|
|
@@ -2026,10 +2531,13 @@ function ChatPopup({
|
|
|
2026
2531
|
title = "Chat",
|
|
2027
2532
|
placeholder = "Message the AI",
|
|
2028
2533
|
starterPrompts,
|
|
2029
|
-
|
|
2534
|
+
options,
|
|
2535
|
+
defaultOpen = false,
|
|
2536
|
+
headerProps,
|
|
2537
|
+
defaultSelectedIds
|
|
2030
2538
|
}) {
|
|
2031
|
-
const [isOpen, setIsOpen] =
|
|
2032
|
-
const [view, setView] =
|
|
2539
|
+
const [isOpen, setIsOpen] = React11.useState(defaultOpen);
|
|
2540
|
+
const [view, setView] = React11.useState("chat");
|
|
2033
2541
|
const { createThread } = useThreads();
|
|
2034
2542
|
const handleNewChat = async () => {
|
|
2035
2543
|
try {
|
|
@@ -2040,10 +2548,12 @@ function ChatPopup({
|
|
|
2040
2548
|
}
|
|
2041
2549
|
};
|
|
2042
2550
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fixed bottom-6 right-6 z-50 flex flex-col items-end gap-4 font-sans", children: [
|
|
2043
|
-
isOpen && /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "py-0 w-[440px] h-[640px] flex flex-col overflow-hidden border bg-background/95 backdrop-blur supports-backdrop-filter:bg-background/60 shadow-2xl animate-in fade-in zoom-in-95 duration-200 origin-bottom-right", children: [
|
|
2044
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2045
|
-
|
|
2046
|
-
|
|
2551
|
+
isOpen && /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "py-0 w-[440px] h-[640px] gap-0 flex flex-col overflow-hidden border bg-background/95 backdrop-blur supports-backdrop-filter:bg-background/60 shadow-2xl animate-in fade-in zoom-in-95 duration-200 origin-bottom-right", children: [
|
|
2552
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2553
|
+
ChatHeader,
|
|
2554
|
+
{
|
|
2555
|
+
title: view === "history" ? "History" : title,
|
|
2556
|
+
leftContent: view === "history" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2047
2557
|
Button,
|
|
2048
2558
|
{
|
|
2049
2559
|
variant: "ghost",
|
|
@@ -2052,50 +2562,52 @@ function ChatPopup({
|
|
|
2052
2562
|
className: "text-muted-foreground hover:text-foreground",
|
|
2053
2563
|
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconArrowLeft, { className: "size-4" })
|
|
2054
2564
|
}
|
|
2055
|
-
),
|
|
2056
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2565
|
+
) : void 0,
|
|
2566
|
+
rightContent: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2567
|
+
view === "chat" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2568
|
+
Button,
|
|
2569
|
+
{
|
|
2570
|
+
variant: "ghost",
|
|
2571
|
+
size: "icon-xs",
|
|
2572
|
+
onClick: () => setView("history"),
|
|
2573
|
+
className: "text-muted-foreground hover:text-foreground",
|
|
2574
|
+
title: "History",
|
|
2575
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconHistory, { className: "size-4" })
|
|
2576
|
+
}
|
|
2577
|
+
),
|
|
2578
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2579
|
+
Button,
|
|
2580
|
+
{
|
|
2581
|
+
variant: "ghost",
|
|
2582
|
+
size: "icon-xs",
|
|
2583
|
+
onClick: handleNewChat,
|
|
2584
|
+
className: "text-muted-foreground hover:text-foreground",
|
|
2585
|
+
title: "New Chat",
|
|
2586
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconPlus, { className: "size-4" })
|
|
2587
|
+
}
|
|
2588
|
+
),
|
|
2589
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2590
|
+
Button,
|
|
2591
|
+
{
|
|
2592
|
+
variant: "ghost",
|
|
2593
|
+
size: "icon-xs",
|
|
2594
|
+
onClick: () => setIsOpen(false),
|
|
2595
|
+
className: "text-muted-foreground hover:text-foreground",
|
|
2596
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconX, { className: "size-4" })
|
|
2597
|
+
}
|
|
2598
|
+
)
|
|
2599
|
+
] }),
|
|
2600
|
+
...headerProps
|
|
2601
|
+
}
|
|
2602
|
+
),
|
|
2093
2603
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden", children: view === "chat" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2094
2604
|
Thread,
|
|
2095
2605
|
{
|
|
2096
2606
|
placeholder,
|
|
2097
2607
|
starterPrompts,
|
|
2098
|
-
|
|
2608
|
+
options,
|
|
2609
|
+
className: "h-full",
|
|
2610
|
+
defaultSelectedIds
|
|
2099
2611
|
}
|
|
2100
2612
|
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2101
2613
|
ThreadList,
|
|
@@ -2123,16 +2635,21 @@ function ChatSidebar({
|
|
|
2123
2635
|
title = "Chat",
|
|
2124
2636
|
placeholder = "Message the AI",
|
|
2125
2637
|
starterPrompts,
|
|
2126
|
-
|
|
2638
|
+
options,
|
|
2639
|
+
className,
|
|
2640
|
+
headerProps,
|
|
2641
|
+
defaultSelectedIds
|
|
2127
2642
|
}) {
|
|
2128
2643
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full border-r bg-background w-80", className), children: [
|
|
2129
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2644
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChatHeader, { title, ...headerProps }),
|
|
2130
2645
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2131
2646
|
Thread,
|
|
2132
2647
|
{
|
|
2133
2648
|
placeholder,
|
|
2134
2649
|
starterPrompts,
|
|
2135
|
-
|
|
2650
|
+
options,
|
|
2651
|
+
className: "h-full",
|
|
2652
|
+
defaultSelectedIds
|
|
2136
2653
|
}
|
|
2137
2654
|
) })
|
|
2138
2655
|
] });
|
|
@@ -2141,13 +2658,437 @@ function ChatFull({
|
|
|
2141
2658
|
title = "Chat",
|
|
2142
2659
|
placeholder = "Message the AI",
|
|
2143
2660
|
starterPrompts,
|
|
2144
|
-
|
|
2661
|
+
options,
|
|
2662
|
+
className,
|
|
2663
|
+
headerProps,
|
|
2664
|
+
leftSidebar,
|
|
2665
|
+
rightSidebar,
|
|
2666
|
+
leftSidebarClassName,
|
|
2667
|
+
rightSidebarClassName,
|
|
2668
|
+
leftSidebarCollapsible = false,
|
|
2669
|
+
rightSidebarCollapsible = false,
|
|
2670
|
+
defaultLeftSidebarCollapsed = false,
|
|
2671
|
+
defaultRightSidebarCollapsed = false,
|
|
2672
|
+
leftSidebarCollapsed: controlledLeftCollapsed,
|
|
2673
|
+
rightSidebarCollapsed: controlledRightCollapsed,
|
|
2674
|
+
onLeftSidebarCollapseChange,
|
|
2675
|
+
onRightSidebarCollapseChange,
|
|
2676
|
+
autoFocus = false,
|
|
2677
|
+
defaultSelectedIds
|
|
2145
2678
|
}) {
|
|
2679
|
+
const [internalLeftCollapsed, setInternalLeftCollapsed] = React11.useState(
|
|
2680
|
+
defaultLeftSidebarCollapsed
|
|
2681
|
+
);
|
|
2682
|
+
const [internalRightCollapsed, setInternalRightCollapsed] = React11.useState(
|
|
2683
|
+
defaultRightSidebarCollapsed
|
|
2684
|
+
);
|
|
2685
|
+
const leftCollapsed = controlledLeftCollapsed !== void 0 ? controlledLeftCollapsed : internalLeftCollapsed;
|
|
2686
|
+
const rightCollapsed = controlledRightCollapsed !== void 0 ? controlledRightCollapsed : internalRightCollapsed;
|
|
2687
|
+
const handleLeftToggle = () => {
|
|
2688
|
+
const newCollapsed = !leftCollapsed;
|
|
2689
|
+
if (controlledLeftCollapsed === void 0) {
|
|
2690
|
+
setInternalLeftCollapsed(newCollapsed);
|
|
2691
|
+
}
|
|
2692
|
+
onLeftSidebarCollapseChange?.(newCollapsed);
|
|
2693
|
+
};
|
|
2694
|
+
const handleRightToggle = () => {
|
|
2695
|
+
const newCollapsed = !rightCollapsed;
|
|
2696
|
+
if (controlledRightCollapsed === void 0) {
|
|
2697
|
+
setInternalRightCollapsed(newCollapsed);
|
|
2698
|
+
}
|
|
2699
|
+
onRightSidebarCollapseChange?.(newCollapsed);
|
|
2700
|
+
};
|
|
2146
2701
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full w-full bg-background", className), children: [
|
|
2147
|
-
title && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2148
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2702
|
+
title && /* @__PURE__ */ jsxRuntime.jsx(ChatHeader, { title, ...headerProps }),
|
|
2703
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-hidden flex relative", children: [
|
|
2704
|
+
leftSidebar && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2705
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2706
|
+
"div",
|
|
2707
|
+
{
|
|
2708
|
+
className: cn(
|
|
2709
|
+
"flex-shrink-0 border-r border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
|
|
2710
|
+
leftCollapsed && leftSidebarCollapsible ? "w-0 border-r-0 min-w-0" : "",
|
|
2711
|
+
!leftCollapsed && leftSidebarClassName
|
|
2712
|
+
),
|
|
2713
|
+
children: !leftCollapsed && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2714
|
+
leftSidebarCollapsible && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end p-2 border-b border-border shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2715
|
+
Button,
|
|
2716
|
+
{
|
|
2717
|
+
variant: "ghost",
|
|
2718
|
+
size: "icon-sm",
|
|
2719
|
+
onClick: handleLeftToggle,
|
|
2720
|
+
"aria-label": "Collapse left sidebar",
|
|
2721
|
+
className: "h-8 w-8",
|
|
2722
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronLeft, { className: "h-4 w-4" })
|
|
2723
|
+
}
|
|
2724
|
+
) }),
|
|
2725
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: leftSidebar })
|
|
2726
|
+
] })
|
|
2727
|
+
}
|
|
2728
|
+
),
|
|
2729
|
+
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(
|
|
2730
|
+
Button,
|
|
2731
|
+
{
|
|
2732
|
+
variant: "ghost",
|
|
2733
|
+
size: "icon-sm",
|
|
2734
|
+
onClick: handleLeftToggle,
|
|
2735
|
+
"aria-label": "Expand left sidebar",
|
|
2736
|
+
className: "h-8 w-8",
|
|
2737
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronRight, { className: "h-4 w-4" })
|
|
2738
|
+
}
|
|
2739
|
+
) })
|
|
2740
|
+
] }),
|
|
2741
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2742
|
+
Thread,
|
|
2743
|
+
{
|
|
2744
|
+
placeholder,
|
|
2745
|
+
starterPrompts,
|
|
2746
|
+
options,
|
|
2747
|
+
autoFocus,
|
|
2748
|
+
defaultSelectedIds
|
|
2749
|
+
}
|
|
2750
|
+
) }),
|
|
2751
|
+
rightSidebar && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2752
|
+
rightSidebarCollapsible && rightCollapsed && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 border-l border-border bg-background flex items-center justify-center w-10", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2753
|
+
Button,
|
|
2754
|
+
{
|
|
2755
|
+
variant: "ghost",
|
|
2756
|
+
size: "icon-sm",
|
|
2757
|
+
onClick: handleRightToggle,
|
|
2758
|
+
"aria-label": "Expand right sidebar",
|
|
2759
|
+
className: "h-8 w-8",
|
|
2760
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronLeft, { className: "h-4 w-4" })
|
|
2761
|
+
}
|
|
2762
|
+
) }),
|
|
2763
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2764
|
+
"div",
|
|
2765
|
+
{
|
|
2766
|
+
className: cn(
|
|
2767
|
+
"flex-shrink-0 border-l border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
|
|
2768
|
+
rightCollapsed && rightSidebarCollapsible ? "w-0 border-l-0 min-w-0" : "",
|
|
2769
|
+
!rightCollapsed && rightSidebarClassName
|
|
2770
|
+
),
|
|
2771
|
+
children: !rightCollapsed && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2772
|
+
rightSidebarCollapsible && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-start p-2 border-b border-border shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2773
|
+
Button,
|
|
2774
|
+
{
|
|
2775
|
+
variant: "ghost",
|
|
2776
|
+
size: "icon-sm",
|
|
2777
|
+
onClick: handleRightToggle,
|
|
2778
|
+
"aria-label": "Collapse right sidebar",
|
|
2779
|
+
className: "h-8 w-8",
|
|
2780
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronRight, { className: "h-4 w-4" })
|
|
2781
|
+
}
|
|
2782
|
+
) }),
|
|
2783
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: rightSidebar })
|
|
2784
|
+
] })
|
|
2785
|
+
}
|
|
2786
|
+
)
|
|
2787
|
+
] })
|
|
2788
|
+
] })
|
|
2149
2789
|
] });
|
|
2150
2790
|
}
|
|
2791
|
+
var PopoverContext = React11__namespace.createContext(
|
|
2792
|
+
void 0
|
|
2793
|
+
);
|
|
2794
|
+
function usePopoverContext() {
|
|
2795
|
+
const context = React11__namespace.useContext(PopoverContext);
|
|
2796
|
+
if (!context) {
|
|
2797
|
+
throw new Error("Popover components must be used within a Popover");
|
|
2798
|
+
}
|
|
2799
|
+
return context;
|
|
2800
|
+
}
|
|
2801
|
+
function Popover({
|
|
2802
|
+
children,
|
|
2803
|
+
defaultOpen = false,
|
|
2804
|
+
open: controlledOpen,
|
|
2805
|
+
onOpenChange
|
|
2806
|
+
}) {
|
|
2807
|
+
const [internalOpen, setInternalOpen] = React11__namespace.useState(defaultOpen);
|
|
2808
|
+
const triggerRef = React11__namespace.useRef(null);
|
|
2809
|
+
const open = controlledOpen ?? internalOpen;
|
|
2810
|
+
const setOpen = React11__namespace.useCallback(
|
|
2811
|
+
(newOpen) => {
|
|
2812
|
+
if (controlledOpen === void 0) {
|
|
2813
|
+
setInternalOpen(newOpen);
|
|
2814
|
+
}
|
|
2815
|
+
onOpenChange?.(newOpen);
|
|
2816
|
+
},
|
|
2817
|
+
[controlledOpen, onOpenChange]
|
|
2818
|
+
);
|
|
2819
|
+
const value = React11__namespace.useMemo(
|
|
2820
|
+
() => ({
|
|
2821
|
+
open,
|
|
2822
|
+
setOpen,
|
|
2823
|
+
triggerRef
|
|
2824
|
+
}),
|
|
2825
|
+
[open, setOpen]
|
|
2826
|
+
);
|
|
2827
|
+
return /* @__PURE__ */ jsxRuntime.jsx(PopoverContext.Provider, { value, children });
|
|
2828
|
+
}
|
|
2829
|
+
var PopoverTrigger = React11__namespace.forwardRef(
|
|
2830
|
+
({ asChild, className, children, ...props }, ref) => {
|
|
2831
|
+
const { setOpen, triggerRef } = usePopoverContext();
|
|
2832
|
+
const handleClick = (e) => {
|
|
2833
|
+
setOpen(true);
|
|
2834
|
+
props.onClick?.(e);
|
|
2835
|
+
};
|
|
2836
|
+
if (asChild && React11__namespace.isValidElement(children)) {
|
|
2837
|
+
return React11__namespace.cloneElement(children, {
|
|
2838
|
+
ref: (node) => {
|
|
2839
|
+
triggerRef.current = node;
|
|
2840
|
+
if (typeof children.ref === "function") {
|
|
2841
|
+
children.ref(node);
|
|
2842
|
+
} else if (children.ref) {
|
|
2843
|
+
children.ref.current = node;
|
|
2844
|
+
}
|
|
2845
|
+
},
|
|
2846
|
+
onClick: handleClick
|
|
2847
|
+
});
|
|
2848
|
+
}
|
|
2849
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2850
|
+
"button",
|
|
2851
|
+
{
|
|
2852
|
+
ref: (node) => {
|
|
2853
|
+
triggerRef.current = node;
|
|
2854
|
+
if (typeof ref === "function") {
|
|
2855
|
+
ref(node);
|
|
2856
|
+
} else if (ref) {
|
|
2857
|
+
ref.current = node;
|
|
2858
|
+
}
|
|
2859
|
+
},
|
|
2860
|
+
className,
|
|
2861
|
+
onClick: handleClick,
|
|
2862
|
+
...props,
|
|
2863
|
+
children
|
|
2864
|
+
}
|
|
2865
|
+
);
|
|
2866
|
+
}
|
|
2867
|
+
);
|
|
2868
|
+
PopoverTrigger.displayName = "PopoverTrigger";
|
|
2869
|
+
var PopoverContent = React11__namespace.forwardRef(
|
|
2870
|
+
({
|
|
2871
|
+
className,
|
|
2872
|
+
side = "bottom",
|
|
2873
|
+
align = "start",
|
|
2874
|
+
sideOffset = 4,
|
|
2875
|
+
alignOffset = 0,
|
|
2876
|
+
children,
|
|
2877
|
+
...props
|
|
2878
|
+
}, ref) => {
|
|
2879
|
+
const { open, setOpen, triggerRef } = usePopoverContext();
|
|
2880
|
+
const [position, setPosition] = React11__namespace.useState({ top: 0, left: 0 });
|
|
2881
|
+
const contentRef = React11__namespace.useRef(null);
|
|
2882
|
+
React11__namespace.useEffect(() => {
|
|
2883
|
+
if (!open || !triggerRef.current) return;
|
|
2884
|
+
const updatePosition = () => {
|
|
2885
|
+
if (!triggerRef.current || !contentRef.current) return;
|
|
2886
|
+
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
2887
|
+
const contentRect = contentRef.current.getBoundingClientRect();
|
|
2888
|
+
const scrollX = window.scrollX;
|
|
2889
|
+
const scrollY = window.scrollY;
|
|
2890
|
+
let top = 0;
|
|
2891
|
+
let left = 0;
|
|
2892
|
+
switch (side) {
|
|
2893
|
+
case "bottom":
|
|
2894
|
+
top = triggerRect.bottom + sideOffset + scrollY;
|
|
2895
|
+
break;
|
|
2896
|
+
case "top":
|
|
2897
|
+
top = triggerRect.top - contentRect.height - sideOffset + scrollY;
|
|
2898
|
+
break;
|
|
2899
|
+
case "right":
|
|
2900
|
+
top = triggerRect.top + scrollY;
|
|
2901
|
+
left = triggerRect.right + sideOffset + scrollX;
|
|
2902
|
+
break;
|
|
2903
|
+
case "left":
|
|
2904
|
+
top = triggerRect.top + scrollY;
|
|
2905
|
+
left = triggerRect.left - contentRect.width - sideOffset + scrollX;
|
|
2906
|
+
break;
|
|
2907
|
+
}
|
|
2908
|
+
switch (align) {
|
|
2909
|
+
case "start":
|
|
2910
|
+
if (side === "top" || side === "bottom") {
|
|
2911
|
+
left = triggerRect.left + scrollX + alignOffset;
|
|
2912
|
+
} else {
|
|
2913
|
+
top += alignOffset;
|
|
2914
|
+
}
|
|
2915
|
+
break;
|
|
2916
|
+
case "center":
|
|
2917
|
+
if (side === "top" || side === "bottom") {
|
|
2918
|
+
left = triggerRect.left + triggerRect.width / 2 - contentRect.width / 2 + scrollX + alignOffset;
|
|
2919
|
+
} else {
|
|
2920
|
+
top += triggerRect.height / 2 - contentRect.height / 2 + alignOffset;
|
|
2921
|
+
}
|
|
2922
|
+
break;
|
|
2923
|
+
case "end":
|
|
2924
|
+
if (side === "top" || side === "bottom") {
|
|
2925
|
+
left = triggerRect.left + triggerRect.width - contentRect.width + scrollX + alignOffset;
|
|
2926
|
+
} else {
|
|
2927
|
+
top += triggerRect.height - contentRect.height + alignOffset;
|
|
2928
|
+
}
|
|
2929
|
+
break;
|
|
2930
|
+
}
|
|
2931
|
+
setPosition({ top, left });
|
|
2932
|
+
};
|
|
2933
|
+
requestAnimationFrame(() => {
|
|
2934
|
+
updatePosition();
|
|
2935
|
+
});
|
|
2936
|
+
window.addEventListener("resize", updatePosition);
|
|
2937
|
+
window.addEventListener("scroll", updatePosition, true);
|
|
2938
|
+
return () => {
|
|
2939
|
+
window.removeEventListener("resize", updatePosition);
|
|
2940
|
+
window.removeEventListener("scroll", updatePosition, true);
|
|
2941
|
+
};
|
|
2942
|
+
}, [open, side, align, sideOffset, alignOffset, triggerRef]);
|
|
2943
|
+
React11__namespace.useEffect(() => {
|
|
2944
|
+
if (!open) return;
|
|
2945
|
+
const handleClickOutside = (event) => {
|
|
2946
|
+
if (contentRef.current && !contentRef.current.contains(event.target) && triggerRef.current && !triggerRef.current.contains(event.target)) {
|
|
2947
|
+
setOpen(false);
|
|
2948
|
+
}
|
|
2949
|
+
};
|
|
2950
|
+
const handleEscape = (event) => {
|
|
2951
|
+
if (event.key === "Escape") {
|
|
2952
|
+
setOpen(false);
|
|
2953
|
+
}
|
|
2954
|
+
};
|
|
2955
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
2956
|
+
document.addEventListener("keydown", handleEscape);
|
|
2957
|
+
return () => {
|
|
2958
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
2959
|
+
document.removeEventListener("keydown", handleEscape);
|
|
2960
|
+
};
|
|
2961
|
+
}, [open, setOpen, triggerRef]);
|
|
2962
|
+
if (!open) return null;
|
|
2963
|
+
const content = /* @__PURE__ */ jsxRuntime.jsx(
|
|
2964
|
+
"div",
|
|
2965
|
+
{
|
|
2966
|
+
ref: (node) => {
|
|
2967
|
+
contentRef.current = node;
|
|
2968
|
+
if (typeof ref === "function") {
|
|
2969
|
+
ref(node);
|
|
2970
|
+
} else if (ref) {
|
|
2971
|
+
ref.current = node;
|
|
2972
|
+
}
|
|
2973
|
+
},
|
|
2974
|
+
className: cn(
|
|
2975
|
+
"bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 ring-foreground/5 rounded-2xl shadow-2xl ring-1 z-50 min-w-48 max-h-96 overflow-hidden",
|
|
2976
|
+
className
|
|
2977
|
+
),
|
|
2978
|
+
style: {
|
|
2979
|
+
position: "absolute",
|
|
2980
|
+
top: `${position.top}px`,
|
|
2981
|
+
left: `${position.left}px`
|
|
2982
|
+
},
|
|
2983
|
+
...props,
|
|
2984
|
+
children
|
|
2985
|
+
}
|
|
2986
|
+
);
|
|
2987
|
+
return reactDom.createPortal(content, document.body);
|
|
2988
|
+
}
|
|
2989
|
+
);
|
|
2990
|
+
PopoverContent.displayName = "PopoverContent";
|
|
2991
|
+
var ThreadPopover = ({
|
|
2992
|
+
className,
|
|
2993
|
+
buttonClassName,
|
|
2994
|
+
buttonVariant = "ghost",
|
|
2995
|
+
buttonSize = "icon",
|
|
2996
|
+
emptyState,
|
|
2997
|
+
onThreadSelect
|
|
2998
|
+
}) => {
|
|
2999
|
+
const [isOpen, setIsOpen] = React11__namespace.useState(false);
|
|
3000
|
+
reactHotkeysHook.useHotkeys(
|
|
3001
|
+
"h",
|
|
3002
|
+
(e) => {
|
|
3003
|
+
e.preventDefault();
|
|
3004
|
+
setIsOpen((prev) => !prev);
|
|
3005
|
+
},
|
|
3006
|
+
{
|
|
3007
|
+
enableOnFormTags: false,
|
|
3008
|
+
// Don't trigger when typing in form inputs
|
|
3009
|
+
enableOnContentEditable: false
|
|
3010
|
+
// Don't trigger in contenteditable elements
|
|
3011
|
+
}
|
|
3012
|
+
);
|
|
3013
|
+
const handleThreadSelect = (threadId) => {
|
|
3014
|
+
setIsOpen(false);
|
|
3015
|
+
onThreadSelect?.(threadId);
|
|
3016
|
+
};
|
|
3017
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [
|
|
3018
|
+
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3019
|
+
Button,
|
|
3020
|
+
{
|
|
3021
|
+
variant: buttonVariant,
|
|
3022
|
+
size: buttonSize,
|
|
3023
|
+
className: cn(buttonClassName),
|
|
3024
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconHistory, { className: "size-4" })
|
|
3025
|
+
}
|
|
3026
|
+
) }),
|
|
3027
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3028
|
+
PopoverContent,
|
|
3029
|
+
{
|
|
3030
|
+
className: cn("w-80 p-0", className),
|
|
3031
|
+
side: "bottom",
|
|
3032
|
+
align: "start",
|
|
3033
|
+
sideOffset: 8,
|
|
3034
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col h-[400px]", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3035
|
+
ThreadList,
|
|
3036
|
+
{
|
|
3037
|
+
emptyState,
|
|
3038
|
+
onThreadSelect: handleThreadSelect,
|
|
3039
|
+
className: "h-full"
|
|
3040
|
+
}
|
|
3041
|
+
) })
|
|
3042
|
+
}
|
|
3043
|
+
)
|
|
3044
|
+
] });
|
|
3045
|
+
};
|
|
3046
|
+
var CreateThreadButton = ({
|
|
3047
|
+
className,
|
|
3048
|
+
variant = "ghost",
|
|
3049
|
+
size = "icon",
|
|
3050
|
+
children,
|
|
3051
|
+
onThreadCreated
|
|
3052
|
+
}) => {
|
|
3053
|
+
const { createThread } = useThreads();
|
|
3054
|
+
const [isCreating, setIsCreating] = React11__namespace.useState(false);
|
|
3055
|
+
const handleCreateThread = async () => {
|
|
3056
|
+
if (isCreating) return;
|
|
3057
|
+
try {
|
|
3058
|
+
setIsCreating(true);
|
|
3059
|
+
const threadId = await createThread();
|
|
3060
|
+
onThreadCreated?.(threadId);
|
|
3061
|
+
} catch (error) {
|
|
3062
|
+
console.error("Failed to create thread:", error);
|
|
3063
|
+
} finally {
|
|
3064
|
+
setIsCreating(false);
|
|
3065
|
+
}
|
|
3066
|
+
};
|
|
3067
|
+
reactHotkeysHook.useHotkeys(
|
|
3068
|
+
"n",
|
|
3069
|
+
(e) => {
|
|
3070
|
+
e.preventDefault();
|
|
3071
|
+
handleCreateThread();
|
|
3072
|
+
},
|
|
3073
|
+
{
|
|
3074
|
+
enableOnFormTags: false,
|
|
3075
|
+
// Don't trigger when typing in form inputs
|
|
3076
|
+
enableOnContentEditable: false
|
|
3077
|
+
// Don't trigger in contenteditable elements
|
|
3078
|
+
}
|
|
3079
|
+
);
|
|
3080
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3081
|
+
Button,
|
|
3082
|
+
{
|
|
3083
|
+
variant,
|
|
3084
|
+
size,
|
|
3085
|
+
onClick: handleCreateThread,
|
|
3086
|
+
disabled: isCreating,
|
|
3087
|
+
className: cn(className),
|
|
3088
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconPlus, { className: "size-4" })
|
|
3089
|
+
}
|
|
3090
|
+
);
|
|
3091
|
+
};
|
|
2151
3092
|
function AlertDialog({ ...props }) {
|
|
2152
3093
|
return /* @__PURE__ */ jsxRuntime.jsx(alertDialog.AlertDialog.Root, { "data-slot": "alert-dialog", ...props });
|
|
2153
3094
|
}
|
|
@@ -2230,100 +3171,111 @@ function AlertDialogDescription({
|
|
|
2230
3171
|
}
|
|
2231
3172
|
);
|
|
2232
3173
|
}
|
|
2233
|
-
function DropdownMenu({ ...props }) {
|
|
2234
|
-
return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Root, { "data-slot": "dropdown-menu", ...props });
|
|
2235
|
-
}
|
|
2236
|
-
function DropdownMenuTrigger({ ...props }) {
|
|
2237
|
-
return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
2238
|
-
}
|
|
2239
|
-
function DropdownMenuContent({
|
|
2240
|
-
align = "start",
|
|
2241
|
-
alignOffset = 0,
|
|
2242
|
-
side = "bottom",
|
|
2243
|
-
sideOffset = 4,
|
|
2244
|
-
className,
|
|
2245
|
-
...props
|
|
2246
|
-
}) {
|
|
2247
|
-
return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2248
|
-
menu.Menu.Positioner,
|
|
2249
|
-
{
|
|
2250
|
-
className: "isolate z-50 outline-none",
|
|
2251
|
-
align,
|
|
2252
|
-
alignOffset,
|
|
2253
|
-
side,
|
|
2254
|
-
sideOffset,
|
|
2255
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2256
|
-
menu.Menu.Popup,
|
|
2257
|
-
{
|
|
2258
|
-
"data-slot": "dropdown-menu-content",
|
|
2259
|
-
className: cn("data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/5 bg-popover text-popover-foreground min-w-48 rounded-2xl p-1 shadow-2xl ring-1 duration-100 z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto outline-none data-closed:overflow-hidden", className),
|
|
2260
|
-
...props
|
|
2261
|
-
}
|
|
2262
|
-
)
|
|
2263
|
-
}
|
|
2264
|
-
) });
|
|
2265
|
-
}
|
|
2266
|
-
function DropdownMenuItem({
|
|
2267
|
-
className,
|
|
2268
|
-
inset,
|
|
2269
|
-
variant = "default",
|
|
2270
|
-
...props
|
|
2271
|
-
}) {
|
|
2272
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2273
|
-
menu.Menu.Item,
|
|
2274
|
-
{
|
|
2275
|
-
"data-slot": "dropdown-menu-item",
|
|
2276
|
-
"data-inset": inset,
|
|
2277
|
-
"data-variant": variant,
|
|
2278
|
-
className: cn(
|
|
2279
|
-
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2.5 rounded-xl px-3 py-2 text-sm [&_svg:not([class*='size-'])]:size-4 group/dropdown-menu-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
2280
|
-
className
|
|
2281
|
-
),
|
|
2282
|
-
...props
|
|
2283
|
-
}
|
|
2284
|
-
);
|
|
2285
|
-
}
|
|
2286
3174
|
var AccountDialog = ({
|
|
2287
3175
|
className,
|
|
2288
|
-
variant,
|
|
3176
|
+
variant = "outline",
|
|
2289
3177
|
size
|
|
2290
3178
|
}) => {
|
|
2291
|
-
const { isLoading, isAuthenticated, login, logout } = useAuth();
|
|
2292
|
-
const [open, setOpen] =
|
|
2293
|
-
const [
|
|
3179
|
+
const { isLoading, isAuthenticated, user, login, logout } = useAuth();
|
|
3180
|
+
const [open, setOpen] = React11__namespace.useState(false);
|
|
3181
|
+
const [accountInfoOpen, setAccountInfoOpen] = React11__namespace.useState(false);
|
|
3182
|
+
const [error, setError] = React11__namespace.useState(null);
|
|
3183
|
+
const initials = React11__namespace.useMemo(() => {
|
|
3184
|
+
const name = user?.displayName || user?.name;
|
|
3185
|
+
if (!name) return "";
|
|
3186
|
+
return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
|
|
3187
|
+
}, [user?.displayName, user?.name]);
|
|
2294
3188
|
const handleGoogleSignIn = async () => {
|
|
2295
3189
|
login();
|
|
2296
3190
|
};
|
|
2297
3191
|
if (isAuthenticated) {
|
|
2298
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2299
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
3192
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3193
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
|
|
3194
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3195
|
+
DropdownMenuTrigger,
|
|
3196
|
+
{
|
|
3197
|
+
render: (props) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3198
|
+
Button,
|
|
3199
|
+
{
|
|
3200
|
+
variant,
|
|
3201
|
+
size: "icon",
|
|
3202
|
+
...props,
|
|
3203
|
+
className: cn("rounded-full", className),
|
|
3204
|
+
children: user?.picture ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3205
|
+
"img",
|
|
3206
|
+
{
|
|
3207
|
+
src: user.picture,
|
|
3208
|
+
alt: user.displayName || user.name,
|
|
3209
|
+
className: "size-7 rounded-full object-cover"
|
|
3210
|
+
}
|
|
3211
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex size-7 items-center justify-center rounded-full bg-muted text-xs font-bold", children: initials || /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconUser, { className: "size-4" }) })
|
|
3212
|
+
}
|
|
3213
|
+
)
|
|
3214
|
+
}
|
|
3215
|
+
),
|
|
3216
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuContent, { align: "end", className: "w-56", children: [
|
|
3217
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 p-2", children: [
|
|
3218
|
+
user?.picture ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3219
|
+
"img",
|
|
3220
|
+
{
|
|
3221
|
+
src: user.picture,
|
|
3222
|
+
alt: user.displayName || user.name,
|
|
3223
|
+
className: "size-8 rounded-full object-cover"
|
|
3224
|
+
}
|
|
3225
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex size-8 items-center justify-center rounded-full bg-muted text-xs font-bold", children: initials || /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconUser, { className: "size-4" }) }),
|
|
3226
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col space-y-0.5 overflow-hidden", children: [
|
|
3227
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-sm font-medium", children: user?.displayName || user?.name }),
|
|
3228
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-xs text-muted-foreground", children: user?.email })
|
|
3229
|
+
] })
|
|
3230
|
+
] }),
|
|
3231
|
+
/* @__PURE__ */ jsxRuntime.jsx(Separator, { className: "my-1" }),
|
|
3232
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { onClick: () => setAccountInfoOpen(true), children: [
|
|
3233
|
+
/* @__PURE__ */ jsxRuntime.jsx(ICONS.IconUser, { className: "mr-2 size-4" }),
|
|
3234
|
+
"Account Settings"
|
|
3235
|
+
] }),
|
|
3236
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { onClick: logout, className: "text-destructive", children: [
|
|
3237
|
+
/* @__PURE__ */ jsxRuntime.jsx(ICONS.IconLogout, { className: "mr-2 size-4" }),
|
|
3238
|
+
"Logout"
|
|
3239
|
+
] })
|
|
3240
|
+
] })
|
|
3241
|
+
] }),
|
|
3242
|
+
/* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: accountInfoOpen, onOpenChange: setAccountInfoOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "sm:max-w-md", children: [
|
|
3243
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
|
|
3244
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Account Information" }),
|
|
3245
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Your account details and settings." })
|
|
2321
3246
|
] }),
|
|
2322
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2323
|
-
/* @__PURE__ */ jsxRuntime.jsx(ICONS.
|
|
2324
|
-
"
|
|
3247
|
+
/* @__PURE__ */ jsxRuntime.jsxs(DialogClose, { children: [
|
|
3248
|
+
/* @__PURE__ */ jsxRuntime.jsx(ICONS.IconX, { className: "size-4" }),
|
|
3249
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
|
|
3250
|
+
] }),
|
|
3251
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 py-4", children: [
|
|
3252
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
|
|
3253
|
+
user?.picture ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3254
|
+
"img",
|
|
3255
|
+
{
|
|
3256
|
+
src: user.picture,
|
|
3257
|
+
alt: user.displayName || user.name,
|
|
3258
|
+
className: "size-16 rounded-full object-cover"
|
|
3259
|
+
}
|
|
3260
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex size-16 items-center justify-center rounded-full bg-muted text-xl font-bold", children: initials || /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconUser, { className: "size-8 text-muted-foreground" }) }),
|
|
3261
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
3262
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold", children: user?.displayName || user?.name }),
|
|
3263
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: user?.email })
|
|
3264
|
+
] })
|
|
3265
|
+
] }),
|
|
3266
|
+
/* @__PURE__ */ jsxRuntime.jsx(Separator, {}),
|
|
3267
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
3268
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
3269
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-muted-foreground", children: "User ID" }),
|
|
3270
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-mono text-xs truncate", children: user?.uid || user?.id })
|
|
3271
|
+
] }),
|
|
3272
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
3273
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-muted-foreground", children: "Created At" }),
|
|
3274
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs", children: user?.createdAt || "N/A" })
|
|
3275
|
+
] })
|
|
3276
|
+
] })
|
|
2325
3277
|
] })
|
|
2326
|
-
] })
|
|
3278
|
+
] }) })
|
|
2327
3279
|
] });
|
|
2328
3280
|
}
|
|
2329
3281
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -2365,23 +3317,65 @@ var AccountDialog = ({
|
|
|
2365
3317
|
] }) })
|
|
2366
3318
|
] });
|
|
2367
3319
|
};
|
|
3320
|
+
function ThemeToggle() {
|
|
3321
|
+
const { theme, setTheme, resolvedTheme } = useTheme();
|
|
3322
|
+
const cycleTheme = () => {
|
|
3323
|
+
if (theme === "light") {
|
|
3324
|
+
setTheme("dark");
|
|
3325
|
+
} else if (theme === "dark") {
|
|
3326
|
+
setTheme("system");
|
|
3327
|
+
} else {
|
|
3328
|
+
setTheme("light");
|
|
3329
|
+
}
|
|
3330
|
+
};
|
|
3331
|
+
const getIcon = () => {
|
|
3332
|
+
if (theme === "system") {
|
|
3333
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconDeviceDesktop, { className: "h-4 w-4" });
|
|
3334
|
+
}
|
|
3335
|
+
return resolvedTheme === "dark" ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconMoon, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconSun, { className: "h-4 w-4" });
|
|
3336
|
+
};
|
|
3337
|
+
const getLabel = () => {
|
|
3338
|
+
if (theme === "system") {
|
|
3339
|
+
return "System";
|
|
3340
|
+
}
|
|
3341
|
+
return resolvedTheme === "dark" ? "Dark" : "Light";
|
|
3342
|
+
};
|
|
3343
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3344
|
+
Button,
|
|
3345
|
+
{
|
|
3346
|
+
variant: "ghost",
|
|
3347
|
+
size: "icon",
|
|
3348
|
+
onClick: cycleTheme,
|
|
3349
|
+
"aria-label": `Toggle theme (current: ${getLabel()})`,
|
|
3350
|
+
title: `Current: ${getLabel()}. Click to cycle: Light \u2192 Dark \u2192 System`,
|
|
3351
|
+
children: getIcon()
|
|
3352
|
+
}
|
|
3353
|
+
);
|
|
3354
|
+
}
|
|
2368
3355
|
|
|
2369
3356
|
exports.AccountDialog = AccountDialog;
|
|
2370
3357
|
exports.AuthContext = AuthContext;
|
|
2371
3358
|
exports.AuthProvider = AuthProvider;
|
|
2372
3359
|
exports.ChatFull = ChatFull;
|
|
3360
|
+
exports.ChatHeader = ChatHeader;
|
|
2373
3361
|
exports.ChatPopup = ChatPopup;
|
|
2374
3362
|
exports.ChatSidebar = ChatSidebar;
|
|
2375
3363
|
exports.Composer = Composer;
|
|
3364
|
+
exports.CreateThreadButton = CreateThreadButton;
|
|
2376
3365
|
exports.MelonyClientProvider = MelonyClientProvider;
|
|
2377
3366
|
exports.MelonyContext = MelonyContext;
|
|
3367
|
+
exports.ThemeProvider = ThemeProvider;
|
|
3368
|
+
exports.ThemeToggle = ThemeToggle;
|
|
2378
3369
|
exports.Thread = Thread;
|
|
2379
3370
|
exports.ThreadContext = ThreadContext;
|
|
2380
3371
|
exports.ThreadList = ThreadList;
|
|
3372
|
+
exports.ThreadPopover = ThreadPopover;
|
|
2381
3373
|
exports.ThreadProvider = ThreadProvider;
|
|
2382
3374
|
exports.UIRenderer = UIRenderer;
|
|
3375
|
+
exports.groupEventsToMessages = groupEventsToMessages;
|
|
2383
3376
|
exports.useAuth = useAuth;
|
|
2384
3377
|
exports.useMelony = useMelony;
|
|
3378
|
+
exports.useTheme = useTheme;
|
|
2385
3379
|
exports.useThreads = useThreads;
|
|
2386
3380
|
//# sourceMappingURL=index.cjs.map
|
|
2387
3381
|
//# sourceMappingURL=index.cjs.map
|