@melony/react 0.1.11 → 0.1.14
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 +564 -286
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +127 -15
- package/dist/index.d.ts +127 -15
- package/dist/index.js +520 -247
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React10 = 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 separator = require('@base-ui/react/separator');
|
|
10
12
|
var mergeProps = require('@base-ui/react/merge-props');
|
|
11
13
|
var useRender = require('@base-ui/react/use-render');
|
|
12
|
-
var classVarianceAuthority = require('class-variance-authority');
|
|
13
14
|
var input = require('@base-ui/react/input');
|
|
14
15
|
var select = require('@base-ui/react/select');
|
|
15
|
-
var button = require('@base-ui/react/button');
|
|
16
16
|
var alertDialog = require('@base-ui/react/alert-dialog');
|
|
17
17
|
var menu = require('@base-ui/react/menu');
|
|
18
18
|
|
|
@@ -34,13 +34,12 @@ function _interopNamespace(e) {
|
|
|
34
34
|
return Object.freeze(n);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
var
|
|
37
|
+
var React10__namespace = /*#__PURE__*/_interopNamespace(React10);
|
|
38
38
|
var ICONS__namespace = /*#__PURE__*/_interopNamespace(ICONS);
|
|
39
39
|
|
|
40
40
|
// src/providers/melony-provider.tsx
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
41
|
+
|
|
42
|
+
// src/lib/group-events-to-messages.ts
|
|
44
43
|
function groupEventsToMessages(events) {
|
|
45
44
|
if (events.length === 0) return [];
|
|
46
45
|
const messages = [];
|
|
@@ -64,21 +63,28 @@ function groupEventsToMessages(events) {
|
|
|
64
63
|
}
|
|
65
64
|
return messages;
|
|
66
65
|
}
|
|
67
|
-
var MelonyContext =
|
|
66
|
+
var MelonyContext = React10.createContext(
|
|
68
67
|
void 0
|
|
69
68
|
);
|
|
70
|
-
var
|
|
69
|
+
var MelonyClientProvider = ({
|
|
71
70
|
children,
|
|
72
|
-
client
|
|
71
|
+
client,
|
|
72
|
+
initialEvents
|
|
73
73
|
}) => {
|
|
74
|
-
const [state, setState] =
|
|
75
|
-
|
|
74
|
+
const [state, setState] = React10.useState(client.getState());
|
|
75
|
+
React10.useEffect(() => {
|
|
76
|
+
if (initialEvents && initialEvents.length > 0 && client.getState().events.length === 0) {
|
|
77
|
+
client.reset(initialEvents);
|
|
78
|
+
}
|
|
79
|
+
}, [client, initialEvents]);
|
|
80
|
+
React10.useEffect(() => {
|
|
76
81
|
setState(client.getState());
|
|
82
|
+
const unsubscribe = client.subscribe(setState);
|
|
77
83
|
return () => {
|
|
78
|
-
|
|
84
|
+
unsubscribe();
|
|
79
85
|
};
|
|
80
86
|
}, [client]);
|
|
81
|
-
const sendEvent =
|
|
87
|
+
const sendEvent = React10.useCallback(
|
|
82
88
|
async (event, options) => {
|
|
83
89
|
const generator = client.sendEvent(event, options);
|
|
84
90
|
for await (const _ of generator) {
|
|
@@ -86,29 +92,32 @@ var MelonyProvider = ({
|
|
|
86
92
|
},
|
|
87
93
|
[client]
|
|
88
94
|
);
|
|
89
|
-
const
|
|
90
|
-
|
|
95
|
+
const reset = React10.useCallback(
|
|
96
|
+
(events) => client.reset(events),
|
|
97
|
+
[client]
|
|
98
|
+
);
|
|
99
|
+
const value = React10.useMemo(
|
|
91
100
|
() => ({
|
|
92
101
|
...state,
|
|
93
102
|
messages: groupEventsToMessages(state.events),
|
|
94
103
|
sendEvent,
|
|
95
|
-
|
|
104
|
+
reset,
|
|
96
105
|
client
|
|
97
106
|
}),
|
|
98
|
-
[state, sendEvent,
|
|
107
|
+
[state, sendEvent, reset, client]
|
|
99
108
|
);
|
|
100
109
|
return /* @__PURE__ */ jsxRuntime.jsx(MelonyContext.Provider, { value, children });
|
|
101
110
|
};
|
|
102
|
-
var AuthContext =
|
|
111
|
+
var AuthContext = React10.createContext(
|
|
103
112
|
void 0
|
|
104
113
|
);
|
|
105
114
|
var AuthProvider = ({
|
|
106
115
|
children,
|
|
107
116
|
service
|
|
108
117
|
}) => {
|
|
109
|
-
const [user, setUser] =
|
|
110
|
-
const [isLoading, setIsLoading] =
|
|
111
|
-
const fetchMe =
|
|
118
|
+
const [user, setUser] = React10.useState(null);
|
|
119
|
+
const [isLoading, setIsLoading] = React10.useState(true);
|
|
120
|
+
const fetchMe = React10.useCallback(async () => {
|
|
112
121
|
setIsLoading(true);
|
|
113
122
|
try {
|
|
114
123
|
const userData = await service.getMe();
|
|
@@ -120,13 +129,13 @@ var AuthProvider = ({
|
|
|
120
129
|
setIsLoading(false);
|
|
121
130
|
}
|
|
122
131
|
}, [service]);
|
|
123
|
-
|
|
132
|
+
React10.useEffect(() => {
|
|
124
133
|
fetchMe();
|
|
125
134
|
}, [fetchMe]);
|
|
126
|
-
const login =
|
|
135
|
+
const login = React10.useCallback(() => {
|
|
127
136
|
service.login();
|
|
128
137
|
}, [service]);
|
|
129
|
-
const logout =
|
|
138
|
+
const logout = React10.useCallback(async () => {
|
|
130
139
|
try {
|
|
131
140
|
await service.logout();
|
|
132
141
|
setUser(null);
|
|
@@ -162,23 +171,25 @@ var AuthProvider = ({
|
|
|
162
171
|
}
|
|
163
172
|
return /* @__PURE__ */ jsxRuntime.jsx(AuthContext.Provider, { value, children });
|
|
164
173
|
};
|
|
165
|
-
var ThreadContext =
|
|
174
|
+
var ThreadContext = React10.createContext(
|
|
175
|
+
void 0
|
|
176
|
+
);
|
|
166
177
|
var ThreadProvider = ({
|
|
167
178
|
children,
|
|
168
179
|
service,
|
|
169
180
|
initialThreadId: providedInitialThreadId
|
|
170
181
|
}) => {
|
|
171
|
-
const defaultInitialThreadId =
|
|
182
|
+
const defaultInitialThreadId = React10.useMemo(() => client.generateId(), []);
|
|
172
183
|
const initialThreadId = providedInitialThreadId || defaultInitialThreadId;
|
|
173
|
-
const [threads, setThreads] =
|
|
174
|
-
const [activeThreadId, setActiveThreadId] =
|
|
184
|
+
const [threads, setThreads] = React10.useState([]);
|
|
185
|
+
const [activeThreadId, setActiveThreadId] = React10.useState(
|
|
175
186
|
initialThreadId
|
|
176
187
|
);
|
|
177
|
-
const [isLoading, setIsLoading] =
|
|
178
|
-
const [error, setError] =
|
|
179
|
-
const [threadEvents, setThreadEvents] =
|
|
180
|
-
const [isLoadingEvents, setIsLoadingEvents] =
|
|
181
|
-
const fetchThreads =
|
|
188
|
+
const [isLoading, setIsLoading] = React10.useState(true);
|
|
189
|
+
const [error, setError] = React10.useState(null);
|
|
190
|
+
const [threadEvents, setThreadEvents] = React10.useState([]);
|
|
191
|
+
const [isLoadingEvents, setIsLoadingEvents] = React10.useState(false);
|
|
192
|
+
const fetchThreads = React10.useCallback(async () => {
|
|
182
193
|
setIsLoading(true);
|
|
183
194
|
setError(null);
|
|
184
195
|
try {
|
|
@@ -192,13 +203,13 @@ var ThreadProvider = ({
|
|
|
192
203
|
setIsLoading(false);
|
|
193
204
|
}
|
|
194
205
|
}, [service]);
|
|
195
|
-
|
|
206
|
+
React10.useEffect(() => {
|
|
196
207
|
fetchThreads();
|
|
197
208
|
}, [fetchThreads]);
|
|
198
|
-
const selectThread =
|
|
209
|
+
const selectThread = React10.useCallback((threadId) => {
|
|
199
210
|
setActiveThreadId(threadId);
|
|
200
211
|
}, []);
|
|
201
|
-
const createThread =
|
|
212
|
+
const createThread = React10.useCallback(async () => {
|
|
202
213
|
const newId = service.createThread ? await service.createThread() : client.generateId();
|
|
203
214
|
const newThread = {
|
|
204
215
|
id: newId,
|
|
@@ -208,7 +219,7 @@ var ThreadProvider = ({
|
|
|
208
219
|
setActiveThreadId(newId);
|
|
209
220
|
return newId;
|
|
210
221
|
}, [service]);
|
|
211
|
-
const deleteThread =
|
|
222
|
+
const deleteThread = React10.useCallback(
|
|
212
223
|
async (threadId) => {
|
|
213
224
|
try {
|
|
214
225
|
await service.deleteThread(threadId);
|
|
@@ -230,13 +241,10 @@ var ThreadProvider = ({
|
|
|
230
241
|
},
|
|
231
242
|
[service]
|
|
232
243
|
);
|
|
233
|
-
const refreshThreads =
|
|
244
|
+
const refreshThreads = React10.useCallback(async () => {
|
|
234
245
|
await fetchThreads();
|
|
235
246
|
}, [fetchThreads]);
|
|
236
|
-
|
|
237
|
-
return groupEventsToMessages(threadEvents);
|
|
238
|
-
}, [threadEvents]);
|
|
239
|
-
React9.useEffect(() => {
|
|
247
|
+
React10.useEffect(() => {
|
|
240
248
|
if (!activeThreadId) {
|
|
241
249
|
setThreadEvents([]);
|
|
242
250
|
setIsLoadingEvents(false);
|
|
@@ -266,7 +274,7 @@ var ThreadProvider = ({
|
|
|
266
274
|
cancelled = true;
|
|
267
275
|
};
|
|
268
276
|
}, [activeThreadId, service]);
|
|
269
|
-
const value =
|
|
277
|
+
const value = React10.useMemo(
|
|
270
278
|
() => ({
|
|
271
279
|
threads,
|
|
272
280
|
activeThreadId,
|
|
@@ -277,7 +285,6 @@ var ThreadProvider = ({
|
|
|
277
285
|
deleteThread,
|
|
278
286
|
refreshThreads,
|
|
279
287
|
threadEvents,
|
|
280
|
-
threadMessages,
|
|
281
288
|
isLoadingEvents
|
|
282
289
|
}),
|
|
283
290
|
[
|
|
@@ -290,33 +297,188 @@ var ThreadProvider = ({
|
|
|
290
297
|
deleteThread,
|
|
291
298
|
refreshThreads,
|
|
292
299
|
threadEvents,
|
|
293
|
-
threadMessages,
|
|
294
300
|
isLoadingEvents
|
|
295
301
|
]
|
|
296
302
|
);
|
|
297
303
|
return /* @__PURE__ */ jsxRuntime.jsx(ThreadContext.Provider, { value, children });
|
|
298
304
|
};
|
|
299
|
-
var
|
|
300
|
-
|
|
305
|
+
var ThemeContext = React10.createContext(void 0);
|
|
306
|
+
function ThemeProvider({ children }) {
|
|
307
|
+
const [theme, setThemeState] = React10.useState("system");
|
|
308
|
+
const [resolvedTheme, setResolvedTheme] = React10.useState("light");
|
|
309
|
+
React10.useEffect(() => {
|
|
310
|
+
if (typeof window !== "undefined") {
|
|
311
|
+
const stored = localStorage.getItem("theme");
|
|
312
|
+
if (stored) {
|
|
313
|
+
setThemeState(stored);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}, []);
|
|
317
|
+
React10.useEffect(() => {
|
|
318
|
+
if (typeof window !== "undefined") {
|
|
319
|
+
if (theme === "system") {
|
|
320
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
321
|
+
const updateResolvedTheme = () => {
|
|
322
|
+
setResolvedTheme(mediaQuery.matches ? "dark" : "light");
|
|
323
|
+
};
|
|
324
|
+
updateResolvedTheme();
|
|
325
|
+
mediaQuery.addEventListener("change", updateResolvedTheme);
|
|
326
|
+
return () => mediaQuery.removeEventListener("change", updateResolvedTheme);
|
|
327
|
+
} else {
|
|
328
|
+
setResolvedTheme(theme);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}, [theme]);
|
|
332
|
+
React10.useEffect(() => {
|
|
333
|
+
if (typeof window !== "undefined") {
|
|
334
|
+
const root = document.documentElement;
|
|
335
|
+
if (resolvedTheme === "dark") {
|
|
336
|
+
root.classList.add("dark");
|
|
337
|
+
} else {
|
|
338
|
+
root.classList.remove("dark");
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}, [resolvedTheme]);
|
|
342
|
+
const setTheme = (newTheme) => {
|
|
343
|
+
setThemeState(newTheme);
|
|
344
|
+
if (typeof window !== "undefined") {
|
|
345
|
+
localStorage.setItem("theme", newTheme);
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value: { theme, setTheme, resolvedTheme }, children });
|
|
349
|
+
}
|
|
350
|
+
function useTheme() {
|
|
351
|
+
const context = React10.useContext(ThemeContext);
|
|
352
|
+
if (context === void 0) {
|
|
353
|
+
throw new Error("useTheme must be used within a ThemeProvider");
|
|
354
|
+
}
|
|
355
|
+
return context;
|
|
356
|
+
}
|
|
357
|
+
var useMelony = (options) => {
|
|
358
|
+
const context = React10.useContext(MelonyContext);
|
|
301
359
|
if (context === void 0) {
|
|
302
|
-
throw new Error("useMelony must be used within a
|
|
360
|
+
throw new Error("useMelony must be used within a MelonyClientProvider");
|
|
303
361
|
}
|
|
362
|
+
const { client, reset } = context;
|
|
363
|
+
const { initialEvents } = options || {};
|
|
364
|
+
React10.useEffect(() => {
|
|
365
|
+
if (initialEvents && initialEvents.length > 0 && client.getState().events.length === 0) {
|
|
366
|
+
reset(initialEvents);
|
|
367
|
+
}
|
|
368
|
+
}, [client, initialEvents, reset]);
|
|
304
369
|
return context;
|
|
305
370
|
};
|
|
306
371
|
var useAuth = () => {
|
|
307
|
-
const context =
|
|
372
|
+
const context = React10.useContext(AuthContext);
|
|
308
373
|
if (context === void 0) {
|
|
309
374
|
throw new Error("useAuth must be used within an AuthProvider");
|
|
310
375
|
}
|
|
311
376
|
return context;
|
|
312
377
|
};
|
|
313
378
|
var useThreads = () => {
|
|
314
|
-
const context =
|
|
379
|
+
const context = React10.useContext(ThreadContext);
|
|
315
380
|
if (context === void 0) {
|
|
316
381
|
throw new Error("useThreads must be used within a ThreadProvider");
|
|
317
382
|
}
|
|
318
383
|
return context;
|
|
319
384
|
};
|
|
385
|
+
function cn(...inputs) {
|
|
386
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
387
|
+
}
|
|
388
|
+
var buttonVariants = classVarianceAuthority.cva(
|
|
389
|
+
"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",
|
|
390
|
+
{
|
|
391
|
+
variants: {
|
|
392
|
+
variant: {
|
|
393
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
|
394
|
+
outline: "border-border bg-input/30 hover:bg-input/50 hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
395
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
|
396
|
+
ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
397
|
+
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",
|
|
398
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
399
|
+
},
|
|
400
|
+
size: {
|
|
401
|
+
default: "h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5",
|
|
402
|
+
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",
|
|
403
|
+
sm: "h-8 gap-1 px-3 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
404
|
+
lg: "h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
|
|
405
|
+
icon: "size-9",
|
|
406
|
+
"icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
|
|
407
|
+
"icon-sm": "size-8",
|
|
408
|
+
"icon-lg": "size-10"
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
defaultVariants: {
|
|
412
|
+
variant: "default",
|
|
413
|
+
size: "default"
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
);
|
|
417
|
+
function Button({
|
|
418
|
+
className,
|
|
419
|
+
variant = "default",
|
|
420
|
+
size = "default",
|
|
421
|
+
...props
|
|
422
|
+
}) {
|
|
423
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
424
|
+
button.Button,
|
|
425
|
+
{
|
|
426
|
+
"data-slot": "button",
|
|
427
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
428
|
+
...props
|
|
429
|
+
}
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
function Textarea({ className, ...props }) {
|
|
433
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
434
|
+
"textarea",
|
|
435
|
+
{
|
|
436
|
+
"data-slot": "textarea",
|
|
437
|
+
className: cn(
|
|
438
|
+
"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",
|
|
439
|
+
className
|
|
440
|
+
),
|
|
441
|
+
...props
|
|
442
|
+
}
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
function Composer({
|
|
446
|
+
value,
|
|
447
|
+
onChange,
|
|
448
|
+
onSubmit,
|
|
449
|
+
placeholder = "Type a message...",
|
|
450
|
+
isLoading,
|
|
451
|
+
className
|
|
452
|
+
}) {
|
|
453
|
+
const handleKeyDown = (e) => {
|
|
454
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
455
|
+
e.preventDefault();
|
|
456
|
+
onSubmit();
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
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: [
|
|
460
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
461
|
+
Textarea,
|
|
462
|
+
{
|
|
463
|
+
value,
|
|
464
|
+
onChange: (e) => onChange(e.target.value),
|
|
465
|
+
onKeyDown: handleKeyDown,
|
|
466
|
+
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"
|
|
468
|
+
}
|
|
469
|
+
),
|
|
470
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
471
|
+
Button,
|
|
472
|
+
{
|
|
473
|
+
type: "submit",
|
|
474
|
+
disabled: !value.trim() && !isLoading || isLoading,
|
|
475
|
+
size: "icon-lg",
|
|
476
|
+
onClick: () => onSubmit(),
|
|
477
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconArrowUp, { className: "h-5 w-5" })
|
|
478
|
+
}
|
|
479
|
+
) })
|
|
480
|
+
] }) });
|
|
481
|
+
}
|
|
320
482
|
function Card({
|
|
321
483
|
className,
|
|
322
484
|
size = "default",
|
|
@@ -385,7 +547,7 @@ var Card2 = ({
|
|
|
385
547
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
386
548
|
Card,
|
|
387
549
|
{
|
|
388
|
-
className: cn("
|
|
550
|
+
className: cn("min-w-96", className),
|
|
389
551
|
style,
|
|
390
552
|
children: [
|
|
391
553
|
(title || subtitle) && /* @__PURE__ */ jsxRuntime.jsxs(CardHeader, { className: "pb-3", children: [
|
|
@@ -707,8 +869,8 @@ var Image = ({
|
|
|
707
869
|
className,
|
|
708
870
|
style
|
|
709
871
|
}) => {
|
|
710
|
-
const [hasError, setHasError] =
|
|
711
|
-
const [isLoading, setIsLoading] =
|
|
872
|
+
const [hasError, setHasError] = React10.useState(false);
|
|
873
|
+
const [isLoading, setIsLoading] = React10.useState(true);
|
|
712
874
|
const sizes = {
|
|
713
875
|
sm: "h-11 w-11",
|
|
714
876
|
md: "h-22 w-22",
|
|
@@ -861,7 +1023,7 @@ var Chart = ({
|
|
|
861
1023
|
className,
|
|
862
1024
|
style
|
|
863
1025
|
}) => {
|
|
864
|
-
const [tooltip, setTooltip] =
|
|
1026
|
+
const [tooltip, setTooltip] = React10.useState(null);
|
|
865
1027
|
if (!Array.isArray(data)) {
|
|
866
1028
|
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" });
|
|
867
1029
|
}
|
|
@@ -1206,19 +1368,6 @@ var Input2 = ({
|
|
|
1206
1368
|
)
|
|
1207
1369
|
] });
|
|
1208
1370
|
};
|
|
1209
|
-
function Textarea({ className, ...props }) {
|
|
1210
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1211
|
-
"textarea",
|
|
1212
|
-
{
|
|
1213
|
-
"data-slot": "textarea",
|
|
1214
|
-
className: cn(
|
|
1215
|
-
"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",
|
|
1216
|
-
className
|
|
1217
|
-
),
|
|
1218
|
-
...props
|
|
1219
|
-
}
|
|
1220
|
-
);
|
|
1221
|
-
}
|
|
1222
1371
|
var Textarea2 = ({
|
|
1223
1372
|
placeholder,
|
|
1224
1373
|
defaultValue,
|
|
@@ -1590,50 +1739,6 @@ var RadioGroup = ({
|
|
|
1590
1739
|
)
|
|
1591
1740
|
] });
|
|
1592
1741
|
};
|
|
1593
|
-
var buttonVariants = classVarianceAuthority.cva(
|
|
1594
|
-
"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",
|
|
1595
|
-
{
|
|
1596
|
-
variants: {
|
|
1597
|
-
variant: {
|
|
1598
|
-
default: "bg-primary text-primary-foreground hover:bg-primary/80",
|
|
1599
|
-
outline: "border-border bg-input/30 hover:bg-input/50 hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
1600
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
|
|
1601
|
-
ghost: "hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground",
|
|
1602
|
-
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",
|
|
1603
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
1604
|
-
},
|
|
1605
|
-
size: {
|
|
1606
|
-
default: "h-9 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5",
|
|
1607
|
-
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",
|
|
1608
|
-
sm: "h-8 gap-1 px-3 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
1609
|
-
lg: "h-10 gap-1.5 px-4 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
|
|
1610
|
-
icon: "size-9",
|
|
1611
|
-
"icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
|
|
1612
|
-
"icon-sm": "size-8",
|
|
1613
|
-
"icon-lg": "size-10"
|
|
1614
|
-
}
|
|
1615
|
-
},
|
|
1616
|
-
defaultVariants: {
|
|
1617
|
-
variant: "default",
|
|
1618
|
-
size: "default"
|
|
1619
|
-
}
|
|
1620
|
-
}
|
|
1621
|
-
);
|
|
1622
|
-
function Button({
|
|
1623
|
-
className,
|
|
1624
|
-
variant = "default",
|
|
1625
|
-
size = "default",
|
|
1626
|
-
...props
|
|
1627
|
-
}) {
|
|
1628
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1629
|
-
button.Button,
|
|
1630
|
-
{
|
|
1631
|
-
"data-slot": "button",
|
|
1632
|
-
className: cn(buttonVariants({ variant, size, className })),
|
|
1633
|
-
...props
|
|
1634
|
-
}
|
|
1635
|
-
);
|
|
1636
|
-
}
|
|
1637
1742
|
var Button2 = ({
|
|
1638
1743
|
label,
|
|
1639
1744
|
variant = "primary",
|
|
@@ -1650,6 +1755,8 @@ var Button2 = ({
|
|
|
1650
1755
|
secondary: "secondary",
|
|
1651
1756
|
danger: "destructive",
|
|
1652
1757
|
outline: "outline",
|
|
1758
|
+
ghost: "ghost",
|
|
1759
|
+
link: "link",
|
|
1653
1760
|
success: "default"
|
|
1654
1761
|
// Success doesn't have a direct shadcn mapping in base variant, default is usually primary
|
|
1655
1762
|
};
|
|
@@ -1672,7 +1779,7 @@ var Button2 = ({
|
|
|
1672
1779
|
};
|
|
1673
1780
|
var Form = ({ children, onSubmitAction, className, style }) => {
|
|
1674
1781
|
const { sendEvent } = useMelony();
|
|
1675
|
-
const [isSubmitted, setIsSubmitted] =
|
|
1782
|
+
const [isSubmitted, setIsSubmitted] = React10.useState(false);
|
|
1676
1783
|
const handleSubmit = (e) => {
|
|
1677
1784
|
e.preventDefault();
|
|
1678
1785
|
if (isSubmitted) return;
|
|
@@ -1718,6 +1825,32 @@ var Form = ({ children, onSubmitAction, className, style }) => {
|
|
|
1718
1825
|
}
|
|
1719
1826
|
);
|
|
1720
1827
|
};
|
|
1828
|
+
function StarterPrompts({
|
|
1829
|
+
prompts,
|
|
1830
|
+
onPromptClick
|
|
1831
|
+
}) {
|
|
1832
|
+
if (!prompts || prompts.length === 0) {
|
|
1833
|
+
return null;
|
|
1834
|
+
}
|
|
1835
|
+
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: [
|
|
1836
|
+
/* @__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?" }) }),
|
|
1837
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2 w-full", children: prompts.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1838
|
+
Button2,
|
|
1839
|
+
{
|
|
1840
|
+
label: item.label,
|
|
1841
|
+
variant: "ghost",
|
|
1842
|
+
size: "lg",
|
|
1843
|
+
onClickAction: {
|
|
1844
|
+
type: "text",
|
|
1845
|
+
role: "user",
|
|
1846
|
+
data: { content: item.prompt }
|
|
1847
|
+
},
|
|
1848
|
+
className: "w-full justify-start"
|
|
1849
|
+
},
|
|
1850
|
+
index
|
|
1851
|
+
)) })
|
|
1852
|
+
] });
|
|
1853
|
+
}
|
|
1721
1854
|
function UIRenderer({ node }) {
|
|
1722
1855
|
const { type, props, children } = node;
|
|
1723
1856
|
const typeMap = {
|
|
@@ -1756,46 +1889,57 @@ function UIRenderer({ node }) {
|
|
|
1756
1889
|
const componentProps = { ...props };
|
|
1757
1890
|
return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...componentProps, children: renderedChildren });
|
|
1758
1891
|
}
|
|
1759
|
-
function
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
placeholder = "Type a message...",
|
|
1764
|
-
isLoading,
|
|
1765
|
-
className
|
|
1766
|
-
}) {
|
|
1767
|
-
const handleKeyDown = (e) => {
|
|
1768
|
-
if (e.key === "Enter" && !e.shiftKey) {
|
|
1769
|
-
e.preventDefault();
|
|
1770
|
-
onSubmit();
|
|
1892
|
+
function MessageContent({ events }) {
|
|
1893
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: events.map((event, index) => {
|
|
1894
|
+
if (event.type === "text-delta") {
|
|
1895
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { children: event.data?.delta }, index);
|
|
1771
1896
|
}
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
{
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1897
|
+
if (event.type === "text") {
|
|
1898
|
+
return /* @__PURE__ */ jsxRuntime.jsx("p", { children: event.data?.content || event.data?.text }, index);
|
|
1899
|
+
}
|
|
1900
|
+
if (event.ui) {
|
|
1901
|
+
return /* @__PURE__ */ jsxRuntime.jsx(UIRenderer, { node: event.ui }, index);
|
|
1902
|
+
}
|
|
1903
|
+
return null;
|
|
1904
|
+
}) });
|
|
1905
|
+
}
|
|
1906
|
+
function MessageBubble({ message }) {
|
|
1907
|
+
const isUser = message.role === "user";
|
|
1908
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1909
|
+
"div",
|
|
1910
|
+
{
|
|
1911
|
+
className: cn(
|
|
1912
|
+
"flex flex-col",
|
|
1913
|
+
isUser ? "items-end" : "items-start"
|
|
1914
|
+
),
|
|
1915
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1916
|
+
"div",
|
|
1917
|
+
{
|
|
1918
|
+
className: cn(
|
|
1919
|
+
"flex flex-col items-start max-w-[85%] rounded-2xl px-4 py-2 space-y-4 whitespace-pre-wrap",
|
|
1920
|
+
isUser ? "bg-primary text-primary-foreground" : "px-0 py-0 text-foreground"
|
|
1921
|
+
),
|
|
1922
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(MessageContent, { events: message.content })
|
|
1923
|
+
}
|
|
1924
|
+
)
|
|
1925
|
+
}
|
|
1926
|
+
);
|
|
1927
|
+
}
|
|
1928
|
+
function LoadingIndicator() {
|
|
1929
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground animate-pulse", children: "Thinking..." });
|
|
1930
|
+
}
|
|
1931
|
+
function ErrorDisplay({ error }) {
|
|
1932
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-destructive p-2 border border-destructive rounded-md bg-destructive/10", children: error.message });
|
|
1933
|
+
}
|
|
1934
|
+
function MessageList({ messages, isLoading, error }) {
|
|
1935
|
+
if (messages.length === 0) {
|
|
1936
|
+
return null;
|
|
1937
|
+
}
|
|
1938
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
1939
|
+
messages.map((message, index) => /* @__PURE__ */ jsxRuntime.jsx(MessageBubble, { message }, index)),
|
|
1940
|
+
isLoading && /* @__PURE__ */ jsxRuntime.jsx(LoadingIndicator, {}),
|
|
1941
|
+
error && /* @__PURE__ */ jsxRuntime.jsx(ErrorDisplay, { error })
|
|
1942
|
+
] });
|
|
1799
1943
|
}
|
|
1800
1944
|
function Thread({
|
|
1801
1945
|
className,
|
|
@@ -1804,9 +1948,9 @@ function Thread({
|
|
|
1804
1948
|
onStarterPromptClick
|
|
1805
1949
|
}) {
|
|
1806
1950
|
const { messages, isLoading, error, sendEvent } = useMelony();
|
|
1807
|
-
const [input, setInput] =
|
|
1808
|
-
const messagesEndRef =
|
|
1809
|
-
|
|
1951
|
+
const [input, setInput] = React10.useState("");
|
|
1952
|
+
const messagesEndRef = React10.useRef(null);
|
|
1953
|
+
React10.useEffect(() => {
|
|
1810
1954
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
1811
1955
|
}, [messages]);
|
|
1812
1956
|
const handleSubmit = async (e, overrideInput) => {
|
|
@@ -1827,57 +1971,38 @@ function Thread({
|
|
|
1827
1971
|
handleSubmit(void 0, prompt);
|
|
1828
1972
|
}
|
|
1829
1973
|
};
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
] }),
|
|
1848
|
-
messages.map((message, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1849
|
-
"div",
|
|
1850
|
-
{
|
|
1851
|
-
className: cn(
|
|
1852
|
-
"flex flex-col",
|
|
1853
|
-
message.role === "user" ? "items-end" : "items-start"
|
|
1974
|
+
const showStarterPrompts = messages.length === 0 && starterPrompts && starterPrompts.length > 0;
|
|
1975
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative flex flex-col h-full bg-background", className), children: [
|
|
1976
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto p-4 pb-36", children: [
|
|
1977
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1978
|
+
"div",
|
|
1979
|
+
{
|
|
1980
|
+
className: cn(
|
|
1981
|
+
"max-w-4xl mx-auto w-full p-4",
|
|
1982
|
+
showStarterPrompts && "min-h-full flex flex-col"
|
|
1983
|
+
),
|
|
1984
|
+
children: [
|
|
1985
|
+
showStarterPrompts && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1986
|
+
StarterPrompts,
|
|
1987
|
+
{
|
|
1988
|
+
prompts: starterPrompts,
|
|
1989
|
+
onPromptClick: handleStarterPromptClick
|
|
1990
|
+
}
|
|
1854
1991
|
),
|
|
1855
|
-
|
|
1856
|
-
|
|
1992
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1993
|
+
MessageList,
|
|
1857
1994
|
{
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
),
|
|
1862
|
-
children: message.content.map((event, j) => {
|
|
1863
|
-
if (event.type === "text-delta")
|
|
1864
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { children: event.data?.delta }, j);
|
|
1865
|
-
if (event.type === "text")
|
|
1866
|
-
return /* @__PURE__ */ jsxRuntime.jsx("p", { children: event.data?.content || event.data?.text }, j);
|
|
1867
|
-
if (event.ui) return /* @__PURE__ */ jsxRuntime.jsx(UIRenderer, { node: event.ui }, j);
|
|
1868
|
-
return null;
|
|
1869
|
-
})
|
|
1995
|
+
messages,
|
|
1996
|
+
isLoading,
|
|
1997
|
+
error
|
|
1870
1998
|
}
|
|
1871
1999
|
)
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground animate-pulse", children: "Thinking..." }),
|
|
1876
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-destructive p-2 border border-destructive rounded-md bg-destructive/10", children: error.message })
|
|
1877
|
-
] }),
|
|
2000
|
+
]
|
|
2001
|
+
}
|
|
2002
|
+
),
|
|
1878
2003
|
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: messagesEndRef })
|
|
1879
2004
|
] }),
|
|
1880
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4
|
|
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(
|
|
1881
2006
|
Composer,
|
|
1882
2007
|
{
|
|
1883
2008
|
value: input,
|
|
@@ -1889,18 +2014,34 @@ function Thread({
|
|
|
1889
2014
|
) }) })
|
|
1890
2015
|
] });
|
|
1891
2016
|
}
|
|
2017
|
+
function ChatHeader({
|
|
2018
|
+
title,
|
|
2019
|
+
leftContent,
|
|
2020
|
+
rightContent,
|
|
2021
|
+
className,
|
|
2022
|
+
titleClassName,
|
|
2023
|
+
children
|
|
2024
|
+
}) {
|
|
2025
|
+
if (children) {
|
|
2026
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("p-4 border-b border-border h-14 flex items-center shrink-0", className), children });
|
|
2027
|
+
}
|
|
2028
|
+
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.jsxs("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [
|
|
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
|
+
] }),
|
|
2036
|
+
rightContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 shrink-0 ml-2", children: rightContent })
|
|
2037
|
+
] });
|
|
2038
|
+
}
|
|
1892
2039
|
var ThreadList = ({
|
|
1893
2040
|
className,
|
|
1894
2041
|
emptyState,
|
|
1895
2042
|
onThreadSelect
|
|
1896
2043
|
}) => {
|
|
1897
|
-
const {
|
|
1898
|
-
threads,
|
|
1899
|
-
activeThreadId,
|
|
1900
|
-
selectThread,
|
|
1901
|
-
createThread,
|
|
1902
|
-
deleteThread
|
|
1903
|
-
} = useThreads();
|
|
2044
|
+
const { threads, activeThreadId, selectThread, createThread, deleteThread } = useThreads();
|
|
1904
2045
|
const handleThreadClick = (threadId) => {
|
|
1905
2046
|
if (threadId !== activeThreadId) {
|
|
1906
2047
|
selectThread(threadId);
|
|
@@ -1938,10 +2079,10 @@ var ThreadList = ({
|
|
|
1938
2079
|
return d.toLocaleDateString();
|
|
1939
2080
|
};
|
|
1940
2081
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full", className), children: [
|
|
1941
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2
|
|
2082
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-2", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1942
2083
|
Button,
|
|
1943
2084
|
{
|
|
1944
|
-
variant: "
|
|
2085
|
+
variant: "ghost",
|
|
1945
2086
|
size: "sm",
|
|
1946
2087
|
onClick: handleNewThread,
|
|
1947
2088
|
className: "w-full justify-start",
|
|
@@ -1962,31 +2103,13 @@ var ThreadList = ({
|
|
|
1962
2103
|
{
|
|
1963
2104
|
onClick: () => handleThreadClick(thread.id),
|
|
1964
2105
|
className: cn(
|
|
1965
|
-
"group relative flex items-center gap-3
|
|
1966
|
-
isActive ? "bg-
|
|
2106
|
+
"group relative flex items-center gap-3 px-3 py-1.5 rounded-lg cursor-pointer transition-colors",
|
|
2107
|
+
isActive ? "bg-muted" : "hover:bg-muted"
|
|
1967
2108
|
),
|
|
1968
2109
|
children: [
|
|
1969
2110
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1970
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1971
|
-
|
|
1972
|
-
{
|
|
1973
|
-
className: cn(
|
|
1974
|
-
"text-sm font-medium truncate",
|
|
1975
|
-
isActive && "text-primary-foreground"
|
|
1976
|
-
),
|
|
1977
|
-
children: thread.title || `Thread ${thread.id.slice(0, 8)}`
|
|
1978
|
-
}
|
|
1979
|
-
),
|
|
1980
|
-
thread.updatedAt && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1981
|
-
"span",
|
|
1982
|
-
{
|
|
1983
|
-
className: cn(
|
|
1984
|
-
"text-xs shrink-0",
|
|
1985
|
-
isActive ? "text-primary-foreground/70" : "text-muted-foreground"
|
|
1986
|
-
),
|
|
1987
|
-
children: formatDate(thread.updatedAt)
|
|
1988
|
-
}
|
|
1989
|
-
)
|
|
2111
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-sm font-medium truncate"), children: thread.title || `Thread ${thread.id.slice(0, 8)}` }),
|
|
2112
|
+
thread.updatedAt && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-xs shrink-0"), children: formatDate(thread.updatedAt) })
|
|
1990
2113
|
] }) }),
|
|
1991
2114
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1992
2115
|
Button,
|
|
@@ -2012,10 +2135,11 @@ function ChatPopup({
|
|
|
2012
2135
|
title = "Chat",
|
|
2013
2136
|
placeholder = "Message the AI",
|
|
2014
2137
|
starterPrompts,
|
|
2015
|
-
defaultOpen = false
|
|
2138
|
+
defaultOpen = false,
|
|
2139
|
+
headerProps
|
|
2016
2140
|
}) {
|
|
2017
|
-
const [isOpen, setIsOpen] =
|
|
2018
|
-
const [view, setView] =
|
|
2141
|
+
const [isOpen, setIsOpen] = React10.useState(defaultOpen);
|
|
2142
|
+
const [view, setView] = React10.useState("chat");
|
|
2019
2143
|
const { createThread } = useThreads();
|
|
2020
2144
|
const handleNewChat = async () => {
|
|
2021
2145
|
try {
|
|
@@ -2027,9 +2151,11 @@ function ChatPopup({
|
|
|
2027
2151
|
};
|
|
2028
2152
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fixed bottom-6 right-6 z-50 flex flex-col items-end gap-4 font-sans", children: [
|
|
2029
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: [
|
|
2030
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2031
|
-
|
|
2032
|
-
|
|
2154
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2155
|
+
ChatHeader,
|
|
2156
|
+
{
|
|
2157
|
+
title: view === "history" ? "History" : title,
|
|
2158
|
+
leftContent: view === "history" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2033
2159
|
Button,
|
|
2034
2160
|
{
|
|
2035
2161
|
variant: "ghost",
|
|
@@ -2038,44 +2164,44 @@ function ChatPopup({
|
|
|
2038
2164
|
className: "text-muted-foreground hover:text-foreground",
|
|
2039
2165
|
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconArrowLeft, { className: "size-4" })
|
|
2040
2166
|
}
|
|
2041
|
-
),
|
|
2042
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2167
|
+
) : void 0,
|
|
2168
|
+
rightContent: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2169
|
+
view === "chat" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2170
|
+
Button,
|
|
2171
|
+
{
|
|
2172
|
+
variant: "ghost",
|
|
2173
|
+
size: "icon-xs",
|
|
2174
|
+
onClick: () => setView("history"),
|
|
2175
|
+
className: "text-muted-foreground hover:text-foreground",
|
|
2176
|
+
title: "History",
|
|
2177
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconHistory, { className: "size-4" })
|
|
2178
|
+
}
|
|
2179
|
+
),
|
|
2180
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2181
|
+
Button,
|
|
2182
|
+
{
|
|
2183
|
+
variant: "ghost",
|
|
2184
|
+
size: "icon-xs",
|
|
2185
|
+
onClick: handleNewChat,
|
|
2186
|
+
className: "text-muted-foreground hover:text-foreground",
|
|
2187
|
+
title: "New Chat",
|
|
2188
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconPlus, { className: "size-4" })
|
|
2189
|
+
}
|
|
2190
|
+
),
|
|
2191
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2192
|
+
Button,
|
|
2193
|
+
{
|
|
2194
|
+
variant: "ghost",
|
|
2195
|
+
size: "icon-xs",
|
|
2196
|
+
onClick: () => setIsOpen(false),
|
|
2197
|
+
className: "text-muted-foreground hover:text-foreground",
|
|
2198
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconX, { className: "size-4" })
|
|
2199
|
+
}
|
|
2200
|
+
)
|
|
2201
|
+
] }),
|
|
2202
|
+
...headerProps
|
|
2203
|
+
}
|
|
2204
|
+
),
|
|
2079
2205
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden", children: view === "chat" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2080
2206
|
Thread,
|
|
2081
2207
|
{
|
|
@@ -2109,10 +2235,11 @@ function ChatSidebar({
|
|
|
2109
2235
|
title = "Chat",
|
|
2110
2236
|
placeholder = "Message the AI",
|
|
2111
2237
|
starterPrompts,
|
|
2112
|
-
className
|
|
2238
|
+
className,
|
|
2239
|
+
headerProps
|
|
2113
2240
|
}) {
|
|
2114
2241
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full border-r bg-background w-80", className), children: [
|
|
2115
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2242
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChatHeader, { title, ...headerProps }),
|
|
2116
2243
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2117
2244
|
Thread,
|
|
2118
2245
|
{
|
|
@@ -2127,11 +2254,122 @@ function ChatFull({
|
|
|
2127
2254
|
title = "Chat",
|
|
2128
2255
|
placeholder = "Message the AI",
|
|
2129
2256
|
starterPrompts,
|
|
2130
|
-
className
|
|
2257
|
+
className,
|
|
2258
|
+
headerProps,
|
|
2259
|
+
leftSidebar,
|
|
2260
|
+
rightSidebar,
|
|
2261
|
+
leftSidebarClassName,
|
|
2262
|
+
rightSidebarClassName,
|
|
2263
|
+
leftSidebarCollapsible = false,
|
|
2264
|
+
rightSidebarCollapsible = false,
|
|
2265
|
+
defaultLeftSidebarCollapsed = false,
|
|
2266
|
+
defaultRightSidebarCollapsed = false,
|
|
2267
|
+
leftSidebarCollapsed: controlledLeftCollapsed,
|
|
2268
|
+
rightSidebarCollapsed: controlledRightCollapsed,
|
|
2269
|
+
onLeftSidebarCollapseChange,
|
|
2270
|
+
onRightSidebarCollapseChange
|
|
2131
2271
|
}) {
|
|
2272
|
+
const [internalLeftCollapsed, setInternalLeftCollapsed] = React10.useState(
|
|
2273
|
+
defaultLeftSidebarCollapsed
|
|
2274
|
+
);
|
|
2275
|
+
const [internalRightCollapsed, setInternalRightCollapsed] = React10.useState(
|
|
2276
|
+
defaultRightSidebarCollapsed
|
|
2277
|
+
);
|
|
2278
|
+
const leftCollapsed = controlledLeftCollapsed !== void 0 ? controlledLeftCollapsed : internalLeftCollapsed;
|
|
2279
|
+
const rightCollapsed = controlledRightCollapsed !== void 0 ? controlledRightCollapsed : internalRightCollapsed;
|
|
2280
|
+
const handleLeftToggle = () => {
|
|
2281
|
+
const newCollapsed = !leftCollapsed;
|
|
2282
|
+
if (controlledLeftCollapsed === void 0) {
|
|
2283
|
+
setInternalLeftCollapsed(newCollapsed);
|
|
2284
|
+
}
|
|
2285
|
+
onLeftSidebarCollapseChange?.(newCollapsed);
|
|
2286
|
+
};
|
|
2287
|
+
const handleRightToggle = () => {
|
|
2288
|
+
const newCollapsed = !rightCollapsed;
|
|
2289
|
+
if (controlledRightCollapsed === void 0) {
|
|
2290
|
+
setInternalRightCollapsed(newCollapsed);
|
|
2291
|
+
}
|
|
2292
|
+
onRightSidebarCollapseChange?.(newCollapsed);
|
|
2293
|
+
};
|
|
2132
2294
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col h-full w-full bg-background", className), children: [
|
|
2133
|
-
title && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2134
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2295
|
+
title && /* @__PURE__ */ jsxRuntime.jsx(ChatHeader, { title, ...headerProps }),
|
|
2296
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-hidden flex relative", children: [
|
|
2297
|
+
leftSidebar && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2298
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2299
|
+
"div",
|
|
2300
|
+
{
|
|
2301
|
+
className: cn(
|
|
2302
|
+
"flex-shrink-0 border-r border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
|
|
2303
|
+
leftCollapsed && leftSidebarCollapsible ? "w-0 border-r-0 min-w-0" : "",
|
|
2304
|
+
!leftCollapsed && leftSidebarClassName
|
|
2305
|
+
),
|
|
2306
|
+
children: !leftCollapsed && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2307
|
+
leftSidebarCollapsible && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end p-2 border-b border-border shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2308
|
+
Button,
|
|
2309
|
+
{
|
|
2310
|
+
variant: "ghost",
|
|
2311
|
+
size: "icon-sm",
|
|
2312
|
+
onClick: handleLeftToggle,
|
|
2313
|
+
"aria-label": "Collapse left sidebar",
|
|
2314
|
+
className: "h-8 w-8",
|
|
2315
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronLeft, { className: "h-4 w-4" })
|
|
2316
|
+
}
|
|
2317
|
+
) }),
|
|
2318
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: leftSidebar })
|
|
2319
|
+
] })
|
|
2320
|
+
}
|
|
2321
|
+
),
|
|
2322
|
+
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(
|
|
2323
|
+
Button,
|
|
2324
|
+
{
|
|
2325
|
+
variant: "ghost",
|
|
2326
|
+
size: "icon-sm",
|
|
2327
|
+
onClick: handleLeftToggle,
|
|
2328
|
+
"aria-label": "Expand left sidebar",
|
|
2329
|
+
className: "h-8 w-8",
|
|
2330
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronRight, { className: "h-4 w-4" })
|
|
2331
|
+
}
|
|
2332
|
+
) })
|
|
2333
|
+
] }),
|
|
2334
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(Thread, { placeholder, starterPrompts }) }),
|
|
2335
|
+
rightSidebar && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2336
|
+
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
|
+
Button,
|
|
2338
|
+
{
|
|
2339
|
+
variant: "ghost",
|
|
2340
|
+
size: "icon-sm",
|
|
2341
|
+
onClick: handleRightToggle,
|
|
2342
|
+
"aria-label": "Expand right sidebar",
|
|
2343
|
+
className: "h-8 w-8",
|
|
2344
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronLeft, { className: "h-4 w-4" })
|
|
2345
|
+
}
|
|
2346
|
+
) }),
|
|
2347
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2348
|
+
"div",
|
|
2349
|
+
{
|
|
2350
|
+
className: cn(
|
|
2351
|
+
"flex-shrink-0 border-l border-border bg-background transition-all duration-300 ease-in-out overflow-hidden flex flex-col",
|
|
2352
|
+
rightCollapsed && rightSidebarCollapsible ? "w-0 border-l-0 min-w-0" : "",
|
|
2353
|
+
!rightCollapsed && rightSidebarClassName
|
|
2354
|
+
),
|
|
2355
|
+
children: !rightCollapsed && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2356
|
+
rightSidebarCollapsible && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-start p-2 border-b border-border shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2357
|
+
Button,
|
|
2358
|
+
{
|
|
2359
|
+
variant: "ghost",
|
|
2360
|
+
size: "icon-sm",
|
|
2361
|
+
onClick: handleRightToggle,
|
|
2362
|
+
"aria-label": "Collapse right sidebar",
|
|
2363
|
+
className: "h-8 w-8",
|
|
2364
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconChevronRight, { className: "h-4 w-4" })
|
|
2365
|
+
}
|
|
2366
|
+
) }),
|
|
2367
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-hidden min-h-0", children: rightSidebar })
|
|
2368
|
+
] })
|
|
2369
|
+
}
|
|
2370
|
+
)
|
|
2371
|
+
] })
|
|
2372
|
+
] })
|
|
2135
2373
|
] });
|
|
2136
2374
|
}
|
|
2137
2375
|
function AlertDialog({ ...props }) {
|
|
@@ -2275,8 +2513,8 @@ var AccountDialog = ({
|
|
|
2275
2513
|
size
|
|
2276
2514
|
}) => {
|
|
2277
2515
|
const { isLoading, isAuthenticated, login, logout } = useAuth();
|
|
2278
|
-
const [open, setOpen] =
|
|
2279
|
-
const [error, setError] =
|
|
2516
|
+
const [open, setOpen] = React10__namespace.useState(false);
|
|
2517
|
+
const [error, setError] = React10__namespace.useState(null);
|
|
2280
2518
|
const handleGoogleSignIn = async () => {
|
|
2281
2519
|
login();
|
|
2282
2520
|
};
|
|
@@ -2351,23 +2589,63 @@ var AccountDialog = ({
|
|
|
2351
2589
|
] }) })
|
|
2352
2590
|
] });
|
|
2353
2591
|
};
|
|
2592
|
+
function ThemeToggle() {
|
|
2593
|
+
const { theme, setTheme, resolvedTheme } = useTheme();
|
|
2594
|
+
const cycleTheme = () => {
|
|
2595
|
+
if (theme === "light") {
|
|
2596
|
+
setTheme("dark");
|
|
2597
|
+
} else if (theme === "dark") {
|
|
2598
|
+
setTheme("system");
|
|
2599
|
+
} else {
|
|
2600
|
+
setTheme("light");
|
|
2601
|
+
}
|
|
2602
|
+
};
|
|
2603
|
+
const getIcon = () => {
|
|
2604
|
+
if (theme === "system") {
|
|
2605
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconDeviceDesktop, { className: "h-4 w-4" });
|
|
2606
|
+
}
|
|
2607
|
+
return resolvedTheme === "dark" ? /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconMoon, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(ICONS.IconSun, { className: "h-4 w-4" });
|
|
2608
|
+
};
|
|
2609
|
+
const getLabel = () => {
|
|
2610
|
+
if (theme === "system") {
|
|
2611
|
+
return "System";
|
|
2612
|
+
}
|
|
2613
|
+
return resolvedTheme === "dark" ? "Dark" : "Light";
|
|
2614
|
+
};
|
|
2615
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2616
|
+
Button,
|
|
2617
|
+
{
|
|
2618
|
+
variant: "ghost",
|
|
2619
|
+
size: "icon",
|
|
2620
|
+
onClick: cycleTheme,
|
|
2621
|
+
"aria-label": `Toggle theme (current: ${getLabel()})`,
|
|
2622
|
+
title: `Current: ${getLabel()}. Click to cycle: Light \u2192 Dark \u2192 System`,
|
|
2623
|
+
children: getIcon()
|
|
2624
|
+
}
|
|
2625
|
+
);
|
|
2626
|
+
}
|
|
2354
2627
|
|
|
2355
2628
|
exports.AccountDialog = AccountDialog;
|
|
2356
2629
|
exports.AuthContext = AuthContext;
|
|
2357
2630
|
exports.AuthProvider = AuthProvider;
|
|
2358
2631
|
exports.ChatFull = ChatFull;
|
|
2632
|
+
exports.ChatHeader = ChatHeader;
|
|
2359
2633
|
exports.ChatPopup = ChatPopup;
|
|
2360
2634
|
exports.ChatSidebar = ChatSidebar;
|
|
2361
2635
|
exports.Composer = Composer;
|
|
2636
|
+
exports.MelonyClientProvider = MelonyClientProvider;
|
|
2362
2637
|
exports.MelonyContext = MelonyContext;
|
|
2363
|
-
exports.
|
|
2638
|
+
exports.ThemeProvider = ThemeProvider;
|
|
2639
|
+
exports.ThemeToggle = ThemeToggle;
|
|
2364
2640
|
exports.Thread = Thread;
|
|
2365
2641
|
exports.ThreadContext = ThreadContext;
|
|
2366
2642
|
exports.ThreadList = ThreadList;
|
|
2367
2643
|
exports.ThreadProvider = ThreadProvider;
|
|
2368
2644
|
exports.UIRenderer = UIRenderer;
|
|
2645
|
+
exports.groupEventsToMessages = groupEventsToMessages;
|
|
2369
2646
|
exports.useAuth = useAuth;
|
|
2370
2647
|
exports.useMelony = useMelony;
|
|
2648
|
+
exports.useTheme = useTheme;
|
|
2371
2649
|
exports.useThreads = useThreads;
|
|
2372
2650
|
//# sourceMappingURL=index.cjs.map
|
|
2373
2651
|
//# sourceMappingURL=index.cjs.map
|