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