@docsearch/react 4.6.3 → 5.0.0-beta.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.
Files changed (79) hide show
  1. package/README.md +0 -2
  2. package/dist/esm/AskAiScreenState-D0IZsCMJ.d.ts +106 -0
  3. package/dist/esm/DocSearch-Dq5Utfyb.d.ts +295 -0
  4. package/dist/esm/DocSearchAskAiModal-BwbMrrHv.d.ts +48 -0
  5. package/dist/esm/DocSearchAskAiModal-CCrk6YLb.js +954 -0
  6. package/dist/esm/DocSearchAskAiModal-CCrk6YLb.js.map +1 -0
  7. package/dist/esm/DocSearchButton-CRlNPf5k.d.ts +18 -0
  8. package/dist/esm/DocSearchButton-CaxxOzQU.js +71 -0
  9. package/dist/esm/DocSearchButton-CaxxOzQU.js.map +1 -0
  10. package/dist/esm/DocSearchModal-CpvDjo1O.js +250 -0
  11. package/dist/esm/DocSearchModal-CpvDjo1O.js.map +1 -0
  12. package/dist/esm/DocSearchTheme-DvL4mf0D.d.ts +5 -0
  13. package/dist/esm/askaiModal.d.ts +2 -0
  14. package/dist/esm/askaiModal.js +3 -0
  15. package/dist/esm/button.d.ts +2 -0
  16. package/dist/esm/button.js +3 -0
  17. package/dist/esm/docsearchAi.d.ts +220 -0
  18. package/dist/esm/docsearchAi.js +34 -0
  19. package/dist/esm/docsearchAi.js.map +1 -0
  20. package/dist/esm/index-Dl8FMlR5.d.ts +223 -0
  21. package/dist/esm/index.d.ts +9 -655
  22. package/dist/esm/index.js +35 -3
  23. package/dist/esm/index.js.map +1 -0
  24. package/dist/esm/keyboard-BkSdCzTU.js +9 -0
  25. package/dist/esm/keyboard-BkSdCzTU.js.map +1 -0
  26. package/dist/esm/keyboardShortcuts-C-lx6Xt7.js +25 -0
  27. package/dist/esm/keyboardShortcuts-C-lx6Xt7.js.map +1 -0
  28. package/dist/esm/modal.d.ts +2 -0
  29. package/dist/esm/modal.js +3 -0
  30. package/dist/esm/normalizeDocSearchIndexes-DAzlMybx.js +1240 -0
  31. package/dist/esm/normalizeDocSearchIndexes-DAzlMybx.js.map +1 -0
  32. package/dist/esm/objectSpread2-BNmiQYyW.js +67 -0
  33. package/dist/esm/objectWithoutProperties-phqYxDS0.js +53 -0
  34. package/dist/esm/objectWithoutProperties-phqYxDS0.js.map +1 -0
  35. package/dist/esm/sidepanel.d.ts +395 -0
  36. package/dist/esm/sidepanel.js +773 -0
  37. package/dist/esm/sidepanel.js.map +1 -0
  38. package/dist/esm/useDocSearchKeyboardEvents-68G8dw6c.d.ts +43 -0
  39. package/dist/esm/useDocSearchKeyboardEvents.d.ts +2 -41
  40. package/dist/esm/useDocSearchKeyboardEvents.js +43 -1
  41. package/dist/esm/useDocSearchKeyboardEvents.js.map +1 -0
  42. package/dist/esm/useSearchClient-mIHVB6ga.js +433 -0
  43. package/dist/esm/useSearchClient-mIHVB6ga.js.map +1 -0
  44. package/dist/esm/useSuggestedQuestions-D2TGVPsI.js +1112 -0
  45. package/dist/esm/useSuggestedQuestions-D2TGVPsI.js.map +1 -0
  46. package/dist/esm/useTheme.d.ts +7 -6
  47. package/dist/esm/useTheme.js +21 -1
  48. package/dist/esm/useTheme.js.map +1 -0
  49. package/dist/esm/version.d.ts +4 -2
  50. package/dist/esm/version.js +6 -1
  51. package/dist/esm/version.js.map +1 -0
  52. package/dist/umd/index.js +175 -5
  53. package/dist/umd/index.js.map +1 -1
  54. package/package.json +31 -34
  55. package/style/askai.js +1 -0
  56. package/button.js +0 -1
  57. package/dist/esm/DocSearchButton.d.ts +0 -18
  58. package/dist/esm/DocSearchButton.js +0 -1
  59. package/dist/esm/DocSearchModal.d.ts +0 -444
  60. package/dist/esm/DocSearchModal.js +0 -3
  61. package/dist/esm/Sidepanel.d.ts +0 -371
  62. package/dist/esm/Sidepanel.js +0 -3
  63. package/dist/umd/DocSearchModal.js +0 -5
  64. package/dist/umd/DocSearchModal.js.map +0 -1
  65. package/dist/umd/DocsearchButton.js +0 -3
  66. package/dist/umd/DocsearchButton.js.map +0 -1
  67. package/dist/umd/Sidepanel.js +0 -5
  68. package/dist/umd/Sidepanel.js.map +0 -1
  69. package/dist/umd/useDocSearchKeyboardEvents.js +0 -3
  70. package/dist/umd/useDocSearchKeyboardEvents.js.map +0 -1
  71. package/dist/umd/useTheme.js +0 -3
  72. package/dist/umd/useTheme.js.map +0 -1
  73. package/dist/umd/version.js +0 -3
  74. package/dist/umd/version.js.map +0 -1
  75. package/modal.js +0 -1
  76. package/sidepanel.js +0 -1
  77. package/useDocSearchKeyboardEvents.js +0 -1
  78. package/useTheme.js +0 -1
  79. package/version.js +0 -1
@@ -0,0 +1,773 @@
1
+ import { t as _objectSpread2 } from "./objectSpread2-BNmiQYyW.js";
2
+ import { n as isAppleDevice, t as ACTION_KEY_DEFAULT } from "./keyboard-BkSdCzTU.js";
3
+ import { n as SearchIcon, t as _objectWithoutProperties } from "./objectWithoutProperties-phqYxDS0.js";
4
+ import { a as AlgoliaLogo, f as RecentIcon, l as CloseIcon, m as LoadingIcon, p as SparklesIcon, t as useSearchClient } from "./useSearchClient-mIHVB6ga.js";
5
+ import { S as AlertIcon, _ as BackIcon, a as MemoizedMarkdown, b as MoreVerticalIcon, c as buildDummyAskAiHit, d as getMessageContent, f as isAIToolPart, g as ConversationPromptSuggestions, h as FeedbackActions, i as groupConsecutiveToolResults, l as extractLinksFromMessage, m as SourcesPanel, n as useAskAi, o as ToolCall, r as Menu, s as EMPTY_TOOLS, t as useSuggestedQuestions, u as getAgentPromptSuggestions, v as NewConversationIcon, x as StopIcon, y as ConversationHistoryIcon } from "./useSuggestedQuestions-D2TGVPsI.js";
6
+ import { version } from "./version.js";
7
+ import { DocSearch, useDocSearch } from "@docsearch/core";
8
+ import React, { Fragment, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
9
+ import { createPortal } from "react-dom";
10
+
11
+ //#region src/icons/SendIcon.tsx
12
+ const SendIcon = () => {
13
+ return /* @__PURE__ */ React.createElement("svg", {
14
+ xmlns: "http://www.w3.org/2000/svg",
15
+ width: "24",
16
+ height: "24",
17
+ viewBox: "0 0 24 24",
18
+ fill: "none",
19
+ stroke: "currentColor",
20
+ strokeWidth: "2",
21
+ strokeLinecap: "round",
22
+ strokeLinejoin: "round"
23
+ }, /* @__PURE__ */ React.createElement("path", { d: "m5 12 7-7 7 7" }), /* @__PURE__ */ React.createElement("path", { d: "M12 19V5" }));
24
+ };
25
+
26
+ //#endregion
27
+ //#region src/icons/ExpandIcon.tsx
28
+ const ExpandIcon = () => {
29
+ return /* @__PURE__ */ React.createElement("svg", {
30
+ xmlns: "http://www.w3.org/2000/svg",
31
+ width: "14",
32
+ height: "14",
33
+ viewBox: "0 0 13 13",
34
+ fill: "none"
35
+ }, /* @__PURE__ */ React.createElement("path", {
36
+ fillRule: "evenodd",
37
+ clipRule: "evenodd",
38
+ d: "M8 0.5C8 0.223858 8.22386 0 8.5 0H12.5C12.7761 0 13 0.223858 13 0.5V4.5C13 4.77614 12.7761 5 12.5 5C12.2239 5 12 4.77614 12 4.5V1.70711L8.18689 5.52022C7.99162 5.71548 7.67504 5.71548 7.47978 5.52022C7.28452 5.32496 7.28452 5.00838 7.47978 4.81311L11.2929 1H8.5C8.22386 1 8 0.776142 8 0.5ZM5.52022 7.47978C5.71548 7.67504 5.71548 7.99162 5.52022 8.18689L1.70711 12H4.5C4.77614 12 5 12.2239 5 12.5C5 12.7761 4.77614 13 4.5 13H0.5C0.223858 13 0 12.7761 0 12.5V8.5C0 8.22386 0.223858 8 0.5 8C0.776142 8 1 8.22386 1 8.5V11.2929L4.81311 7.47978C5.00838 7.28452 5.32496 7.28452 5.52022 7.47978Z",
39
+ fill: "currentColor"
40
+ }));
41
+ };
42
+
43
+ //#endregion
44
+ //#region src/icons/FolderIcon.tsx
45
+ const FolderIcon = () => {
46
+ return /* @__PURE__ */ React.createElement("svg", {
47
+ xmlns: "http://www.w3.org/2000/svg",
48
+ width: "18",
49
+ height: "18",
50
+ viewBox: "0 0 24 24",
51
+ fill: "none",
52
+ stroke: "currentColor",
53
+ strokeWidth: "2",
54
+ strokeLinecap: "round",
55
+ strokeLinejoin: "round"
56
+ }, /* @__PURE__ */ React.createElement("path", { d: "M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" }));
57
+ };
58
+
59
+ //#endregion
60
+ //#region src/icons/EditIcon.tsx
61
+ const EditIcon = () => {
62
+ return /* @__PURE__ */ React.createElement("svg", {
63
+ xmlns: "http://www.w3.org/2000/svg",
64
+ width: "18",
65
+ height: "18",
66
+ viewBox: "0 0 24 24",
67
+ fill: "none",
68
+ stroke: "currentColor",
69
+ strokeWidth: "2",
70
+ strokeLinecap: "round",
71
+ strokeLinejoin: "round"
72
+ }, /* @__PURE__ */ React.createElement("path", { d: "M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }), /* @__PURE__ */ React.createElement("path", { d: "M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z" }));
73
+ };
74
+
75
+ //#endregion
76
+ //#region src/useIsMobile.ts
77
+ const useIsMobile = () => {
78
+ const [isMobile, setIsMobile] = React.useState(false);
79
+ React.useEffect(() => {
80
+ const checkForMobile = () => {
81
+ const isMobileMediaQuery = window.matchMedia("(max-width: 768px)");
82
+ setIsMobile(isMobileMediaQuery.matches);
83
+ };
84
+ checkForMobile();
85
+ window.addEventListener("resize", checkForMobile);
86
+ return () => {
87
+ window.removeEventListener("resize", checkForMobile);
88
+ };
89
+ }, []);
90
+ return isMobile;
91
+ };
92
+
93
+ //#endregion
94
+ //#region src/Sidepanel/ConversationHistoryScreen.tsx
95
+ const ConversationHistoryScreen = ({ conversations, selectConversation }) => {
96
+ const [items, setItems] = React.useState(() => conversations.getAll());
97
+ const handleRemoveConversation = (item) => {
98
+ conversations.remove(item);
99
+ setItems(conversations.getAll());
100
+ };
101
+ return /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Sidepanel-ConversationHistoryScreen" }, /* @__PURE__ */ React.createElement("ul", null, items.map((item) => /* @__PURE__ */ React.createElement("li", {
102
+ key: item.objectID,
103
+ className: "DocSearch-Sidepanel-RecentConversation"
104
+ }, /* @__PURE__ */ React.createElement("a", {
105
+ href: item.url,
106
+ onClick: (e) => {
107
+ e.preventDefault();
108
+ e.stopPropagation();
109
+ selectConversation(item);
110
+ }
111
+ }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Sidepanel-RecentConversation-container" }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Sidepanel-RecentConversation-icon" }, /* @__PURE__ */ React.createElement(RecentIcon, null)), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Sidepanel-RecentConversation-content" }, /* @__PURE__ */ React.createElement("span", { className: "DocSearch-Sidepanel-RecentConversation-title" }, item.hierarchy.lvl1)), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Hit-action" }, /* @__PURE__ */ React.createElement("button", {
112
+ className: "DocSearch-Hit-action-button",
113
+ type: "button",
114
+ title: "Remove conversation from history",
115
+ onClick: (e) => {
116
+ e.preventDefault();
117
+ e.stopPropagation();
118
+ handleRemoveConversation(item);
119
+ }
120
+ }, /* @__PURE__ */ React.createElement(CloseIcon, null)))))))));
121
+ };
122
+
123
+ //#endregion
124
+ //#region src/Sidepanel/AggregatedSearchBlock.tsx
125
+ const before = "Searched for ";
126
+ const separator = ", ";
127
+ const lastSeparator = " and ";
128
+ const after = "";
129
+ function AggregatedSearchBlock({ queries }) {
130
+ return /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-MessageContent-Tool Tool--AggregatedResult" }, /* @__PURE__ */ React.createElement(SearchIcon, { size: 18 }), /* @__PURE__ */ React.createElement("span", null, /* @__PURE__ */ React.createElement("span", null, before), queries.map((q, idx) => /* @__PURE__ */ React.createElement(Fragment, { key: q + idx }, /* @__PURE__ */ React.createElement("span", { className: "DocSearch-AskAiScreen-MessageContent-Tool-Query" }, "\"", q, "\""), idx < queries.length - 2 && separator, idx === queries.length - 2 && lastSeparator)), after));
131
+ }
132
+
133
+ //#endregion
134
+ //#region src/Sidepanel/ConversationScreen.tsx
135
+ const ConversationExchange = React.forwardRef(({ exchange, translations = {}, isLastExchange, conversations, onFeedback, status, streamError, memoryEnabled, tools, onSelectPromptSuggestion }, conversationRef) => {
136
+ var _userMessage$metadata, _assistantMessage$met, _userContent$text;
137
+ const { userMessage, assistantMessage } = exchange;
138
+ const { reasoningText = "Reasoning...", thinkingText = "Thinking...", searchingText = "Searching...", relatedSourcesText, stoppedStreamingText = "You stopped this response", preToolCallText = "Searching...", toolCallResultText = "Searched for", copyButtonText = "Copy", copyButtonCopiedText = "Copied!", errorTitleText = "Chat error", savedMemoryToolResultText = "Saved to memory", memoryToolResultText = "Used memory to enhance results", suggestedPromptsTitleText = "Suggested prompts" } = translations;
139
+ const assistantContent = useMemo(() => getMessageContent(assistantMessage), [assistantMessage]);
140
+ const userContent = useMemo(() => getMessageContent(userMessage), [userMessage]);
141
+ const assistantParts = useMemo(() => groupConsecutiveToolResults((assistantMessage === null || assistantMessage === void 0 ? void 0 : assistantMessage.parts) || []), [assistantMessage]);
142
+ const urlsToDisplay = React.useMemo(() => extractLinksFromMessage(assistantMessage), [assistantMessage]);
143
+ const suggestedPrompts = React.useMemo(() => {
144
+ if (!isLastExchange) return [];
145
+ return getAgentPromptSuggestions((assistantMessage === null || assistantMessage === void 0 ? void 0 : assistantMessage.parts) || []);
146
+ }, [assistantMessage, isLastExchange]);
147
+ const wasStopped = ((_userMessage$metadata = userMessage.metadata) === null || _userMessage$metadata === void 0 ? void 0 : _userMessage$metadata.stopped) || (assistantMessage === null || assistantMessage === void 0 || (_assistantMessage$met = assistantMessage.metadata) === null || _assistantMessage$met === void 0 ? void 0 : _assistantMessage$met.stopped);
148
+ const isThinking = ["submitted", "streaming"].includes(status) && !assistantParts.some((part) => part.type !== "step-start");
149
+ const showActions = !wasStopped && (!isLastExchange || isLastExchange && status === "ready" && Boolean(assistantMessage));
150
+ const messageId = (assistantMessage === null || assistantMessage === void 0 ? void 0 : assistantMessage.id) || exchange.id;
151
+ return /* @__PURE__ */ React.createElement("div", {
152
+ className: "DocSearch-AskAiScreen-Response-Container",
153
+ ref: conversationRef
154
+ }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Response" }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Message DocSearch-AskAiScreen-Message--user" }, /* @__PURE__ */ React.createElement("p", { className: "DocSearch-AskAiScreen-Query" }, (_userContent$text = userContent === null || userContent === void 0 ? void 0 : userContent.text) !== null && _userContent$text !== void 0 ? _userContent$text : "")), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Message DocSearch-AskAiScreen-Message--assistant" }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-MessageContent" }, status === "error" && streamError && isLastExchange && /* @__PURE__ */ React.createElement("div", {
155
+ className: "DocSearch-AskAiScreen-Error",
156
+ role: "alert"
157
+ }, /* @__PURE__ */ React.createElement(AlertIcon, { "aria-hidden": "true" }), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Error-Content" }, /* @__PURE__ */ React.createElement("h4", { className: "DocSearch-AskAiScreen-Error-Title" }, errorTitleText), /* @__PURE__ */ React.createElement(MemoizedMarkdown, {
158
+ content: streamError.message,
159
+ copyButtonText: "",
160
+ copyButtonCopiedText: "",
161
+ isStreaming: false
162
+ }))), assistantParts.map((part, idx) => {
163
+ const index = idx;
164
+ if (part.type === "reasoning" && part.state === "streaming") return /* @__PURE__ */ React.createElement("div", {
165
+ key: index,
166
+ className: "DocSearch-AskAiScreen-MessageContent-Reasoning shimmer"
167
+ }, /* @__PURE__ */ React.createElement(LoadingIcon, { className: "DocSearch-AskAiScreen-SmallerLoadingIcon" }), /* @__PURE__ */ React.createElement("span", { className: "shimmer" }, reasoningText));
168
+ if (part.type === "aggregated-tool-call") return /* @__PURE__ */ React.createElement(AggregatedSearchBlock, {
169
+ key: index,
170
+ queries: part.queries
171
+ });
172
+ if (isAIToolPart(part)) return /* @__PURE__ */ React.createElement(ToolCall, {
173
+ key: index,
174
+ part,
175
+ translations: {
176
+ preToolCallText,
177
+ searchingText,
178
+ toolCallResultText,
179
+ savedMemoryToolResultText,
180
+ memoryToolResultText
181
+ },
182
+ tools,
183
+ memoryEnabled
184
+ });
185
+ if (typeof part === "string") return /* @__PURE__ */ React.createElement(MemoizedMarkdown, {
186
+ key: index,
187
+ content: part,
188
+ copyButtonText,
189
+ copyButtonCopiedText,
190
+ isStreaming: false
191
+ });
192
+ if (part.type === "text") return /* @__PURE__ */ React.createElement(MemoizedMarkdown, {
193
+ key: index,
194
+ content: part.text,
195
+ copyButtonText,
196
+ copyButtonCopiedText,
197
+ isStreaming: part.state === "streaming"
198
+ });
199
+ return null;
200
+ }), isThinking && isLastExchange && assistantParts.length === 0 && /* @__PURE__ */ React.createElement("div", {
201
+ className: "DocSearch-AskAiScreen-MessageContent-Thinking",
202
+ role: "status"
203
+ }, /* @__PURE__ */ React.createElement("span", { className: "shimmer" }, thinkingText), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-AskAi-Thinking-Skeleton shimmer" }), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-AskAi-Thinking-Skeleton DocSearch-AskAi-Thinking-Skeleton--short shimmer" }))), wasStopped && /* @__PURE__ */ React.createElement("p", { className: "DocSearck-AskAiScreen-MessageContent-Stopped" }, stoppedStreamingText)), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Answer-Footer" }, /* @__PURE__ */ React.createElement(SourcesPanel, {
204
+ links: urlsToDisplay,
205
+ titleText: relatedSourcesText
206
+ }), /* @__PURE__ */ React.createElement(FeedbackActions, {
207
+ isSidepanel: true,
208
+ id: messageId,
209
+ showActions,
210
+ latestAssistantMessageContent: (assistantContent === null || assistantContent === void 0 ? void 0 : assistantContent.text) || null,
211
+ translations,
212
+ conversations,
213
+ onFeedback
214
+ })), suggestedPrompts.length > 0 && /* @__PURE__ */ React.createElement(ConversationPromptSuggestions, {
215
+ title: suggestedPromptsTitleText,
216
+ suggestions: suggestedPrompts,
217
+ onSelectPromptSuggestion
218
+ })));
219
+ });
220
+ const ConversationScreen = memo(({ exchanges, translations = {}, handleFeedback, tools = EMPTY_TOOLS, status, conversations, streamError, memoryEnabled, onSelectPromptSuggestion }) => {
221
+ const { conversationDisclaimer = "Answers are generated with AI which can make mistakes. Verify responses." } = translations;
222
+ const mostRecentExchangeRef = React.useRef(null);
223
+ const totalExchanges = exchanges.length;
224
+ React.useEffect(() => {
225
+ if (mostRecentExchangeRef.current) mostRecentExchangeRef.current.scrollIntoView({
226
+ behavior: "smooth",
227
+ block: "start"
228
+ });
229
+ }, [totalExchanges]);
230
+ return /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Sidepanel-ConversationScreen" }, /* @__PURE__ */ React.createElement("p", { className: "DocSearch-Sidepanel-ConversationScreen-disclaimer" }, conversationDisclaimer), exchanges.slice().map((exchange, idx) => {
231
+ const isLastExchange = idx === exchanges.length - 1;
232
+ return /* @__PURE__ */ React.createElement(ConversationExchange, {
233
+ key: exchange.id,
234
+ exchange,
235
+ translations,
236
+ isLastExchange,
237
+ ref: isLastExchange ? mostRecentExchangeRef : null,
238
+ tools,
239
+ status,
240
+ conversations,
241
+ streamError,
242
+ memoryEnabled,
243
+ onFeedback: handleFeedback,
244
+ onSelectPromptSuggestion
245
+ });
246
+ }));
247
+ });
248
+
249
+ //#endregion
250
+ //#region src/Sidepanel/NewConversationScreen.tsx
251
+ const NewConversationScreen = ({ suggestedQuestions, onSelectQuestion, translations = {} }) => {
252
+ const { titleText = "How can I help you today?", introductionText = "I search through your documentation to help you find setup guides, feature details and troubleshooting tips, fast." } = translations;
253
+ return /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Sidepanel-NewConversationScreen" }, /* @__PURE__ */ React.createElement("h4", { className: "DocSearch-Sidepanel-Screen--title" }, titleText), /* @__PURE__ */ React.createElement("p", { className: "DocSearch-Sidepanel-Screen--introduction" }, introductionText), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Sidepanel-List" }, suggestedQuestions.map((q) => /* @__PURE__ */ React.createElement("button", {
254
+ key: q.objectID,
255
+ type: "button",
256
+ className: "DocSearch-Sidepanel-SuggestedQuestion",
257
+ title: "View conversation",
258
+ onClick: () => {
259
+ onSelectQuestion(q);
260
+ }
261
+ }, /* @__PURE__ */ React.createElement("span", null, q.question)))));
262
+ };
263
+
264
+ //#endregion
265
+ //#region src/Sidepanel/PromptForm.tsx
266
+ const MAX_PROMPT_ROWS = 8;
267
+ const PromptForm = React.forwardRef(({ exchanges, isStreaming, translations = {}, onSend, onStopStreaming }, ref) => {
268
+ const isMobile = useIsMobile();
269
+ const [userPrompt, setUserPrompt] = React.useState("");
270
+ const promptRef = React.useRef(null);
271
+ React.useImperativeHandle(ref, () => promptRef.current);
272
+ const { promptPlaceholderText = "Ask a question", promptAnsweringText = "Answering...", promptAskAnotherQuestionText = "Ask another question", promptDisclaimerText = "Answers are generated with AI which can make mistakes.", promptLabelText = "Press Enter to send, or Shift and Enter for new line.", promptAriaLabelText = "Prompt input" } = translations;
273
+ const managePromptHeight = () => {
274
+ if (!promptRef.current) return;
275
+ const textArea = promptRef.current;
276
+ const styles = getComputedStyle(textArea);
277
+ const lineHeight = parseFloat(styles.lineHeight);
278
+ const padding = parseFloat(styles.paddingTop) + parseFloat(styles.paddingBottom);
279
+ textArea.style.height = "auto";
280
+ const fullHeight = textArea.scrollHeight;
281
+ const maxHeight = MAX_PROMPT_ROWS * lineHeight + padding;
282
+ textArea.style.overflowY = fullHeight > maxHeight ? "auto" : "hidden";
283
+ textArea.style.height = `${Math.min(fullHeight, maxHeight)}px`;
284
+ };
285
+ const handleSend = () => {
286
+ if (isStreaming) return;
287
+ const prompt = userPrompt.trim();
288
+ if (prompt === "") return;
289
+ onSend(prompt);
290
+ setUserPrompt("");
291
+ requestAnimationFrame(() => {
292
+ var _promptRef$current;
293
+ (_promptRef$current = promptRef.current) === null || _promptRef$current === void 0 || _promptRef$current.focus();
294
+ managePromptHeight();
295
+ });
296
+ };
297
+ const handleKeyDown = (e) => {
298
+ if (isStreaming) return;
299
+ if (e.key === "Enter" && !e.shiftKey) {
300
+ e.preventDefault();
301
+ handleSend();
302
+ }
303
+ };
304
+ React.useLayoutEffect(() => {
305
+ managePromptHeight();
306
+ }, [isMobile]);
307
+ let promptPlaceholder = promptPlaceholderText;
308
+ if (isStreaming) promptPlaceholder = promptAnsweringText;
309
+ else if (exchanges.length > 0) promptPlaceholder = promptAskAnotherQuestionText;
310
+ return /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Sidepanel-Prompt" }, /* @__PURE__ */ React.createElement("form", {
311
+ className: "DocSearch-Sidepanel-Prompt--form",
312
+ onSubmit: (e) => {
313
+ e.preventDefault();
314
+ if (isStreaming) return;
315
+ handleSend();
316
+ }
317
+ }, /* @__PURE__ */ React.createElement("textarea", {
318
+ ref: promptRef,
319
+ placeholder: promptPlaceholder,
320
+ className: "DocSearch-Sidepanel-Prompt--textarea",
321
+ value: userPrompt,
322
+ "aria-label": promptAriaLabelText,
323
+ "aria-labelledby": "prompt-label",
324
+ autoComplete: "off",
325
+ translate: "no",
326
+ rows: isMobile ? 1 : 2,
327
+ onKeyDown: handleKeyDown,
328
+ onInput: managePromptHeight,
329
+ onChange: (e) => setUserPrompt(e.target.value)
330
+ }), /* @__PURE__ */ React.createElement("span", {
331
+ id: "prompt-label",
332
+ className: "sr-only"
333
+ }, promptLabelText), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Sidepanel-Prompt--actions" }, isStreaming && /* @__PURE__ */ React.createElement("button", {
334
+ type: "button",
335
+ title: "Stop streaming",
336
+ className: "DocSearch-Sidepanel-Prompt--stop",
337
+ onClick: onStopStreaming
338
+ }, /* @__PURE__ */ React.createElement(StopIcon, null)), !isStreaming && /* @__PURE__ */ React.createElement("button", {
339
+ type: "submit",
340
+ "aria-label": "Send question",
341
+ title: "Send question",
342
+ className: "DocSearch-Sidepanel-Prompt--submit",
343
+ "aria-disabled": userPrompt === ""
344
+ }, /* @__PURE__ */ React.createElement(SendIcon, null)))), /* @__PURE__ */ React.createElement("p", { className: "DocSearch-Sidepanel-Prompt--disclaimer" }, promptDisclaimerText));
345
+ });
346
+
347
+ //#endregion
348
+ //#region src/Sidepanel/setSidepanelSearchClient.ts
349
+ const setSidepanelSearchClient = (client) => {
350
+ if (/docsearch-sidepanel.js \(.*\)/.test(client.transporter.algoliaAgent.value) === false) client.addAlgoliaAgent("docsearch-sidepanel", version);
351
+ return client;
352
+ };
353
+
354
+ //#endregion
355
+ //#region src/Sidepanel/SidepanelHeader.tsx
356
+ const BackButton = ({ onBack, mobile = false, disabled = false }) => {
357
+ return /* @__PURE__ */ React.createElement("button", {
358
+ type: "button",
359
+ className: `DocSearch-Action DocSearch-Sidepanel-Action-back${mobile ? " mobile" : ""}`,
360
+ title: "Go back to previous screen",
361
+ "aria-disabled": disabled,
362
+ onClick: disabled ? void 0 : onBack
363
+ }, /* @__PURE__ */ React.createElement(BackIcon, null));
364
+ };
365
+ const SidepanelHeader = React.memo(({ sidepanelState, exchanges, setSidepanelState, onNewConversation, onToggleExpanded, onClose, translations = {}, hasConversations, isStreaming }) => {
366
+ const { title = "Ask AI", conversationHistoryTitle = "My conversation history", newConversationText = "Start a new conversation", viewConversationHistoryText = "Conversation history" } = translations;
367
+ const isMobile = useIsMobile();
368
+ const goToConversationHistory = () => {
369
+ setSidepanelState("conversation-history");
370
+ };
371
+ const onBack = React.useCallback(() => {
372
+ if (exchanges.length > 0) setSidepanelState("conversation");
373
+ else setSidepanelState("new-conversation");
374
+ }, [exchanges, setSidepanelState]);
375
+ const newConversationDisabled = sidepanelState === "new-conversation" && exchanges.length < 1;
376
+ let header = title;
377
+ if (sidepanelState === "conversation-history") header = conversationHistoryTitle;
378
+ if (isMobile) header = title;
379
+ return /* @__PURE__ */ React.createElement("header", { className: "DocSearch-Sidepanel-Header" }, /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Sidepanel-Header--left" }, /* @__PURE__ */ React.createElement(BackButton, {
380
+ mobile: true,
381
+ disabled: isStreaming,
382
+ onBack
383
+ }), sidepanelState === "conversation-history" && /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Divider" }), /* @__PURE__ */ React.createElement("button", {
384
+ type: "button",
385
+ className: "DocSearch-Action",
386
+ title: newConversationText,
387
+ onClick: onNewConversation
388
+ }, /* @__PURE__ */ React.createElement(EditIcon, null)), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Divider" }), /* @__PURE__ */ React.createElement("button", {
389
+ type: "button",
390
+ className: "DocSearch-Action",
391
+ title: viewConversationHistoryText,
392
+ onClick: goToConversationHistory
393
+ }, /* @__PURE__ */ React.createElement(FolderIcon, null))), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Sidepanel-Header--center" }, /* @__PURE__ */ React.createElement(BackButton, {
394
+ disabled: isStreaming,
395
+ onBack
396
+ }), /* @__PURE__ */ React.createElement(SparklesIcon, { className: "DocSearch-Sidepanel-Header-TitleIcon" }), /* @__PURE__ */ React.createElement("h2", { className: "DocSearch-Sidepanel-Title" }, header)), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Sidepanel-Header--right" }, sidepanelState !== "conversation-history" && (!newConversationDisabled || hasConversations) && /* @__PURE__ */ React.createElement(Menu, null, /* @__PURE__ */ React.createElement(Menu.Trigger, {
397
+ className: "DocSearch-Action DocSearch-Sidepanel-Action-menu",
398
+ disabled: isStreaming
399
+ }, /* @__PURE__ */ React.createElement(MoreVerticalIcon, null)), /* @__PURE__ */ React.createElement(Menu.Content, null, !newConversationDisabled && /* @__PURE__ */ React.createElement(Menu.Item, { onClick: onNewConversation }, /* @__PURE__ */ React.createElement(NewConversationIcon, null), newConversationText), hasConversations && /* @__PURE__ */ React.createElement(Menu.Item, { onClick: goToConversationHistory }, /* @__PURE__ */ React.createElement(ConversationHistoryIcon, null), viewConversationHistoryText))), /* @__PURE__ */ React.createElement("button", {
400
+ type: "button",
401
+ className: "DocSearch-Action DocSearch-Sidepanel-Action-expand",
402
+ title: "Expand or collapse Sidepanel",
403
+ onClick: onToggleExpanded
404
+ }, /* @__PURE__ */ React.createElement(ExpandIcon, null)), /* @__PURE__ */ React.createElement("button", {
405
+ type: "button",
406
+ className: "DocSearch-Action DocSearch-Sidepanel-Action-close",
407
+ title: "Close Sidepanel",
408
+ onClick: onClose
409
+ }, /* @__PURE__ */ React.createElement(CloseIcon, null))));
410
+ });
411
+
412
+ //#endregion
413
+ //#region src/Sidepanel/useManageSidepanelLayout.ts
414
+ function useManageSidepanelLayout({ variant, selectors, isOpen, expectedWidth, side }) {
415
+ const targetRef = useRef(null);
416
+ const lastSelectorRef = useRef(null);
417
+ const isMobile = useIsMobile();
418
+ useLayoutEffect(() => {
419
+ if (variant === "floating" || isMobile) return;
420
+ if (lastSelectorRef.current !== selectors) {
421
+ if (targetRef.current) {
422
+ if (side === "left") targetRef.current.style.marginLeft = "";
423
+ else targetRef.current.style.marginRight = "";
424
+ targetRef.current.style.transition = "";
425
+ }
426
+ const nextTarget = Array.from(document.querySelectorAll(selectors))[0] || document.body;
427
+ targetRef.current = nextTarget;
428
+ lastSelectorRef.current = selectors;
429
+ if (targetRef.current) targetRef.current.style.transition = `margin-${side} 280ms cubic-bezier(0.22, 1, 0.36, 1)`;
430
+ }
431
+ const target = targetRef.current;
432
+ if (!target) return;
433
+ const offset = isOpen ? expectedWidth : "0px";
434
+ if (side === "left") target.style.marginLeft = offset;
435
+ else target.style.marginRight = offset;
436
+ }, [
437
+ isOpen,
438
+ expectedWidth,
439
+ variant,
440
+ selectors,
441
+ side,
442
+ isMobile
443
+ ]);
444
+ useLayoutEffect(() => {
445
+ return () => {
446
+ if (targetRef.current) {
447
+ if (side === "left") targetRef.current.style.marginLeft = "";
448
+ else targetRef.current.style.marginRight = "";
449
+ targetRef.current.style.transition = "";
450
+ }
451
+ };
452
+ }, [side]);
453
+ }
454
+
455
+ //#endregion
456
+ //#region src/Sidepanel/useSidepanelKeyboardEvents.ts
457
+ function useSidepanelKeyboardEvents({ onClose, onOpen, isOpen, keyboardShortcuts }) {
458
+ useEffect(() => {
459
+ function onKeyDown(e) {
460
+ var _e$key;
461
+ if (isOpen && e.code === "Escape") {
462
+ onClose();
463
+ return;
464
+ }
465
+ if (!((keyboardShortcuts === null || keyboardShortcuts === void 0 ? void 0 : keyboardShortcuts["Ctrl/Cmd+I"]) !== false)) return;
466
+ if (((_e$key = e.key) === null || _e$key === void 0 ? void 0 : _e$key.toLowerCase()) === "i" && (e.metaKey || e.ctrlKey)) {
467
+ e.preventDefault();
468
+ if (isOpen) onClose();
469
+ else onOpen();
470
+ }
471
+ }
472
+ window.addEventListener("keydown", onKeyDown);
473
+ return () => {
474
+ window.removeEventListener("keydown", onKeyDown);
475
+ };
476
+ }, [
477
+ isOpen,
478
+ onClose,
479
+ onOpen,
480
+ keyboardShortcuts
481
+ ]);
482
+ }
483
+
484
+ //#endregion
485
+ //#region src/Sidepanel/useSidepanelWidth.ts
486
+ const BASE_WIDTH = 360;
487
+ const EXPANDED_WIDTH = 580;
488
+ const useSidepanelWidth = ({ isExpanded, width, expandedWidth }) => {
489
+ const baseWidth = React.useMemo(() => {
490
+ return typeof width === "number" ? `${width}px` : width !== null && width !== void 0 ? width : `${BASE_WIDTH}px`;
491
+ }, [width]);
492
+ const resolvedExpandedWidth = React.useMemo(() => {
493
+ return typeof expandedWidth === "number" ? `${expandedWidth}px` : expandedWidth !== null && expandedWidth !== void 0 ? expandedWidth : `${EXPANDED_WIDTH}px`;
494
+ }, [expandedWidth]);
495
+ return isExpanded ? resolvedExpandedWidth : baseWidth;
496
+ };
497
+
498
+ //#endregion
499
+ //#region src/Sidepanel/Sidepanel.tsx
500
+ function SidepanelInner({ isOpen = false, onOpen, onClose, assistantId, apiKey, appId, indexName, variant = "floating", searchParameters, pushSelector, width, expandedWidth, suggestedQuestions: suggestedQuestionsEnabled = false, translations = {}, keyboardShortcuts, side = "right", initialMessage, tools = EMPTY_TOOLS, memory, indices }, ref) {
501
+ var _memory$enabled;
502
+ const [isExpanded, setIsExpanded] = React.useState(false);
503
+ const [sidepanelState, setSidepanelState] = React.useState("new-conversation");
504
+ const [stoppedStreaming, setStoppedStreaming] = React.useState(false);
505
+ const sidepanelContainerRef = React.useRef(null);
506
+ const promptInputRef = React.useRef(null);
507
+ const isMobile = useIsMobile();
508
+ const expectedWidth = useSidepanelWidth({
509
+ isExpanded,
510
+ width,
511
+ expandedWidth
512
+ });
513
+ const selectors = React.useMemo(() => pushSelector !== null && pushSelector !== void 0 ? pushSelector : "#root, main, .app, body", [pushSelector]);
514
+ const toggleIsExpanded = useCallback(() => {
515
+ setIsExpanded(!isExpanded);
516
+ }, [isExpanded]);
517
+ const searchClient = useSearchClient(appId, apiKey, setSidepanelSearchClient);
518
+ const { chatId, status, sendMessage, stopAskAiStreaming, isStreaming, exchanges, conversations, messages, sendFeedback, askAiError, startNewConversation, restoreConversation } = useAskAi({
519
+ appId,
520
+ indexName,
521
+ assistantId,
522
+ apiKey,
523
+ searchParameters,
524
+ tools,
525
+ memory,
526
+ indices
527
+ });
528
+ const suggestedQuestions = useSuggestedQuestions({
529
+ assistantId,
530
+ suggestedQuestionsEnabled,
531
+ searchClient
532
+ });
533
+ const prevStatus = React.useRef(status);
534
+ const handleSend = React.useCallback((prompt) => {
535
+ setStoppedStreaming(false);
536
+ sendMessage({ text: prompt });
537
+ setSidepanelState("conversation");
538
+ }, [sendMessage]);
539
+ const handleStartNewConversation = () => {
540
+ startNewConversation();
541
+ setSidepanelState("new-conversation");
542
+ };
543
+ const handleSelectQuestion = (question) => {
544
+ setStoppedStreaming(false);
545
+ startNewConversation();
546
+ sendMessage({ text: question.question }, { body: { suggestedQuestionId: question.objectID } });
547
+ setSidepanelState("conversation");
548
+ };
549
+ const handleStopStreaming = () => {
550
+ setStoppedStreaming(true);
551
+ stopAskAiStreaming();
552
+ };
553
+ const handleSelectConversation = React.useCallback((conversation) => {
554
+ if (conversation.messages) restoreConversation(conversation.messages, conversation.chatId);
555
+ else if (conversation.query) sendMessage({ text: conversation.query });
556
+ setSidepanelState("conversation");
557
+ }, [sendMessage, restoreConversation]);
558
+ useManageSidepanelLayout({
559
+ variant,
560
+ expectedWidth,
561
+ selectors,
562
+ isOpen,
563
+ side
564
+ });
565
+ useSidepanelKeyboardEvents({
566
+ onClose,
567
+ onOpen,
568
+ isOpen,
569
+ keyboardShortcuts
570
+ });
571
+ React.useImperativeHandle(ref, () => ({
572
+ open: onOpen,
573
+ close: onClose,
574
+ get isReady() {
575
+ return true;
576
+ },
577
+ get isOpen() {
578
+ return isOpen;
579
+ }
580
+ }), [
581
+ onOpen,
582
+ onClose,
583
+ isOpen
584
+ ]);
585
+ React.useEffect(() => {
586
+ if (prevStatus.current === "streaming" && status === "ready") {
587
+ if (stoppedStreaming && messages.at(-1)) messages.at(-1).metadata = { stopped: true };
588
+ for (const part of messages[0].parts) if (part.type === "text") conversations.add(buildDummyAskAiHit(part.text, messages, chatId));
589
+ }
590
+ prevStatus.current = status;
591
+ }, [
592
+ conversations,
593
+ status,
594
+ messages,
595
+ stoppedStreaming,
596
+ chatId
597
+ ]);
598
+ React.useEffect(() => {
599
+ function setFullViewportHeight() {
600
+ if (sidepanelContainerRef.current) {
601
+ const vh = window.innerHeight * .01;
602
+ sidepanelContainerRef.current.style.setProperty("--sp-vh", `${vh}px`);
603
+ }
604
+ }
605
+ setFullViewportHeight();
606
+ window.addEventListener("resize", setFullViewportHeight);
607
+ return () => {
608
+ window.removeEventListener("resize", setFullViewportHeight);
609
+ };
610
+ }, []);
611
+ React.useEffect(() => {
612
+ if (!initialMessage) return;
613
+ let selectedConversation;
614
+ if (initialMessage.messageId) {
615
+ var _conversations$getCon;
616
+ selectedConversation = (_conversations$getCon = conversations.getConversation) === null || _conversations$getCon === void 0 ? void 0 : _conversations$getCon.call(conversations, initialMessage.messageId);
617
+ }
618
+ if (selectedConversation) handleSelectConversation(selectedConversation);
619
+ else {
620
+ startNewConversation();
621
+ sendMessage({ text: initialMessage.query }, initialMessage.suggestedQuestionId ? { body: { suggestedQuestionId: initialMessage.suggestedQuestionId } } : {});
622
+ setSidepanelState("conversation");
623
+ }
624
+ }, [
625
+ initialMessage,
626
+ sendMessage,
627
+ conversations,
628
+ handleSelectConversation,
629
+ startNewConversation
630
+ ]);
631
+ React.useEffect(() => {
632
+ if (isOpen && !isMobile) {
633
+ var _promptInputRef$curre;
634
+ (_promptInputRef$curre = promptInputRef.current) === null || _promptInputRef$curre === void 0 || _promptInputRef$curre.focus();
635
+ }
636
+ if (!isOpen) {
637
+ var _promptInputRef$curre2;
638
+ (_promptInputRef$curre2 = promptInputRef.current) === null || _promptInputRef$curre2 === void 0 || _promptInputRef$curre2.blur();
639
+ }
640
+ }, [isOpen, isMobile]);
641
+ return /* @__PURE__ */ React.createElement("div", {
642
+ className: `DocSearch-Sidepanel-Container ${variant} side-${side}${isOpen ? " is-open" : ""}${isExpanded ? " is-expanded" : ""}`,
643
+ style: { "--sp-width": expectedWidth },
644
+ role: "dialog",
645
+ tabIndex: -1,
646
+ ref: sidepanelContainerRef
647
+ }, /* @__PURE__ */ React.createElement("aside", {
648
+ id: "docsearch-sidepanel",
649
+ className: `DocSearch-Sidepanel ${sidepanelState}`
650
+ }, /* @__PURE__ */ React.createElement(SidepanelHeader, {
651
+ sidepanelState,
652
+ exchanges,
653
+ setSidepanelState,
654
+ hasConversations: conversations.getAll().length > 0,
655
+ isStreaming,
656
+ onNewConversation: handleStartNewConversation,
657
+ onToggleExpanded: toggleIsExpanded,
658
+ onClose
659
+ }), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-Sidepanel-Content" }, sidepanelState === "new-conversation" && /* @__PURE__ */ React.createElement(NewConversationScreen, {
660
+ suggestedQuestions,
661
+ translations: translations.newConversationScreen,
662
+ onSelectQuestion: handleSelectQuestion
663
+ }), sidepanelState === "conversation" && /* @__PURE__ */ React.createElement(ConversationScreen, {
664
+ exchanges,
665
+ status,
666
+ conversations,
667
+ handleFeedback: sendFeedback,
668
+ translations: translations.conversationScreen,
669
+ streamError: askAiError,
670
+ memoryEnabled: (_memory$enabled = memory === null || memory === void 0 ? void 0 : memory.enabled) !== null && _memory$enabled !== void 0 ? _memory$enabled : false,
671
+ tools,
672
+ onSelectPromptSuggestion: handleSend
673
+ }), sidepanelState === "conversation-history" && /* @__PURE__ */ React.createElement(ConversationHistoryScreen, {
674
+ conversations,
675
+ selectConversation: handleSelectConversation
676
+ })), /* @__PURE__ */ React.createElement(PromptForm, {
677
+ ref: promptInputRef,
678
+ exchanges,
679
+ isStreaming,
680
+ translations: translations.promptForm,
681
+ onSend: handleSend,
682
+ onStopStreaming: handleStopStreaming
683
+ }), /* @__PURE__ */ React.createElement("footer", { className: "DocSearch-Sidepanel-Footer" }, /* @__PURE__ */ React.createElement("span", { className: "DocSearch-Logo DocSearch-Sidepanel--powered-by" }, /* @__PURE__ */ React.createElement(AlgoliaLogo, { translations: translations.logo })))));
684
+ }
685
+ const Sidepanel = React.forwardRef(SidepanelInner);
686
+
687
+ //#endregion
688
+ //#region src/Sidepanel/SidepanelButton.tsx
689
+ const _excluded$1 = [
690
+ "variant",
691
+ "keyboardShortcuts",
692
+ "translations"
693
+ ];
694
+ const SidepanelButton = (_ref) => {
695
+ let { variant = "floating", keyboardShortcuts, translations = {} } = _ref, props = _objectWithoutProperties(_ref, _excluded$1);
696
+ const { buttonText = "Ask AI", buttonAriaLabel = "Ask AI" } = translations;
697
+ const [key, setKey] = useState(null);
698
+ useEffect(() => {
699
+ if (typeof navigator !== "undefined") isAppleDevice() ? setKey("⌘") : setKey(ACTION_KEY_DEFAULT);
700
+ }, []);
701
+ const actionKeyAltText = key === "Ctrl" ? "Control" : "Meta";
702
+ const isCtrlCmdIEnabled = (keyboardShortcuts === null || keyboardShortcuts === void 0 ? void 0 : keyboardShortcuts["Ctrl/Cmd+I"]) !== false;
703
+ const shortcut = `${actionKeyAltText}+i`;
704
+ return /* @__PURE__ */ React.createElement("button", _objectSpread2(_objectSpread2({
705
+ className: `DocSearch-SidepanelButton ${variant}`,
706
+ type: "button",
707
+ "aria-label": isCtrlCmdIEnabled ? `${buttonAriaLabel} (${shortcut})` : buttonAriaLabel,
708
+ "aria-keyshortcuts": isCtrlCmdIEnabled ? shortcut : void 0
709
+ }, variant === "floating" ? { tabIndex: -1 } : {}), props), /* @__PURE__ */ React.createElement(SparklesIcon, null), variant !== "floating" && buttonText);
710
+ };
711
+
712
+ //#endregion
713
+ //#region src/Sidepanel.tsx
714
+ const _excluded = [
715
+ "keyboardShortcuts",
716
+ "theme",
717
+ "onReady",
718
+ "onOpen",
719
+ "onClose",
720
+ "onSidepanelOpen",
721
+ "onSidepanelClose"
722
+ ];
723
+ const _excluded2 = ["portalContainer"];
724
+ const _excluded3 = ["button", "panel"];
725
+ function DocSearchSidepanelComponent(_ref, ref) {
726
+ let { keyboardShortcuts, theme, onReady, onOpen, onClose, onSidepanelOpen, onSidepanelClose } = _ref, props = _objectWithoutProperties(_ref, _excluded);
727
+ return /* @__PURE__ */ React.createElement(DocSearch, {
728
+ keyboardShortcuts,
729
+ theme,
730
+ ref,
731
+ onReady,
732
+ onOpen,
733
+ onClose,
734
+ onSidepanelOpen,
735
+ onSidepanelClose
736
+ }, /* @__PURE__ */ React.createElement(DocSearchSidepanelComp, props));
737
+ }
738
+ const DocSearchSidepanel = React.forwardRef(DocSearchSidepanelComponent);
739
+ function DocSearchSidepanelComp(_ref2) {
740
+ let { button: buttonProps = {}, panel: _ref3 = {} } = _ref2, { portalContainer } = _ref3, panelProps = _objectWithoutProperties(_ref3, _excluded2), rootProps = _objectWithoutProperties(_ref2, _excluded3);
741
+ const { docsearchState, setDocsearchState, keyboardShortcuts, registerView, initialAskAiMessage } = useDocSearch();
742
+ const toggleSidepanelState = React.useCallback(() => {
743
+ setDocsearchState(docsearchState === "sidepanel" ? "ready" : "sidepanel");
744
+ }, [docsearchState, setDocsearchState]);
745
+ const handleClose = () => {
746
+ setDocsearchState("ready");
747
+ };
748
+ const handleOpen = () => {
749
+ setDocsearchState("sidepanel");
750
+ };
751
+ const containerElement = React.useMemo(() => portalContainer !== null && portalContainer !== void 0 ? portalContainer : document.body, [portalContainer]);
752
+ React.useEffect(() => {
753
+ registerView("sidepanel");
754
+ }, [registerView]);
755
+ const ButtonComp = React.useMemo(() => /* @__PURE__ */ React.createElement(SidepanelButton, _objectSpread2({
756
+ keyboardShortcuts,
757
+ onClick: toggleSidepanelState
758
+ }, buttonProps)), [
759
+ keyboardShortcuts,
760
+ toggleSidepanelState,
761
+ buttonProps
762
+ ]);
763
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, buttonProps.variant === "inline" ? ButtonComp : createPortal(ButtonComp, containerElement), createPortal(/* @__PURE__ */ React.createElement(Sidepanel, _objectSpread2(_objectSpread2(_objectSpread2({
764
+ initialMessage: initialAskAiMessage,
765
+ isOpen: docsearchState === "sidepanel",
766
+ onClose: handleClose,
767
+ onOpen: handleOpen
768
+ }, rootProps), panelProps), {}, { keyboardShortcuts })), containerElement));
769
+ }
770
+
771
+ //#endregion
772
+ export { DocSearchSidepanel, Sidepanel, SidepanelButton };
773
+ //# sourceMappingURL=sidepanel.js.map