goji-search 1.0.1 → 1.1.0
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/goji-search/components/elements/action-buttons.d.ts +2 -1
- package/dist/goji-search/components/elements/action-buttons.js +52 -19
- package/dist/goji-search/components/elements/auto-expanding-textarea.d.ts +8 -0
- package/dist/goji-search/components/elements/auto-expanding-textarea.js +36 -0
- package/dist/goji-search/components/elements/inspiration-menu.js +17 -17
- package/dist/goji-search/components/elements/message-list.d.ts +1 -3
- package/dist/goji-search/components/elements/message-list.js +81 -103
- package/dist/goji-search/components/elements/search-input.d.ts +2 -2
- package/dist/goji-search/components/elements/search-input.js +37 -33
- package/dist/goji-search/components/elements/suggested-questions.js +1 -1
- package/dist/goji-search/components/goji-search-component.d.ts +9 -1
- package/dist/goji-search/components/goji-search-component.js +295 -105
- package/dist/goji-search/config/company.d.ts +0 -1
- package/dist/goji-search/config/company.js +34 -7
- package/dist/goji-search/lib/goji-client.d.ts +39 -0
- package/dist/goji-search/lib/goji-client.js +55 -2
- package/dist/goji-search.css +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/package.json +1 -1
|
@@ -3,10 +3,11 @@ interface ActionButtonsProps {
|
|
|
3
3
|
isHovered: boolean;
|
|
4
4
|
isStreaming: boolean;
|
|
5
5
|
searchQuery: string;
|
|
6
|
+
isRecording?: boolean;
|
|
6
7
|
onSubmit: () => void;
|
|
7
8
|
onVoiceSearch: () => void;
|
|
8
9
|
onClose: () => void;
|
|
9
10
|
onCalendarClick: () => void;
|
|
10
11
|
}
|
|
11
|
-
export declare function ActionButtons({ size, isHovered, isStreaming, searchQuery, onSubmit, onVoiceSearch, onClose, onCalendarClick, }: ActionButtonsProps): import("react/jsx-runtime").JSX.Element | null;
|
|
12
|
+
export declare function ActionButtons({ size, isHovered, isStreaming, searchQuery, isRecording, onSubmit, onVoiceSearch, onClose, onCalendarClick, }: ActionButtonsProps): import("react/jsx-runtime").JSX.Element | null;
|
|
12
13
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Mic, Calendar, ArrowUp } from "lucide-react";
|
|
3
3
|
import { useState, useId } from "react";
|
|
4
|
-
export function ActionButtons({ size, isHovered, isStreaming, searchQuery, onSubmit, onVoiceSearch, onClose, onCalendarClick, // Added calendar click handler
|
|
4
|
+
export function ActionButtons({ size, isHovered, isStreaming, searchQuery, isRecording = false, onSubmit, onVoiceSearch, onClose, onCalendarClick, // Added calendar click handler
|
|
5
5
|
}) {
|
|
6
6
|
if (size !== "m" && size !== "l" && size !== "xl")
|
|
7
7
|
return null;
|
|
@@ -49,34 +49,68 @@ export function ActionButtons({ size, isHovered, isStreaming, searchQuery, onSub
|
|
|
49
49
|
pointerEvents: "none",
|
|
50
50
|
transition: "opacity 120ms ease-in-out",
|
|
51
51
|
zIndex: 30,
|
|
52
|
-
}, children: "Send message" })] }), _jsxs("div", { style: { position: "relative", display: "inline-block", marginLeft: "0.25rem" }, onMouseEnter: () => setHoverVoice(true), onMouseLeave: () => setHoverVoice(false), children: [
|
|
53
|
-
setHoverVoice(false);
|
|
54
|
-
e.currentTarget.style.boxShadow = "inset 0 1px 0 rgba(255, 255, 255, 0.3)";
|
|
55
|
-
}, style: {
|
|
52
|
+
}, children: "Send message" })] }), _jsxs("div", { style: { position: "relative", display: "inline-block", marginLeft: "0.25rem" }, onMouseEnter: () => setHoverVoice(true), onMouseLeave: () => setHoverVoice(false), children: [_jsxs("button", { type: "button", onClick: onVoiceSearch, "aria-describedby": hoverVoice ? voiceTooltipId : undefined, onFocus: () => setHoverVoice(true), onBlur: () => setHoverVoice(false), style: {
|
|
56
53
|
borderRadius: "1.3rem",
|
|
57
|
-
border: "1px solid rgba(255, 255, 255, 0.3)",
|
|
58
|
-
backgroundColor: "rgba(255, 255, 255, 0.2)",
|
|
54
|
+
border: isRecording ? "1px solid rgba(220, 38, 38, 0.5)" : "1px solid rgba(255, 255, 255, 0.3)",
|
|
55
|
+
backgroundColor: isRecording ? "rgba(220, 38, 38, 0.2)" : "rgba(255, 255, 255, 0.2)",
|
|
59
56
|
padding: size === "l" || size === "xl" ? "0.5rem" : "0.3rem",
|
|
60
57
|
display: "flex",
|
|
61
58
|
alignItems: "center",
|
|
62
59
|
justifyContent: "center",
|
|
63
|
-
|
|
64
|
-
color: "rgba(0, 0, 0, 0.75)",
|
|
60
|
+
color: isRecording ? "rgba(220, 38, 38, 0.9)" : "rgba(0, 0, 0, 0.75)",
|
|
65
61
|
backdropFilter: "blur(20px)",
|
|
66
62
|
WebkitBackdropFilter: "blur(20px)",
|
|
67
63
|
transition: "all 0.2s",
|
|
68
64
|
cursor: "pointer",
|
|
69
65
|
outline: "none",
|
|
70
66
|
opacity: size === "m" && !isHovered ? 0.7 : 1,
|
|
71
|
-
boxShadow: "inset 0 1px 0 rgba(255, 255, 255, 0.3)",
|
|
67
|
+
boxShadow: isRecording ? "inset 0 1px 0 rgba(220, 38, 38, 0.2)" : "inset 0 1px 0 rgba(255, 255, 255, 0.3)",
|
|
72
68
|
}, onMouseEnter: (e) => {
|
|
73
|
-
|
|
69
|
+
if (!isRecording) {
|
|
70
|
+
e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.3)";
|
|
71
|
+
}
|
|
74
72
|
}, onMouseLeave: (e) => {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
if (!isRecording) {
|
|
74
|
+
e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.2)";
|
|
75
|
+
}
|
|
76
|
+
}, children: [_jsx(Mic, { style: {
|
|
77
|
+
width: size === "l" || size === "xl" ? "1rem" : "0.875rem",
|
|
78
|
+
height: size === "l" || size === "xl" ? "1rem" : "0.875rem",
|
|
79
|
+
} }), isRecording && (_jsxs("span", { "aria-hidden": "true", style: {
|
|
80
|
+
display: "inline-flex",
|
|
81
|
+
alignItems: "flex-end",
|
|
82
|
+
gap: "2px",
|
|
83
|
+
marginLeft: size === "l" || size === "xl" ? "6px" : "4px",
|
|
84
|
+
height: size === "l" || size === "xl" ? "1rem" : "0.875rem",
|
|
85
|
+
}, children: [_jsx("span", { style: {
|
|
86
|
+
width: "2px",
|
|
87
|
+
height: "55%",
|
|
88
|
+
backgroundColor: "rgba(220, 38, 38, 0.95)",
|
|
89
|
+
borderRadius: "1px",
|
|
90
|
+
transformOrigin: "bottom",
|
|
91
|
+
animation: "eqPulse 900ms ease-in-out 0ms infinite",
|
|
92
|
+
} }), _jsx("span", { style: {
|
|
93
|
+
width: "2px",
|
|
94
|
+
height: "85%",
|
|
95
|
+
backgroundColor: "rgba(220, 38, 38, 0.95)",
|
|
96
|
+
borderRadius: "1px",
|
|
97
|
+
transformOrigin: "bottom",
|
|
98
|
+
animation: "eqPulse 900ms ease-in-out 100ms infinite",
|
|
99
|
+
} }), _jsx("span", { style: {
|
|
100
|
+
width: "2px",
|
|
101
|
+
height: "65%",
|
|
102
|
+
backgroundColor: "rgba(220, 38, 38, 0.95)",
|
|
103
|
+
borderRadius: "1px",
|
|
104
|
+
transformOrigin: "bottom",
|
|
105
|
+
animation: "eqPulse 900ms ease-in-out 200ms infinite",
|
|
106
|
+
} }), _jsx("span", { style: {
|
|
107
|
+
width: "2px",
|
|
108
|
+
height: "78%",
|
|
109
|
+
backgroundColor: "rgba(220, 38, 38, 0.95)",
|
|
110
|
+
borderRadius: "1px",
|
|
111
|
+
transformOrigin: "bottom",
|
|
112
|
+
animation: "eqPulse 900ms ease-in-out 300ms infinite",
|
|
113
|
+
} })] }))] }), _jsx("span", { id: voiceTooltipId, role: "tooltip", style: {
|
|
80
114
|
position: "absolute",
|
|
81
115
|
top: "calc(100% + 0.4rem)",
|
|
82
116
|
left: "50%",
|
|
@@ -92,14 +126,13 @@ export function ActionButtons({ size, isHovered, isStreaming, searchQuery, onSub
|
|
|
92
126
|
pointerEvents: "none",
|
|
93
127
|
transition: "opacity 120ms ease-in-out",
|
|
94
128
|
zIndex: 30,
|
|
95
|
-
}, children: "Voice input" })] }), _jsxs("div", { style: { position: "relative", display: "inline-block", marginRight: "0.25rem" }, onMouseEnter: () => setHoverCalendar(true), onMouseLeave: () => setHoverCalendar(false), children: [_jsxs("button", { type: "button", disabled: isStreaming, onClick: onCalendarClick, "aria-describedby": hoverCalendar ? calendarTooltipId : undefined, onFocus: () => setHoverCalendar(true), onBlur: () => setHoverCalendar(false), style: {
|
|
129
|
+
}, children: isRecording ? "Stop recording" : "Voice input" })] }), _jsxs("div", { style: { position: "relative", display: "inline-block", marginRight: "0.25rem" }, onMouseEnter: () => setHoverCalendar(true), onMouseLeave: () => setHoverCalendar(false), children: [_jsxs("button", { type: "button", disabled: isStreaming, onClick: onCalendarClick, "aria-describedby": hoverCalendar ? calendarTooltipId : undefined, onFocus: () => setHoverCalendar(true), onBlur: () => setHoverCalendar(false), style: {
|
|
96
130
|
borderRadius: "1.3rem",
|
|
97
131
|
border: "1px solid rgba(255, 255, 255, 0.3)",
|
|
98
132
|
backgroundColor: "rgb(0, 0, 0)",
|
|
99
133
|
padding: size === "l" || size === "xl" ? "0.5rem" : "0.4rem",
|
|
100
134
|
display: size === "l" || size === "m" || size === "xl" ? "flex" : "none",
|
|
101
135
|
alignItems: "center",
|
|
102
|
-
outlineColor: "none",
|
|
103
136
|
justifyContent: "center",
|
|
104
137
|
color: "rgb(255, 255, 255)",
|
|
105
138
|
transition: "all 0.2s",
|
|
@@ -113,7 +146,7 @@ export function ActionButtons({ size, isHovered, isStreaming, searchQuery, onSub
|
|
|
113
146
|
marginLeft: "0.5rem",
|
|
114
147
|
fontSize: "0.7rem",
|
|
115
148
|
fontWeight: 400,
|
|
116
|
-
display: size === "m" ? "none" : "block",
|
|
149
|
+
display: size === "m" || searchQuery.length > 0 ? "none" : "block",
|
|
117
150
|
transition: "all 0.4s",
|
|
118
151
|
}, children: "Book a call" })] }), _jsx("span", { id: calendarTooltipId, role: "tooltip", style: {
|
|
119
152
|
position: "absolute",
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
interface AutoExpandingTextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
3
|
+
value: string;
|
|
4
|
+
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
5
|
+
onKeyDown?: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;
|
|
6
|
+
}
|
|
7
|
+
declare const AutoExpandingTextarea: React.ForwardRefExoticComponent<AutoExpandingTextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
|
|
8
|
+
export default AutoExpandingTextarea;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useRef, useEffect, forwardRef } from "react";
|
|
3
|
+
const AutoExpandingTextarea = forwardRef(({ value, onChange, onKeyDown, className, style, ...props }, ref) => {
|
|
4
|
+
const textareaRef = useRef(null);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
const el = ref?.current || textareaRef.current;
|
|
7
|
+
if (el) {
|
|
8
|
+
el.style.height = "auto";
|
|
9
|
+
const scrollHeight = el.scrollHeight;
|
|
10
|
+
const minHeight = 24; // one line height
|
|
11
|
+
const maxHeight = 160; // max ~5 lines
|
|
12
|
+
el.style.height = `${Math.min(Math.max(scrollHeight, minHeight), maxHeight)}px`;
|
|
13
|
+
}
|
|
14
|
+
}, [value]);
|
|
15
|
+
return (_jsx("textarea", { ref: ref || textareaRef, value: value, onChange: onChange, onKeyDown: (e) => {
|
|
16
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
17
|
+
e.preventDefault();
|
|
18
|
+
onKeyDown?.(e);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
onKeyDown?.(e);
|
|
22
|
+
}
|
|
23
|
+
}, placeholder: "Chat with me...", className: `w-full bg-white placeholder:text-gray-500 rounded-lg text-sm sm:text-base ${className}`, style: {
|
|
24
|
+
lineHeight: "1.5rem",
|
|
25
|
+
padding: "0.5rem 0.75rem",
|
|
26
|
+
minHeight: "1.5rem",
|
|
27
|
+
maxHeight: "160px",
|
|
28
|
+
outline: "none",
|
|
29
|
+
overflow: "hidden", // ← hide scrollbars
|
|
30
|
+
resize: "none", // ← remove corner handle
|
|
31
|
+
transition: "height 0.15s ease-out",
|
|
32
|
+
...style,
|
|
33
|
+
}, rows: 1, ...props }));
|
|
34
|
+
});
|
|
35
|
+
AutoExpandingTextarea.displayName = "AutoExpandingTextarea";
|
|
36
|
+
export default AutoExpandingTextarea;
|
|
@@ -9,11 +9,14 @@ export function InspirationMenu({ questions, onQuestionClick, onClose }) {
|
|
|
9
9
|
maxWidth: "20rem",
|
|
10
10
|
borderRadius: "0.75rem",
|
|
11
11
|
border: "1px solid rgba(85, 85, 85, 0.18)",
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
// Use opaque background to fully mask underlying text
|
|
13
|
+
backgroundColor: "#ffffff",
|
|
14
|
+
// Remove blur so underlying content does not bleed through visually
|
|
15
|
+
boxShadow: "0 8px 28px rgba(0, 0, 0, 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.6)",
|
|
14
16
|
padding: "0.625rem",
|
|
15
17
|
animation: "slideUpMenu 0.25s cubic-bezier(0.4, 0, 0.2, 1)",
|
|
16
|
-
|
|
18
|
+
// Ensure the popover sits above chat bubbles and other content
|
|
19
|
+
zIndex: 1000,
|
|
17
20
|
}, onClick: (e) => e.stopPropagation(), children: [_jsxs("div", { style: {
|
|
18
21
|
display: "flex",
|
|
19
22
|
justifyContent: "space-between",
|
|
@@ -27,7 +30,7 @@ export function InspirationMenu({ questions, onQuestionClick, onClose }) {
|
|
|
27
30
|
color: "rgba(0, 0, 0, 0.5)",
|
|
28
31
|
letterSpacing: "0.05em",
|
|
29
32
|
textTransform: "capitalize",
|
|
30
|
-
}, children: "
|
|
33
|
+
}, children: "Suggested" }), _jsx("button", { type: "button", onClick: onClose, style: {
|
|
31
34
|
padding: "0.25rem",
|
|
32
35
|
borderRadius: "0.375rem",
|
|
33
36
|
border: "1px solid rgba(255, 255, 255, 0.2)",
|
|
@@ -52,28 +55,25 @@ export function InspirationMenu({ questions, onQuestionClick, onClose }) {
|
|
|
52
55
|
}, children: _jsx(X, { style: { width: "0.875rem", height: "0.875rem" } }) })] }), _jsx("div", { style: { display: "flex", flexDirection: "column", gap: "0.375rem" }, children: questions.map((question, index) => (_jsx("button", { type: "button", onClick: () => onQuestionClick(question), style: {
|
|
53
56
|
padding: "0.5rem 0.75rem",
|
|
54
57
|
borderRadius: "1.3rem",
|
|
55
|
-
border: "1px solid rgba(
|
|
56
|
-
backgroundColor: "
|
|
57
|
-
color: "rgba(0, 0, 0, 0.
|
|
58
|
+
border: "1px solid rgba(0, 0, 0, 0.06)",
|
|
59
|
+
backgroundColor: "#ffffff",
|
|
60
|
+
color: "rgba(0, 0, 0, 0.85)",
|
|
58
61
|
fontSize: "0.75rem",
|
|
59
62
|
textAlign: "left",
|
|
60
63
|
cursor: "pointer",
|
|
61
64
|
transition: "all 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
|
|
62
|
-
|
|
63
|
-
WebkitBackdropFilter: "blur(20px) saturate(180%)",
|
|
64
|
-
boxShadow: "0 1px 2px rgba(0, 0, 0, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.3)",
|
|
65
|
+
boxShadow: "0 1px 2px rgba(0, 0, 0, 0.06)",
|
|
65
66
|
outline: "none",
|
|
66
67
|
lineHeight: "1.3",
|
|
67
68
|
}, onMouseEnter: (e) => {
|
|
68
|
-
e.currentTarget.style.backgroundColor = "rgba(0, 122, 255, 0.
|
|
69
|
-
e.currentTarget.style.borderColor = "rgba(0, 122, 255, 0.
|
|
69
|
+
e.currentTarget.style.backgroundColor = "rgba(0, 122, 255, 0.1)";
|
|
70
|
+
e.currentTarget.style.borderColor = "rgba(0, 122, 255, 0.25)";
|
|
70
71
|
e.currentTarget.style.transform = "translateY(-1px)";
|
|
71
|
-
e.currentTarget.style.boxShadow =
|
|
72
|
-
"0 3px 8px rgba(0, 122, 255, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.4)";
|
|
72
|
+
e.currentTarget.style.boxShadow = "0 3px 8px rgba(0, 122, 255, 0.12)";
|
|
73
73
|
}, onMouseLeave: (e) => {
|
|
74
|
-
e.currentTarget.style.backgroundColor = "
|
|
75
|
-
e.currentTarget.style.borderColor = "rgba(
|
|
74
|
+
e.currentTarget.style.backgroundColor = "#ffffff";
|
|
75
|
+
e.currentTarget.style.borderColor = "rgba(0, 0, 0, 0.06)";
|
|
76
76
|
e.currentTarget.style.transform = "translateY(0)";
|
|
77
|
-
e.currentTarget.style.boxShadow = "0 1px 2px rgba(0, 0, 0, 0.
|
|
77
|
+
e.currentTarget.style.boxShadow = "0 1px 2px rgba(0, 0, 0, 0.06)";
|
|
78
78
|
}, children: question }, index))) })] }));
|
|
79
79
|
}
|
|
@@ -16,9 +16,7 @@ interface MessageListProps {
|
|
|
16
16
|
messages: Message[];
|
|
17
17
|
isStreaming: boolean;
|
|
18
18
|
aiAvatarSrc?: string;
|
|
19
|
-
onClose?: () => void;
|
|
20
|
-
onExpand?: () => void;
|
|
21
19
|
size?: "m" | "l" | "xl" | "s" | "xs";
|
|
22
20
|
}
|
|
23
|
-
export declare function MessageList({ messages, isStreaming, aiAvatarSrc,
|
|
21
|
+
export declare function MessageList({ messages, isStreaming, aiAvatarSrc, size, }: MessageListProps): import("react/jsx-runtime").JSX.Element;
|
|
24
22
|
export {};
|
|
@@ -1,15 +1,31 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useRef, useEffect, useState
|
|
2
|
+
import { useRef, useEffect, useState } from "react";
|
|
3
3
|
import ReactMarkdown from "react-markdown";
|
|
4
4
|
import remarkGfm from "remark-gfm";
|
|
5
|
-
import { ExternalLink
|
|
6
|
-
export function MessageList({ messages, isStreaming, aiAvatarSrc = '',
|
|
5
|
+
import { ExternalLink } from "lucide-react";
|
|
6
|
+
export function MessageList({ messages, isStreaming, aiAvatarSrc = '', size = 'l', }) {
|
|
7
7
|
const messagesEndRef = useRef(null);
|
|
8
|
-
const [
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
const [expandedSourcesByMessageIndex, setExpandedSourcesByMessageIndex] = useState({});
|
|
9
|
+
const toggleSources = (messageIndex) => {
|
|
10
|
+
setExpandedSourcesByMessageIndex((prev) => ({
|
|
11
|
+
...prev,
|
|
12
|
+
[messageIndex]: !prev[messageIndex],
|
|
13
|
+
}));
|
|
14
|
+
};
|
|
15
|
+
const convertCitationLinksToUrls = (markdown, sources) => {
|
|
16
|
+
if (!markdown || !sources || sources.length === 0)
|
|
17
|
+
return markdown;
|
|
18
|
+
// Replace [text](N) where N is a positive integer referencing sources[N-1]
|
|
19
|
+
return markdown.replace(/\[([^\]]+)\]\((\d+)\)/g, (match, text, numStr) => {
|
|
20
|
+
const num = parseInt(numStr, 10);
|
|
21
|
+
if (Number.isNaN(num) || num < 1 || num > sources.length)
|
|
22
|
+
return match;
|
|
23
|
+
const url = sources[num - 1]?.url;
|
|
24
|
+
if (!url)
|
|
25
|
+
return match;
|
|
26
|
+
return `[${text}](${url})`;
|
|
27
|
+
});
|
|
28
|
+
};
|
|
13
29
|
useEffect(() => {
|
|
14
30
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
15
31
|
}, [messages]);
|
|
@@ -19,101 +35,39 @@ export function MessageList({ messages, isStreaming, aiAvatarSrc = '', onClose,
|
|
|
19
35
|
position: 'relative',
|
|
20
36
|
flex: 1,
|
|
21
37
|
overflowY: "auto",
|
|
22
|
-
marginTop: "
|
|
38
|
+
marginTop: "1.3rem",
|
|
23
39
|
display: "flex",
|
|
24
40
|
flexDirection: "column",
|
|
25
|
-
gap: "0.
|
|
41
|
+
gap: "0.5rem",
|
|
26
42
|
padding: "0.5rem",
|
|
27
43
|
borderRadius: "0.75rem",
|
|
28
44
|
backgroundColor: "rgba(255, 255, 255, 0.08)",
|
|
29
45
|
border: "1px solid rgba(255, 255, 255, 0.15)",
|
|
30
|
-
}, className: "custom-scrollbar", children: [
|
|
31
|
-
borderRadius: '1.3rem',
|
|
32
|
-
border: '1px solid rgba(255, 255, 255, 0.3)',
|
|
33
|
-
backgroundColor: 'rgba(255, 255, 255, 0.12)',
|
|
34
|
-
padding: '0.375rem',
|
|
35
|
-
display: 'flex',
|
|
36
|
-
alignItems: 'center',
|
|
37
|
-
justifyContent: 'center',
|
|
38
|
-
color: 'rgba(0, 0, 0, 0.75)',
|
|
39
|
-
transition: 'all 0.15s',
|
|
40
|
-
cursor: 'pointer',
|
|
41
|
-
outline: 'none',
|
|
42
|
-
boxShadow: 'inset 0 1px 0 rgba(255, 255, 255, 0.2)',
|
|
43
|
-
}, children: size === 'xl' ? _jsx(Minimize2, { style: { width: '0.9rem', height: '0.9rem' } }) : _jsx(Maximize2, { style: { width: '0.9rem', height: '0.9rem' } }) }), _jsx("span", { id: expandTooltipId, role: "tooltip", style: {
|
|
44
|
-
position: 'absolute',
|
|
45
|
-
top: 'calc(100% + 0.4rem)',
|
|
46
|
-
left: '50%',
|
|
47
|
-
transform: 'translateX(-50%)',
|
|
48
|
-
whiteSpace: 'nowrap',
|
|
49
|
-
background: 'rgba(0,0,0,0.9)',
|
|
50
|
-
color: '#fff',
|
|
51
|
-
padding: '4px 6px',
|
|
52
|
-
borderRadius: '1.3rem',
|
|
53
|
-
fontSize: '0.55rem',
|
|
54
|
-
boxShadow: '0 6px 18px rgba(0,0,0,0.35)',
|
|
55
|
-
opacity: hoverTopExpand ? 1 : 0,
|
|
56
|
-
pointerEvents: 'none',
|
|
57
|
-
transition: 'opacity 120ms ease-in-out',
|
|
58
|
-
zIndex: 30,
|
|
59
|
-
}, children: size === 'xl' ? 'Restore' : 'Expand' })] })), onClose && (_jsxs("div", { style: { position: 'relative' }, children: [_jsx("button", { type: "button", onClick: onClose, onMouseEnter: () => setHoverTopClose(true), onMouseLeave: () => setHoverTopClose(false), "aria-label": "Close", "aria-describedby": hoverTopClose ? xTooltipId : undefined, style: {
|
|
60
|
-
borderRadius: '1.3rem',
|
|
61
|
-
border: '1px solid rgba(255, 255, 255, 0.3)',
|
|
62
|
-
backgroundColor: 'rgba(255, 255, 255, 0.12)',
|
|
63
|
-
padding: '0.375rem',
|
|
64
|
-
display: 'flex',
|
|
65
|
-
alignItems: 'center',
|
|
66
|
-
justifyContent: 'center',
|
|
67
|
-
color: 'rgba(0, 0, 0, 0.75)',
|
|
68
|
-
transition: 'all 0.15s',
|
|
69
|
-
cursor: 'pointer',
|
|
70
|
-
outline: 'none',
|
|
71
|
-
boxShadow: 'inset 0 1px 0 rgba(255, 255, 255, 0.2)',
|
|
72
|
-
}, children: _jsx(X, { style: { width: '0.9rem', height: '0.9rem' } }) }), _jsx("span", { id: xTooltipId, role: "tooltip", style: {
|
|
73
|
-
position: 'absolute',
|
|
74
|
-
top: 'calc(100% + 0.4rem)',
|
|
75
|
-
left: '50%',
|
|
76
|
-
transform: 'translateX(-50%)',
|
|
77
|
-
whiteSpace: 'nowrap',
|
|
78
|
-
background: 'rgba(0,0,0,0.9)',
|
|
79
|
-
color: '#fff',
|
|
80
|
-
padding: '4px 6px',
|
|
81
|
-
borderRadius: '1.3rem',
|
|
82
|
-
fontSize: '0.55rem',
|
|
83
|
-
boxShadow: '0 6px 18px rgba(0,0,0,0.35)',
|
|
84
|
-
opacity: hoverTopClose ? 1 : 0,
|
|
85
|
-
pointerEvents: 'none',
|
|
86
|
-
transition: 'opacity 120ms ease-in-out',
|
|
87
|
-
zIndex: 30,
|
|
88
|
-
}, children: "Close" })] }))] }), messages.map((message, index) => (_jsxs("div", { style: {
|
|
46
|
+
}, className: "custom-scrollbar", children: [messages.map((message, index) => (_jsxs("div", { style: {
|
|
89
47
|
display: "flex",
|
|
90
|
-
|
|
91
|
-
alignItems: message.role === "user" ? "flex-end" : "flex-start",
|
|
48
|
+
justifyContent: message.role === "user" ? "flex-end" : "flex-start",
|
|
92
49
|
animation: "fadeIn 0.3s ease-in",
|
|
93
|
-
gap: "0.
|
|
50
|
+
gap: "0.4rem",
|
|
94
51
|
}, children: [_jsx("div", { style: {
|
|
95
52
|
display: "flex",
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
flexDirection: message.role === "user" ? "row-reverse" : "row"
|
|
53
|
+
gap: "0.4rem",
|
|
54
|
+
alignItems: message.role === "user" ? "flex-end" : "flex-start"
|
|
99
55
|
}, children: _jsx("div", { style: {
|
|
100
|
-
width: "1.
|
|
101
|
-
height:
|
|
102
|
-
borderRadius:
|
|
103
|
-
backgroundColor:
|
|
56
|
+
width: message.role === "user" ? "0" : "1.4rem",
|
|
57
|
+
height: message.role === "user" ? "0" : "auto",
|
|
58
|
+
borderRadius: "none",
|
|
59
|
+
backgroundColor: "transparent",
|
|
104
60
|
display: "flex",
|
|
105
61
|
alignItems: "center",
|
|
106
62
|
justifyContent: "center",
|
|
107
63
|
fontSize: "0.75rem",
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}, children: message.role === "user" ? (_jsx(User, { size: 16, color: "rgb(114, 126, 237)" })) : (aiAvatarSrc ? (_jsx("img", { src: aiAvatarSrc, alt: "AI Avatar", style: {
|
|
64
|
+
border: "none",
|
|
65
|
+
boxShadow: "none",
|
|
66
|
+
}, children: message.role === "user" ? (
|
|
67
|
+
// <User size={16} color="rgba(0, 0, 0, 1)" />
|
|
68
|
+
_jsx("div", {})) : (aiAvatarSrc ? (_jsx("img", { src: aiAvatarSrc, alt: "AI Avatar", style: {
|
|
114
69
|
width: "100%",
|
|
115
70
|
height: "100%",
|
|
116
|
-
borderRadius: "inherit",
|
|
117
71
|
objectFit: "cover"
|
|
118
72
|
} })) : (_jsx("div", { style: {
|
|
119
73
|
width: "100%",
|
|
@@ -122,34 +76,58 @@ export function MessageList({ messages, isStreaming, aiAvatarSrc = '', onClose,
|
|
|
122
76
|
alignItems: "center",
|
|
123
77
|
justifyContent: "center",
|
|
124
78
|
fontSize: "0.75rem",
|
|
125
|
-
color: "
|
|
79
|
+
color: "rgba(217, 219, 234, 1)"
|
|
126
80
|
}, children: "AI" }))) }) }), _jsxs("div", { style: {
|
|
127
81
|
maxWidth: "85%",
|
|
128
|
-
padding: message.role === "user" ? "0.275rem 0.
|
|
82
|
+
padding: message.role === "user" ? "0.275rem 0.5rem" : "0.5rem 0",
|
|
129
83
|
borderRadius: message.role === "user" ? "1rem" : "0",
|
|
130
84
|
fontSize: "0.875rem",
|
|
131
85
|
marginLeft: message.role === "user" ? "0" : "1rem",
|
|
132
86
|
marginRight: message.role === "user" ? "1rem" : "0",
|
|
133
|
-
lineHeight: "1.
|
|
87
|
+
lineHeight: "1.4",
|
|
134
88
|
backgroundColor: message.role === "user" ? "rgb(114, 126, 237)" : "transparent",
|
|
135
89
|
color: message.role === "user" ? "white" : "rgba(0, 0, 0, 0.85)",
|
|
136
90
|
border: message.role === "user" ? "1px solid rgba(255, 255, 255, 0.25)" : "none",
|
|
137
91
|
}, children: [message.role === "user" ? (_jsx("p", { style: { margin: 0, whiteSpace: "pre-wrap" }, children: message.content })) : (_jsx("div", { className: "markdown-content", style: {
|
|
138
92
|
fontSize: "0.875rem",
|
|
139
|
-
lineHeight: "1.
|
|
93
|
+
lineHeight: "1.4",
|
|
140
94
|
color: "rgba(0, 0, 0, 0.85)",
|
|
141
|
-
}, children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm],
|
|
142
|
-
|
|
143
|
-
|
|
95
|
+
}, children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components: {
|
|
96
|
+
a: ({ href, children, ...props }) => {
|
|
97
|
+
const hasSources = Array.isArray(message.sources) && message.sources.length > 0;
|
|
98
|
+
if (!hasSources) {
|
|
99
|
+
const anyProps = props;
|
|
100
|
+
return (_jsx("span", { className: anyProps?.className, style: anyProps?.style, children: children }));
|
|
101
|
+
}
|
|
102
|
+
return (_jsx("a", { href: href || '', target: "_blank", rel: "noopener noreferrer", ...props, children: children }));
|
|
103
|
+
},
|
|
104
|
+
}, children: convertCitationLinksToUrls(message.content, message.sources) }) })), message.role === "assistant" && message.sources && message.sources.length > 0 && (_jsxs("div", { style: {
|
|
105
|
+
marginTop: "0.25rem",
|
|
106
|
+
paddingTop: "0.25rem",
|
|
144
107
|
borderTop: "1px solid rgba(0, 0, 0, 0.1)",
|
|
145
|
-
}, children: [
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
108
|
+
}, children: [_jsxs("div", { style: {
|
|
109
|
+
display: "flex",
|
|
110
|
+
alignItems: "center",
|
|
111
|
+
justifyContent: "space-between",
|
|
112
|
+
gap: "0.5rem",
|
|
113
|
+
marginBottom: "0.25rem",
|
|
114
|
+
}, children: [_jsx("p", { style: {
|
|
115
|
+
fontSize: "0.65rem",
|
|
116
|
+
fontWeight: 600,
|
|
117
|
+
textTransform: "uppercase",
|
|
118
|
+
letterSpacing: "0.05em",
|
|
119
|
+
color: "rgba(0, 0, 0, 0.5)",
|
|
120
|
+
margin: 0,
|
|
121
|
+
}, children: "Sources" }), _jsx("button", { type: "button", onClick: () => toggleSources(index), style: {
|
|
122
|
+
borderRadius: "0.5rem",
|
|
123
|
+
border: "1px solid rgba(255, 255, 255, 0.3)",
|
|
124
|
+
backgroundColor: "rgba(255, 255, 255, 0.2)",
|
|
125
|
+
padding: "0.2rem 0.4rem",
|
|
126
|
+
fontSize: "0.7rem",
|
|
127
|
+
color: "rgba(0, 0, 0, 0.75)",
|
|
128
|
+
cursor: "pointer",
|
|
129
|
+
outline: "none",
|
|
130
|
+
}, children: expandedSourcesByMessageIndex[index] ? "Hide" : "Show" })] }), expandedSourcesByMessageIndex[index] && (_jsx("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: message.sources.map((source) => (_jsxs("a", { href: source.url, target: "_blank", rel: "noopener noreferrer", style: {
|
|
153
131
|
display: "flex",
|
|
154
132
|
alignItems: "center",
|
|
155
133
|
gap: "0.5rem",
|
|
@@ -167,8 +145,8 @@ export function MessageList({ messages, isStreaming, aiAvatarSrc = '', onClose,
|
|
|
167
145
|
borderRadius: "0.375rem",
|
|
168
146
|
fontSize: "0.65rem",
|
|
169
147
|
fontWeight: 600,
|
|
170
|
-
}, children: ["#", source.index] }), _jsx("span", { style: { flex: 1, wordBreak: "break-all" }, children: source.url }), _jsx(ExternalLink, { style: { width: "0.875rem", height: "0.875rem", opacity: 0.6 } })] }, source.index))) })] }))] })] }, index))), showThinkingDots && (_jsx("div", { style: { display: "flex", justifyContent: "flex-start" }, children: _jsxs("div", { style: {
|
|
171
|
-
padding: "0.
|
|
148
|
+
}, children: ["#", source.index] }), _jsx("span", { style: { flex: 1, wordBreak: "break-all" }, children: source.url }), _jsx(ExternalLink, { style: { width: "0.875rem", height: "0.875rem", opacity: 0.6 } })] }, source.index))) }))] }))] })] }, index))), showThinkingDots && (_jsx("div", { style: { display: "flex", justifyContent: "flex-start" }, children: _jsxs("div", { style: {
|
|
149
|
+
padding: "0.25rem 0.6rem",
|
|
172
150
|
borderRadius: "1rem",
|
|
173
151
|
display: "flex",
|
|
174
152
|
gap: "0.375rem",
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type React from "react";
|
|
2
2
|
interface SearchInputProps {
|
|
3
3
|
value: string;
|
|
4
|
-
onChange: (e: React.ChangeEvent<
|
|
4
|
+
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
5
5
|
onFocus: () => void;
|
|
6
6
|
onBlur: () => void;
|
|
7
7
|
placeholder: string;
|
|
8
8
|
size: "xs" | "s" | "m" | "l" | "xl";
|
|
9
|
-
inputRef: React.RefObject<
|
|
9
|
+
inputRef: React.RefObject<HTMLTextAreaElement>;
|
|
10
10
|
inspirationQuestions: string[];
|
|
11
11
|
onInspirationClick: (question: string) => void;
|
|
12
12
|
sparkleRef: React.RefObject<HTMLDivElement>;
|