goji-search 1.0.1 → 1.1.2
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 +42 -13
- package/dist/goji-search/components/elements/auto-expanding-textarea.d.ts +8 -0
- package/dist/goji-search/components/elements/auto-expanding-textarea.js +46 -0
- package/dist/goji-search/components/elements/inspiration-menu.d.ts +2 -1
- package/dist/goji-search/components/elements/inspiration-menu.js +43 -35
- package/dist/goji-search/components/elements/message-list.d.ts +1 -3
- package/dist/goji-search/components/elements/message-list.js +166 -158
- package/dist/goji-search/components/elements/search-input.d.ts +5 -3
- package/dist/goji-search/components/elements/search-input.js +83 -37
- package/dist/goji-search/components/elements/suggested-questions.js +35 -32
- package/dist/goji-search/components/goji-search-component.d.ts +9 -1
- package/dist/goji-search/components/goji-search-component.js +347 -173
- package/dist/goji-search/config/company.d.ts +1 -1
- package/dist/goji-search/config/company.js +39 -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,10 +49,7 @@ 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
54
|
border: "1px solid rgba(255, 255, 255, 0.3)",
|
|
58
55
|
backgroundColor: "rgba(255, 255, 255, 0.2)",
|
|
@@ -60,7 +57,6 @@ export function ActionButtons({ size, isHovered, isStreaming, searchQuery, onSub
|
|
|
60
57
|
display: "flex",
|
|
61
58
|
alignItems: "center",
|
|
62
59
|
justifyContent: "center",
|
|
63
|
-
outlineColor: "none",
|
|
64
60
|
color: "rgba(0, 0, 0, 0.75)",
|
|
65
61
|
backdropFilter: "blur(20px)",
|
|
66
62
|
WebkitBackdropFilter: "blur(20px)",
|
|
@@ -73,10 +69,44 @@ export function ActionButtons({ size, isHovered, isStreaming, searchQuery, onSub
|
|
|
73
69
|
e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.3)";
|
|
74
70
|
}, onMouseLeave: (e) => {
|
|
75
71
|
e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.2)";
|
|
76
|
-
}, children: _jsx(Mic, { style: {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
}, children: [_jsx(Mic, { style: {
|
|
73
|
+
width: size === "l" || size === "xl" ? "1rem" : "0.875rem",
|
|
74
|
+
height: size === "l" || size === "xl" ? "1rem" : "0.875rem",
|
|
75
|
+
} }), isRecording && (_jsxs("span", { "aria-hidden": "true", style: {
|
|
76
|
+
display: "inline-flex",
|
|
77
|
+
alignItems: "flex-end",
|
|
78
|
+
gap: "2px",
|
|
79
|
+
marginLeft: size === "l" || size === "xl" ? "6px" : "4px",
|
|
80
|
+
height: size === "l" || size === "xl" ? "1rem" : "0.875rem",
|
|
81
|
+
}, children: [_jsx("span", { style: {
|
|
82
|
+
width: "2px",
|
|
83
|
+
height: "55%",
|
|
84
|
+
backgroundColor: "rgba(0, 0, 0, 0.75)",
|
|
85
|
+
borderRadius: "1px",
|
|
86
|
+
transformOrigin: "bottom",
|
|
87
|
+
animation: "eqPulse 900ms ease-in-out 0ms infinite",
|
|
88
|
+
} }), _jsx("span", { style: {
|
|
89
|
+
width: "2px",
|
|
90
|
+
height: "85%",
|
|
91
|
+
backgroundColor: "rgba(0, 0, 0, 0.75)",
|
|
92
|
+
borderRadius: "1px",
|
|
93
|
+
transformOrigin: "bottom",
|
|
94
|
+
animation: "eqPulse 900ms ease-in-out 100ms infinite",
|
|
95
|
+
} }), _jsx("span", { style: {
|
|
96
|
+
width: "2px",
|
|
97
|
+
height: "65%",
|
|
98
|
+
backgroundColor: "rgba(0, 0, 0, 0.75)",
|
|
99
|
+
borderRadius: "1px",
|
|
100
|
+
transformOrigin: "bottom",
|
|
101
|
+
animation: "eqPulse 900ms ease-in-out 200ms infinite",
|
|
102
|
+
} }), _jsx("span", { style: {
|
|
103
|
+
width: "2px",
|
|
104
|
+
height: "78%",
|
|
105
|
+
backgroundColor: "rgba(0, 0, 0, 0.75)",
|
|
106
|
+
borderRadius: "1px",
|
|
107
|
+
transformOrigin: "bottom",
|
|
108
|
+
animation: "eqPulse 900ms ease-in-out 300ms infinite",
|
|
109
|
+
} })] }))] }), _jsx("span", { id: voiceTooltipId, role: "tooltip", style: {
|
|
80
110
|
position: "absolute",
|
|
81
111
|
top: "calc(100% + 0.4rem)",
|
|
82
112
|
left: "50%",
|
|
@@ -92,14 +122,13 @@ export function ActionButtons({ size, isHovered, isStreaming, searchQuery, onSub
|
|
|
92
122
|
pointerEvents: "none",
|
|
93
123
|
transition: "opacity 120ms ease-in-out",
|
|
94
124
|
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: {
|
|
125
|
+
}, 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
126
|
borderRadius: "1.3rem",
|
|
97
127
|
border: "1px solid rgba(255, 255, 255, 0.3)",
|
|
98
128
|
backgroundColor: "rgb(0, 0, 0)",
|
|
99
129
|
padding: size === "l" || size === "xl" ? "0.5rem" : "0.4rem",
|
|
100
130
|
display: size === "l" || size === "m" || size === "xl" ? "flex" : "none",
|
|
101
131
|
alignItems: "center",
|
|
102
|
-
outlineColor: "none",
|
|
103
132
|
justifyContent: "center",
|
|
104
133
|
color: "rgb(255, 255, 255)",
|
|
105
134
|
transition: "all 0.2s",
|
|
@@ -113,7 +142,7 @@ export function ActionButtons({ size, isHovered, isStreaming, searchQuery, onSub
|
|
|
113
142
|
marginLeft: "0.5rem",
|
|
114
143
|
fontSize: "0.7rem",
|
|
115
144
|
fontWeight: 400,
|
|
116
|
-
display: size === "m" ? "none" : "block",
|
|
145
|
+
display: size === "m" || searchQuery.length > 0 ? "none" : "block",
|
|
117
146
|
transition: "all 0.4s",
|
|
118
147
|
}, children: "Book a call" })] }), _jsx("span", { id: calendarTooltipId, role: "tooltip", style: {
|
|
119
148
|
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,46 @@
|
|
|
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
|
+
// Reset to minimum height when value is empty
|
|
9
|
+
if (!value || value.trim() === '') {
|
|
10
|
+
el.style.height = "24px";
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
el.style.height = "auto";
|
|
14
|
+
const scrollHeight = el.scrollHeight;
|
|
15
|
+
const minHeight = 24; // one line height
|
|
16
|
+
const maxHeight = 160; // max ~5 lines
|
|
17
|
+
el.style.height = `${Math.min(Math.max(scrollHeight, minHeight), maxHeight)}px`;
|
|
18
|
+
}
|
|
19
|
+
}, [value, ref]);
|
|
20
|
+
return (_jsx("textarea", { ref: ref || textareaRef, value: value, onChange: onChange, onKeyDown: (e) => {
|
|
21
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
22
|
+
e.preventDefault();
|
|
23
|
+
// Trigger form submission by finding parent form and calling submit
|
|
24
|
+
const form = e.currentTarget.closest('form');
|
|
25
|
+
if (form) {
|
|
26
|
+
form.requestSubmit(); // This triggers onSubmit handler
|
|
27
|
+
}
|
|
28
|
+
onKeyDown?.(e);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
onKeyDown?.(e);
|
|
32
|
+
}
|
|
33
|
+
}, placeholder: "Chat with me...", className: `w-full bg-white placeholder:text-gray-500 rounded-lg text-sm sm:text-base ${className}`, style: {
|
|
34
|
+
lineHeight: "1.5rem",
|
|
35
|
+
padding: "0.5rem 0.75rem",
|
|
36
|
+
minHeight: "1.5rem",
|
|
37
|
+
maxHeight: "160px",
|
|
38
|
+
outline: "none",
|
|
39
|
+
overflow: "hidden", // ← hide scrollbars
|
|
40
|
+
resize: "none", // ← remove corner handle
|
|
41
|
+
transition: "height 0.15s ease-out",
|
|
42
|
+
...style,
|
|
43
|
+
}, rows: 1, ...props }));
|
|
44
|
+
});
|
|
45
|
+
AutoExpandingTextarea.displayName = "AutoExpandingTextarea";
|
|
46
|
+
export default AutoExpandingTextarea;
|
|
@@ -2,6 +2,7 @@ interface InspirationMenuProps {
|
|
|
2
2
|
questions: string[];
|
|
3
3
|
onQuestionClick: (question: string) => void;
|
|
4
4
|
onClose: () => void;
|
|
5
|
+
suggestedLabel?: string;
|
|
5
6
|
}
|
|
6
|
-
export declare function InspirationMenu({ questions, onQuestionClick, onClose }: InspirationMenuProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function InspirationMenu({ questions, onQuestionClick, onClose, suggestedLabel }: InspirationMenuProps): import("react/jsx-runtime").JSX.Element;
|
|
7
8
|
export {};
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { X } from "lucide-react";
|
|
3
|
-
export function InspirationMenu({ questions, onQuestionClick, onClose }) {
|
|
4
|
-
return (_jsxs("div", { style: {
|
|
3
|
+
export function InspirationMenu({ questions, onQuestionClick, onClose, suggestedLabel = "Suggested" }) {
|
|
4
|
+
return (_jsxs("div", { "data-inspiration-menu": true, style: {
|
|
5
5
|
position: "absolute",
|
|
6
6
|
bottom: "calc(100% + 0.5rem)",
|
|
7
7
|
left: 0,
|
|
8
8
|
minWidth: "16rem",
|
|
9
9
|
maxWidth: "20rem",
|
|
10
10
|
borderRadius: "0.75rem",
|
|
11
|
-
border: "1px solid rgba(
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
border: "1px solid rgba(255, 255, 255, 0.35)",
|
|
12
|
+
// Glass-like background with transparency
|
|
13
|
+
backgroundColor: "rgba(255, 255, 255, 0.75)",
|
|
14
|
+
backdropFilter: "blur(24px) saturate(180%)",
|
|
15
|
+
WebkitBackdropFilter: "blur(24px) saturate(180%)",
|
|
16
|
+
boxShadow: "0 8px 28px rgba(0, 0, 0, 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.8)",
|
|
14
17
|
padding: "0.625rem",
|
|
15
18
|
animation: "slideUpMenu 0.25s cubic-bezier(0.4, 0, 0.2, 1)",
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
// Ensure the popover sits above chat bubbles and other content
|
|
20
|
+
zIndex: 1000,
|
|
21
|
+
}, onClick: (e) => e.stopPropagation(), onMouseEnter: (e) => e.stopPropagation(), onMouseLeave: onClose, children: [_jsxs("div", { style: {
|
|
18
22
|
display: "flex",
|
|
19
23
|
justifyContent: "space-between",
|
|
20
24
|
alignItems: "center",
|
|
@@ -27,7 +31,7 @@ export function InspirationMenu({ questions, onQuestionClick, onClose }) {
|
|
|
27
31
|
color: "rgba(0, 0, 0, 0.5)",
|
|
28
32
|
letterSpacing: "0.05em",
|
|
29
33
|
textTransform: "capitalize",
|
|
30
|
-
}, children:
|
|
34
|
+
}, children: suggestedLabel }), _jsx("button", { type: "button", onClick: onClose, style: {
|
|
31
35
|
padding: "0.25rem",
|
|
32
36
|
borderRadius: "0.375rem",
|
|
33
37
|
border: "1px solid rgba(255, 255, 255, 0.2)",
|
|
@@ -49,31 +53,35 @@ export function InspirationMenu({ questions, onQuestionClick, onClose }) {
|
|
|
49
53
|
e.currentTarget.style.backgroundColor = "rgba(255, 255, 255, 0.15)";
|
|
50
54
|
e.currentTarget.style.color = "rgba(0, 0, 0, 0.5)";
|
|
51
55
|
e.currentTarget.style.borderColor = "rgba(255, 255, 255, 0.2)";
|
|
52
|
-
}, 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) =>
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
e
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
56
|
+
}, 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) => {
|
|
57
|
+
const truncatedQuestion = question.length > 80 ? question.slice(0, 80) + '...' : question;
|
|
58
|
+
return (_jsx("button", { type: "button", onClick: () => onQuestionClick(question), title: question.length > 80 ? question : undefined, style: {
|
|
59
|
+
padding: "0.5rem 0.75rem",
|
|
60
|
+
borderRadius: "1.3rem",
|
|
61
|
+
border: "1px solid rgba(0, 0, 0, 0.06)",
|
|
62
|
+
backgroundColor: "#ffffff",
|
|
63
|
+
color: "rgba(0, 0, 0, 0.85)",
|
|
64
|
+
fontSize: "0.75rem",
|
|
65
|
+
fontWeight: 500,
|
|
66
|
+
textAlign: "left",
|
|
67
|
+
cursor: "pointer",
|
|
68
|
+
transition: "all 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
|
|
69
|
+
boxShadow: "0 1px 2px rgba(0, 0, 0, 0.06)",
|
|
70
|
+
outline: "none",
|
|
71
|
+
lineHeight: "1.3",
|
|
72
|
+
overflow: "hidden",
|
|
73
|
+
textOverflow: "ellipsis",
|
|
74
|
+
whiteSpace: "nowrap",
|
|
75
|
+
}, onMouseEnter: (e) => {
|
|
76
|
+
e.currentTarget.style.backgroundColor = "rgba(140, 110, 230, 0.12)";
|
|
77
|
+
e.currentTarget.style.borderColor = "rgba(140, 110, 230, 0.3)";
|
|
78
|
+
e.currentTarget.style.transform = "translateY(-1px)";
|
|
79
|
+
e.currentTarget.style.boxShadow = "0 3px 8px rgba(140, 110, 230, 0.15)";
|
|
80
|
+
}, onMouseLeave: (e) => {
|
|
81
|
+
e.currentTarget.style.backgroundColor = "#ffffff";
|
|
82
|
+
e.currentTarget.style.borderColor = "rgba(0, 0, 0, 0.06)";
|
|
83
|
+
e.currentTarget.style.transform = "translateY(0)";
|
|
84
|
+
e.currentTarget.style.boxShadow = "0 1px 2px rgba(0, 0, 0, 0.06)";
|
|
85
|
+
}, children: truncatedQuestion }, index));
|
|
86
|
+
}) })] }));
|
|
79
87
|
}
|
|
@@ -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 {};
|