@docsearch/react 5.0.0-beta.1 → 5.0.0-beta.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/README.md +1 -1
- package/dist/esm/{AskAiScreenState-CRHicWbN.d.ts → AskAiScreenState-Bw2WIgv_.d.ts} +5 -2
- package/dist/esm/{DocSearch-HJsNvtZr.d.ts → DocSearch-CVj6U-nI.d.ts} +4 -18
- package/dist/esm/{DocSearchAskAiModal-KaA6fBV4.js → DocSearchAskAiModal-BczGFkvR.js} +26 -33
- package/dist/esm/DocSearchAskAiModal-BczGFkvR.js.map +1 -0
- package/dist/esm/{DocSearchAskAiModal-B7vpLudE.d.ts → DocSearchAskAiModal-MF2py4NM.d.ts} +4 -4
- package/dist/esm/{DocSearchModal-CpvDjo1O.js → DocSearchModal-D_tfhoN1.js} +13 -21
- package/dist/esm/DocSearchModal-D_tfhoN1.js.map +1 -0
- package/dist/esm/askaiModal.d.ts +1 -1
- package/dist/esm/askaiModal.js +1 -1
- package/dist/esm/docsearchAi.d.ts +4 -9
- package/dist/esm/docsearchAi.js +14 -4
- package/dist/esm/docsearchAi.js.map +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +15 -5
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/modal.d.ts +1 -1
- package/dist/esm/modal.js +1 -1
- package/dist/esm/{normalizeDocSearchIndexes-DAzlMybx.js → normalizeDocSearchIndexes-D8P3VEXa.js} +90 -55
- package/dist/esm/normalizeDocSearchIndexes-D8P3VEXa.js.map +1 -0
- package/dist/esm/sidepanel.d.ts +14 -22
- package/dist/esm/sidepanel.js +14 -11
- package/dist/esm/sidepanel.js.map +1 -1
- package/dist/esm/{useSuggestedQuestions-CG2H3qm4.js → useSuggestedQuestions-Ds7H1JCr.js} +36 -26
- package/dist/esm/useSuggestedQuestions-Ds7H1JCr.js.map +1 -0
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/umd/index.js +43 -41
- package/dist/umd/index.js.map +1 -1
- package/package.json +4 -4
- package/dist/esm/DocSearchAskAiModal-KaA6fBV4.js.map +0 -1
- package/dist/esm/DocSearchModal-CpvDjo1O.js.map +0 -1
- package/dist/esm/normalizeDocSearchIndexes-DAzlMybx.js.map +0 -1
- package/dist/esm/useSuggestedQuestions-CG2H3qm4.js.map +0 -1
package/dist/esm/sidepanel.js
CHANGED
|
@@ -2,7 +2,7 @@ import { t as _objectSpread2 } from "./objectSpread2-BNmiQYyW.js";
|
|
|
2
2
|
import { n as isAppleDevice, t as ACTION_KEY_DEFAULT } from "./keyboard-BkSdCzTU.js";
|
|
3
3
|
import { n as SearchIcon, t as _objectWithoutProperties } from "./objectWithoutProperties-phqYxDS0.js";
|
|
4
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-
|
|
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-Ds7H1JCr.js";
|
|
6
6
|
import { version } from "./version.js";
|
|
7
7
|
import { DocSearch, useDocSearch } from "@docsearch/core";
|
|
8
8
|
import React, { Fragment, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
@@ -133,9 +133,9 @@ function AggregatedSearchBlock({ queries }) {
|
|
|
133
133
|
//#endregion
|
|
134
134
|
//#region src/Sidepanel/ConversationScreen.tsx
|
|
135
135
|
const ConversationExchange = React.forwardRef(({ exchange, translations = {}, isLastExchange, conversations, onFeedback, status, streamError, memoryEnabled, tools, onSelectPromptSuggestion }, conversationRef) => {
|
|
136
|
-
var _userMessage$metadata, _assistantMessage$met
|
|
136
|
+
var _userMessage$metadata, _assistantMessage$met;
|
|
137
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;
|
|
138
|
+
const { reasoningText = "Reasoning...", thinkingText = "Thinking...", searchingText = "Searching...", relatedSourcesText, relatedSourcesTextPlural, 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
139
|
const assistantContent = useMemo(() => getMessageContent(assistantMessage), [assistantMessage]);
|
|
140
140
|
const userContent = useMemo(() => getMessageContent(userMessage), [userMessage]);
|
|
141
141
|
const assistantParts = useMemo(() => groupConsecutiveToolResults((assistantMessage === null || assistantMessage === void 0 ? void 0 : assistantMessage.parts) || []), [assistantMessage]);
|
|
@@ -151,7 +151,7 @@ const ConversationExchange = React.forwardRef(({ exchange, translations = {}, is
|
|
|
151
151
|
return /* @__PURE__ */ React.createElement("div", {
|
|
152
152
|
className: "DocSearch-AskAiScreen-Response-Container",
|
|
153
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" },
|
|
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 !== null && userContent !== void 0 ? userContent : "")), /* @__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
155
|
className: "DocSearch-AskAiScreen-Error",
|
|
156
156
|
role: "alert"
|
|
157
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, {
|
|
@@ -202,12 +202,13 @@ const ConversationExchange = React.forwardRef(({ exchange, translations = {}, is
|
|
|
202
202
|
role: "status"
|
|
203
203
|
}, /* @__PURE__ */ React.createElement("span", { className: "DocSearch-shimmer" }, thinkingText), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-AskAi-Thinking-Skeleton DocSearch-shimmer" }), /* @__PURE__ */ React.createElement("span", { className: "DocSearch-AskAi-Thinking-Skeleton DocSearch-AskAi-Thinking-Skeleton--short DocSearch-shimmer" }))), wasStopped && /* @__PURE__ */ React.createElement("p", { className: "DocSearch-AskAiScreen-MessageContent-Stopped" }, stoppedStreamingText)), /* @__PURE__ */ React.createElement("div", { className: "DocSearch-AskAiScreen-Answer-Footer" }, /* @__PURE__ */ React.createElement(SourcesPanel, {
|
|
204
204
|
links: urlsToDisplay,
|
|
205
|
-
titleText: relatedSourcesText
|
|
205
|
+
titleText: relatedSourcesText,
|
|
206
|
+
pluralTitleText: relatedSourcesTextPlural
|
|
206
207
|
}), /* @__PURE__ */ React.createElement(FeedbackActions, {
|
|
207
208
|
isSidepanel: true,
|
|
208
209
|
id: messageId,
|
|
209
210
|
showActions,
|
|
210
|
-
latestAssistantMessageContent:
|
|
211
|
+
latestAssistantMessageContent: assistantContent || null,
|
|
211
212
|
translations,
|
|
212
213
|
conversations,
|
|
213
214
|
onFeedback
|
|
@@ -497,7 +498,7 @@ const useSidepanelWidth = ({ isExpanded, width, expandedWidth }) => {
|
|
|
497
498
|
|
|
498
499
|
//#endregion
|
|
499
500
|
//#region src/Sidepanel/Sidepanel.tsx
|
|
500
|
-
function SidepanelInner({ isOpen = false, onOpen, onClose,
|
|
501
|
+
function SidepanelInner({ isOpen = false, onOpen, onClose, agentId, apiKey, appId, variant = "floating", searchParameters, pushSelector, width, expandedWidth, suggestedQuestions: suggestedQuestionsEnabled = false, translations = {}, keyboardShortcuts, side = "right", initialMessage, tools = EMPTY_TOOLS, memory, indices }, ref) {
|
|
501
502
|
var _memory$enabled;
|
|
502
503
|
const [isExpanded, setIsExpanded] = React.useState(false);
|
|
503
504
|
const [sidepanelState, setSidepanelState] = React.useState("new-conversation");
|
|
@@ -517,8 +518,7 @@ function SidepanelInner({ isOpen = false, onOpen, onClose, assistantId, apiKey,
|
|
|
517
518
|
const searchClient = useSearchClient(appId, apiKey, setSidepanelSearchClient);
|
|
518
519
|
const { chatId, status, sendMessage, stopAskAiStreaming, isStreaming, exchanges, conversations, messages, sendFeedback, askAiError, startNewConversation, restoreConversation } = useAskAi({
|
|
519
520
|
appId,
|
|
520
|
-
|
|
521
|
-
assistantId,
|
|
521
|
+
agentId,
|
|
522
522
|
apiKey,
|
|
523
523
|
searchParameters,
|
|
524
524
|
tools,
|
|
@@ -526,7 +526,7 @@ function SidepanelInner({ isOpen = false, onOpen, onClose, assistantId, apiKey,
|
|
|
526
526
|
indices
|
|
527
527
|
});
|
|
528
528
|
const suggestedQuestions = useSuggestedQuestions({
|
|
529
|
-
|
|
529
|
+
agentId,
|
|
530
530
|
suggestedQuestionsEnabled,
|
|
531
531
|
searchClient
|
|
532
532
|
});
|
|
@@ -725,6 +725,8 @@ const _excluded3 = ["button", "panel"];
|
|
|
725
725
|
function DocSearchSidepanelComponent(_ref, ref) {
|
|
726
726
|
let { keyboardShortcuts, theme, onReady, onOpen, onClose, onSidepanelOpen, onSidepanelClose } = _ref, props = _objectWithoutProperties(_ref, _excluded);
|
|
727
727
|
return /* @__PURE__ */ React.createElement(DocSearch, {
|
|
728
|
+
appId: props.appId,
|
|
729
|
+
apiKey: props.apiKey,
|
|
728
730
|
keyboardShortcuts,
|
|
729
731
|
theme,
|
|
730
732
|
ref,
|
|
@@ -738,7 +740,8 @@ function DocSearchSidepanelComponent(_ref, ref) {
|
|
|
738
740
|
const DocSearchSidepanel = React.forwardRef(DocSearchSidepanelComponent);
|
|
739
741
|
function DocSearchSidepanelComp(_ref2) {
|
|
740
742
|
let { button: buttonProps = {}, panel: _ref3 = {} } = _ref2, { portalContainer } = _ref3, panelProps = _objectWithoutProperties(_ref3, _excluded2), rootProps = _objectWithoutProperties(_ref2, _excluded3);
|
|
741
|
-
const { docsearchState, setDocsearchState, keyboardShortcuts, registerView, initialAskAiMessage } = useDocSearch();
|
|
743
|
+
const { docsearchState, setDocsearchState, keyboardShortcuts, registerView, initialAskAiMessage, appId, apiKey } = useDocSearch();
|
|
744
|
+
if (!appId || !apiKey) throw new Error("`Sidepanel` requires `appId` and `apiKey` props or values configured on the `DocSearch` provider.");
|
|
742
745
|
const toggleSidepanelState = React.useCallback(() => {
|
|
743
746
|
setDocsearchState(docsearchState === "sidepanel" ? "ready" : "sidepanel");
|
|
744
747
|
}, [docsearchState, setDocsearchState]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidepanel.js","names":[],"sources":["../../src/icons/SendIcon.tsx","../../src/icons/ExpandIcon.tsx","../../src/icons/FolderIcon.tsx","../../src/icons/EditIcon.tsx","../../src/useIsMobile.ts","../../src/Sidepanel/ConversationHistoryScreen.tsx","../../src/Sidepanel/AggregatedSearchBlock.tsx","../../src/Sidepanel/ConversationScreen.tsx","../../src/Sidepanel/NewConversationScreen.tsx","../../src/Sidepanel/PromptForm.tsx","../../src/Sidepanel/setSidepanelSearchClient.ts","../../src/Sidepanel/SidepanelHeader.tsx","../../src/Sidepanel/useManageSidepanelLayout.ts","../../src/Sidepanel/useSidepanelKeyboardEvents.ts","../../src/Sidepanel/useSidepanelWidth.ts","../../src/Sidepanel/Sidepanel.tsx","../../src/Sidepanel/SidepanelButton.tsx","../../src/Sidepanel.tsx"],"sourcesContent":["import type { JSX } from 'react';\nimport React from 'react';\n\nexport const SendIcon = (): JSX.Element => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m5 12 7-7 7 7\" />\n <path d=\"M12 19V5\" />\n </svg>\n );\n};\n","import type { JSX } from 'react';\nimport React from 'react';\n\nexport const ExpandIcon = (): JSX.Element => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 13 13\"\n fill=\"none\"\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n 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\"\n fill=\"currentColor\"\n />\n </svg>\n );\n};\n","import React from 'react';\nimport type { JSX } from 'react';\n\nexport const FolderIcon = (): JSX.Element => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <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\" />\n </svg>\n );\n};\n","import React from 'react';\nimport type { JSX } from 'react';\n\nexport const EditIcon = (): JSX.Element => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\" />\n <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\" />\n </svg>\n );\n};\n","import React from 'react';\n\nexport const useIsMobile = (): boolean => {\n const [isMobile, setIsMobile] = React.useState(false);\n\n React.useEffect(() => {\n const checkForMobile = (): void => {\n const isMobileMediaQuery = window.matchMedia('(max-width: 768px)');\n\n setIsMobile(isMobileMediaQuery.matches);\n };\n\n checkForMobile();\n\n window.addEventListener('resize', checkForMobile);\n\n return (): void => {\n window.removeEventListener('resize', checkForMobile);\n };\n }, []);\n\n return isMobile;\n};\n","/* eslint-disable jsx-a11y/no-noninteractive-element-to-interactive-role */\nimport React from 'react';\nimport type { JSX } from 'react';\n\nimport { CloseIcon, RecentIcon } from '../icons';\nimport type { StoredSearchPlugin } from '../stored-searches';\nimport type { StoredAskAiState } from '../types';\n\ntype ConversationHistoryScreenProps = {\n conversations: StoredSearchPlugin<StoredAskAiState>;\n selectConversation: (conversation: StoredAskAiState) => void;\n};\n\nexport const ConversationHistoryScreen = ({\n conversations,\n selectConversation,\n}: ConversationHistoryScreenProps): JSX.Element => {\n const [items, setItems] = React.useState(() => conversations.getAll());\n\n const handleRemoveConversation = (item: StoredAskAiState): void => {\n conversations.remove(item);\n setItems(conversations.getAll());\n };\n\n return (\n <div className=\"DocSearch-Sidepanel-ConversationHistoryScreen\">\n <ul>\n {items.map((item) => (\n <li\n key={item.objectID}\n className=\"DocSearch-Sidepanel-RecentConversation\"\n >\n <a\n href={item.url}\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n\n selectConversation(item);\n }}\n >\n <div className=\"DocSearch-Sidepanel-RecentConversation-container\">\n <div className=\"DocSearch-Sidepanel-RecentConversation-icon\">\n <RecentIcon />\n </div>\n\n <div className=\"DocSearch-Sidepanel-RecentConversation-content\">\n <span className=\"DocSearch-Sidepanel-RecentConversation-title\">\n {item.hierarchy.lvl1}\n </span>\n </div>\n\n <div className=\"DocSearch-Hit-action\">\n <button\n className=\"DocSearch-Hit-action-button\"\n type=\"button\"\n title=\"Remove conversation from history\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n handleRemoveConversation(item);\n }}\n >\n <CloseIcon />\n </button>\n </div>\n </div>\n </a>\n </li>\n ))}\n </ul>\n </div>\n );\n};\n","import React, { Fragment } from 'react';\nimport type { JSX } from 'react';\n\nimport { SearchIcon } from '../icons';\n\ntype AggregatedSearchBlockProps = {\n queries: string[];\n};\n\nconst before = 'Searched for ';\nconst separator = ', ';\nconst lastSeparator = ' and ';\nconst after = '';\n\nexport function AggregatedSearchBlock({\n queries,\n}: AggregatedSearchBlockProps): JSX.Element {\n return (\n <div className=\"DocSearch-AskAiScreen-MessageContent-Tool Tool--AggregatedResult\">\n <SearchIcon size={18} />\n <span>\n {before && <span>{before}</span>}\n {queries.map((q, idx) => (\n // eslint-disable-next-line react/no-array-index-key\n <Fragment key={q + idx}>\n <span className=\"DocSearch-AskAiScreen-MessageContent-Tool-Query\">\n "{q}"\n </span>\n {idx < queries.length - 2 && separator}\n {idx === queries.length - 2 && lastSeparator}\n </Fragment>\n ))}\n {after && <span>{after}</span>}\n </span>\n </div>\n );\n}\n","import type { UseChatHelpers } from '@ai-sdk/react';\nimport type { JSX } from 'react';\nimport React, { memo, useMemo } from 'react';\n\nimport { type Exchange } from '../AskAiScreen';\nimport { ConversationPromptSuggestions } from '../components/ConversationPromptSuggestions';\nimport { FeedbackActions } from '../components/FeedbackActions';\nimport { SourcesPanel } from '../components/SourcesPanel';\nimport { ToolCall, type ToolCallTranslations } from '../components/ToolCall';\nimport { AlertIcon, LoadingIcon } from '../icons';\nimport { MemoizedMarkdown } from '../MemoizedMarkdown';\nimport type { StoredSearchPlugin } from '../stored-searches';\nimport type { OnAskAiFeedback, StoredAskAiState } from '../types';\nimport { type AIMessage, type ToolCalls } from '../types/AskiAi';\nimport {\n extractLinksFromMessage,\n getMessageContent,\n EMPTY_TOOLS,\n isAIToolPart,\n getAgentPromptSuggestions,\n} from '../utils/ai';\nimport { groupConsecutiveToolResults } from '../utils/groupConsecutiveToolResults';\n\nimport { AggregatedSearchBlock } from './AggregatedSearchBlock';\n\nexport type ConversationScreenTranslations = Partial<\n ToolCallTranslations & {\n /** Text shown as an LLM disclaimer. */\n conversationDisclaimer: string;\n /** Text shown while assistant is reasoning. */\n reasoningText: string;\n /** Text show while assistant is thinking. */\n thinkingText: string;\n /** Text shown describing related sources. */\n relatedSourcesText: string;\n /** Message that's shown when user has stopped the streaming of a message. */\n stoppedStreamingText: string;\n /** Text shown for copy button on code snippets. */\n copyButtonText: string;\n /** Message shown after clicking copy. */\n copyButtonCopiedText: string;\n /** Title for thumbs up feedback icon. */\n likeButtonTitle: string;\n /** Title for thumbs down feedback icon. */\n dislikeButtonTitle: string;\n /** Message displayed after feedback action. */\n thanksForFeedbackText: string;\n /** Title shown at the top of the negative feedback note panel. */\n feedbackPanelTitle: string;\n /** Placeholder for the negative feedback details textarea. */\n feedbackDetailsPlaceholder: string;\n /** Disclaimer shown inside the negative feedback note panel. */\n feedbackDisclaimerText: string;\n /** Submit button text for the negative feedback note panel. */\n feedbackSubmitButtonText: string;\n /** Accessible title for the negative feedback note panel close button. */\n feedbackCloseButtonTitle: string;\n /** Reason chip labels for the negative feedback note panel. */\n feedbackTagIncorrect: string;\n feedbackTagNotWhatIAsked: string;\n feedbackTagSlowOrBuggy: string;\n feedbackTagStyleOrTone: string;\n feedbackTagSafetyOrLegal: string;\n feedbackTagOther: string;\n /** Error title shown if there is an error while chatting. */\n errorTitleText;\n suggestedPromptsTitleText: string;\n }\n>;\n\nexport type ConversationScreenProps = {\n exchanges: Exchange[];\n conversations: StoredSearchPlugin<StoredAskAiState>;\n translations?: ConversationScreenTranslations;\n status: UseChatHelpers<AIMessage>['status'];\n handleFeedback?: OnAskAiFeedback;\n streamError?: Error;\n memoryEnabled?: boolean;\n tools?: ToolCalls;\n onSelectPromptSuggestion: (prompt: string) => void;\n};\n\ntype ConversationnExchangeProps = {\n exchange: Exchange;\n isLastExchange: boolean;\n status: ConversationScreenProps['status'];\n conversations: ConversationScreenProps['conversations'];\n translations?: ConversationScreenTranslations;\n onFeedback?: ConversationScreenProps['handleFeedback'];\n streamError?: ConversationScreenProps['streamError'];\n memoryEnabled?: boolean;\n tools: ToolCalls;\n onSelectPromptSuggestion: (prompt: string) => void;\n};\n\nconst ConversationExchange = React.forwardRef<\n HTMLDivElement,\n ConversationnExchangeProps\n>(\n (\n {\n exchange,\n translations = {},\n isLastExchange,\n conversations,\n onFeedback,\n status,\n streamError,\n memoryEnabled,\n tools,\n onSelectPromptSuggestion,\n },\n conversationRef\n ): JSX.Element => {\n const { userMessage, assistantMessage } = exchange;\n\n const {\n reasoningText = 'Reasoning...',\n thinkingText = 'Thinking...',\n searchingText = 'Searching...',\n relatedSourcesText,\n stoppedStreamingText = 'You stopped this response',\n preToolCallText = 'Searching...',\n toolCallResultText = 'Searched for',\n copyButtonText = 'Copy',\n copyButtonCopiedText = 'Copied!',\n errorTitleText = 'Chat error',\n savedMemoryToolResultText = 'Saved to memory',\n memoryToolResultText = 'Used memory to enhance results',\n suggestedPromptsTitleText = 'Suggested prompts',\n } = translations;\n\n const assistantContent = useMemo(\n () => getMessageContent(assistantMessage),\n [assistantMessage]\n );\n const userContent = useMemo(\n () => getMessageContent(userMessage),\n [userMessage]\n );\n\n const assistantParts = useMemo(\n () => groupConsecutiveToolResults(assistantMessage?.parts || []),\n [assistantMessage]\n );\n const urlsToDisplay = React.useMemo(\n () => extractLinksFromMessage(assistantMessage),\n [assistantMessage]\n );\n const suggestedPrompts = React.useMemo(() => {\n if (!isLastExchange) return [];\n return getAgentPromptSuggestions(assistantMessage?.parts || []);\n }, [assistantMessage, isLastExchange]);\n\n const wasStopped =\n userMessage.metadata?.stopped || assistantMessage?.metadata?.stopped;\n const isThinking =\n ['submitted', 'streaming'].includes(status) &&\n !assistantParts.some((part) => part.type !== 'step-start');\n const showActions =\n !wasStopped &&\n (!isLastExchange ||\n (isLastExchange && status === 'ready' && Boolean(assistantMessage)));\n\n const messageId = assistantMessage?.id || exchange.id;\n\n return (\n <div\n className=\"DocSearch-AskAiScreen-Response-Container\"\n ref={conversationRef}\n >\n <div className=\"DocSearch-AskAiScreen-Response\">\n <div className=\"DocSearch-AskAiScreen-Message DocSearch-AskAiScreen-Message--user\">\n <p className=\"DocSearch-AskAiScreen-Query\">\n {userContent?.text ?? ''}\n </p>\n </div>\n <div className=\"DocSearch-AskAiScreen-Message DocSearch-AskAiScreen-Message--assistant\">\n <div className=\"DocSearch-AskAiScreen-MessageContent\">\n {status === 'error' && streamError && isLastExchange && (\n <div className=\"DocSearch-AskAiScreen-Error\" role=\"alert\">\n <AlertIcon aria-hidden=\"true\" />\n <div className=\"DocSearch-AskAiScreen-Error-Content\">\n <h4 className=\"DocSearch-AskAiScreen-Error-Title\">\n {errorTitleText}\n </h4>\n <MemoizedMarkdown\n content={streamError.message}\n copyButtonText=\"\"\n copyButtonCopiedText=\"\"\n isStreaming={false}\n />\n </div>\n </div>\n )}\n\n {assistantParts.map((part, idx) => {\n const index = idx;\n\n if (part.type === 'reasoning' && part.state === 'streaming') {\n return (\n <div\n key={index}\n className=\"DocSearch-AskAiScreen-MessageContent-Reasoning DocSearch-shimmer\"\n >\n <LoadingIcon className=\"DocSearch-AskAiScreen-SmallerLoadingIcon\" />\n <span className=\"DocSearch-shimmer\">{reasoningText}</span>\n </div>\n );\n }\n\n if (part.type === 'aggregated-tool-call') {\n return (\n <AggregatedSearchBlock key={index} queries={part.queries} />\n );\n }\n\n if (isAIToolPart(part)) {\n return (\n <ToolCall\n key={index}\n part={part}\n translations={{\n preToolCallText,\n searchingText,\n toolCallResultText,\n savedMemoryToolResultText,\n memoryToolResultText,\n }}\n tools={tools}\n memoryEnabled={memoryEnabled}\n />\n );\n }\n\n if (typeof part === 'string') {\n return (\n <MemoizedMarkdown\n key={index}\n content={part}\n copyButtonText={copyButtonText}\n copyButtonCopiedText={copyButtonCopiedText}\n isStreaming={false}\n />\n );\n }\n\n if (part.type === 'text') {\n return (\n <MemoizedMarkdown\n key={index}\n content={part.text}\n copyButtonText={copyButtonText}\n copyButtonCopiedText={copyButtonCopiedText}\n isStreaming={part.state === 'streaming'}\n />\n );\n }\n\n return null;\n })}\n\n {isThinking && isLastExchange && assistantParts.length === 0 && (\n <div\n className=\"DocSearch-AskAiScreen-MessageContent-Thinking\"\n role=\"status\"\n >\n <span className=\"DocSearch-shimmer\">{thinkingText}</span>\n <span className=\"DocSearch-AskAi-Thinking-Skeleton DocSearch-shimmer\" />\n <span className=\"DocSearch-AskAi-Thinking-Skeleton DocSearch-AskAi-Thinking-Skeleton--short DocSearch-shimmer\" />\n </div>\n )}\n </div>\n\n {wasStopped && (\n <p className=\"DocSearch-AskAiScreen-MessageContent-Stopped\">\n {stoppedStreamingText}\n </p>\n )}\n </div>\n\n <div className=\"DocSearch-AskAiScreen-Answer-Footer\">\n <SourcesPanel\n links={urlsToDisplay}\n titleText={relatedSourcesText}\n />\n <FeedbackActions\n isSidepanel={true}\n id={messageId}\n showActions={showActions}\n latestAssistantMessageContent={assistantContent?.text || null}\n translations={translations}\n conversations={conversations}\n onFeedback={onFeedback}\n />\n </div>\n\n {suggestedPrompts.length > 0 && (\n <ConversationPromptSuggestions\n title={suggestedPromptsTitleText}\n suggestions={suggestedPrompts}\n onSelectPromptSuggestion={onSelectPromptSuggestion}\n />\n )}\n </div>\n </div>\n );\n }\n);\n\nexport const ConversationScreen = memo(\n ({\n exchanges,\n translations = {},\n handleFeedback,\n tools = EMPTY_TOOLS,\n status,\n conversations,\n streamError,\n memoryEnabled,\n onSelectPromptSuggestion,\n }: ConversationScreenProps): JSX.Element => {\n const {\n conversationDisclaimer = 'Answers are generated with AI which can make mistakes. Verify responses.',\n } = translations;\n\n const mostRecentExchangeRef = React.useRef<HTMLDivElement>(null);\n const totalExchanges = exchanges.length;\n\n // Only scroll the most recent exchange into view when needed\n React.useEffect(() => {\n if (mostRecentExchangeRef.current) {\n mostRecentExchangeRef.current.scrollIntoView({\n behavior: 'smooth',\n block: 'start',\n });\n }\n }, [totalExchanges]);\n\n return (\n <div className=\"DocSearch-Sidepanel-ConversationScreen\">\n <p className=\"DocSearch-Sidepanel-ConversationScreen-disclaimer\">\n {conversationDisclaimer}\n </p>\n\n {exchanges.slice().map((exchange, idx) => {\n const isLastExchange = idx === exchanges.length - 1;\n return (\n <ConversationExchange\n key={exchange.id}\n exchange={exchange}\n translations={translations}\n isLastExchange={isLastExchange}\n ref={isLastExchange ? mostRecentExchangeRef : null}\n tools={tools}\n status={status}\n conversations={conversations}\n streamError={streamError}\n memoryEnabled={memoryEnabled}\n onFeedback={handleFeedback}\n onSelectPromptSuggestion={onSelectPromptSuggestion}\n />\n );\n })}\n </div>\n );\n }\n);\n","import type { JSX } from 'react';\nimport React from 'react';\n\nimport type { SuggestedQuestionHit } from '../types';\n\nexport type NewConversationScreenTranslations = Partial<{\n /** Title to be shown on the new conversation/starting screen. */\n titleText: string;\n /** Introduction text displayed on the new conversation/starting screen. */\n introductionText: string;\n}>;\n\ntype NewConversationScreenProps = {\n suggestedQuestions: SuggestedQuestionHit[];\n onSelectQuestion: (question: SuggestedQuestionHit) => void;\n translations?: NewConversationScreenTranslations;\n};\n\nexport const NewConversationScreen = ({\n suggestedQuestions,\n onSelectQuestion,\n translations = {},\n}: NewConversationScreenProps): JSX.Element => {\n const {\n titleText = 'How can I help you today?',\n introductionText = 'I search through your documentation to help you find setup guides, feature details and troubleshooting tips, fast.',\n } = translations;\n\n return (\n <div className=\"DocSearch-Sidepanel-NewConversationScreen\">\n <h4 className=\"DocSearch-Sidepanel-Screen--title\">{titleText}</h4>\n <p className=\"DocSearch-Sidepanel-Screen--introduction\">\n {introductionText}\n </p>\n\n <div className=\"DocSearch-Sidepanel-List\">\n {suggestedQuestions.map((q) => (\n <button\n key={q.objectID}\n type=\"button\"\n className=\"DocSearch-Sidepanel-SuggestedQuestion\"\n title=\"View conversation\"\n onClick={() => {\n onSelectQuestion(q);\n }}\n >\n <span>{q.question}</span>\n </button>\n ))}\n </div>\n </div>\n );\n};\n","import React from 'react';\nimport type { JSX } from 'react';\n\nimport type { Exchange } from '../AskAiScreen';\nimport { SendIcon, StopIcon } from '../icons';\nimport { useIsMobile } from '../useIsMobile';\n\nexport type PromptFormTranslations = Partial<{\n /** Initial placeholder for the prompt input. */\n promptPlaceholderText: string;\n /** Placeholder text for wile a conversation is streaming. */\n promptAnsweringText: string;\n /** Placeholder text for after a question has already been asked. */\n promptAskAnotherQuestionText: string;\n /** Disclaimer text displayed beneath the prompt form. */\n promptDisclaimerText: string;\n promptLabelText: string;\n promptAriaLabelText: string;\n}>;\n\ntype Props = {\n exchanges: Exchange[];\n isStreaming: boolean;\n translations?: PromptFormTranslations;\n onSend: (prompt: string) => void;\n onStopStreaming: () => void;\n};\n\nconst MAX_PROMPT_ROWS = 8;\n\nexport const PromptForm = React.forwardRef<HTMLTextAreaElement, Props>(\n (\n { exchanges, isStreaming, translations = {}, onSend, onStopStreaming },\n ref\n ): JSX.Element => {\n const isMobile = useIsMobile();\n const [userPrompt, setUserPrompt] = React.useState('');\n const promptRef = React.useRef<HTMLTextAreaElement>(null);\n\n React.useImperativeHandle(\n ref,\n () => promptRef.current as HTMLTextAreaElement\n );\n\n const {\n promptPlaceholderText = 'Ask a question',\n promptAnsweringText = 'Answering...',\n promptAskAnotherQuestionText = 'Ask another question',\n promptDisclaimerText = 'Answers are generated with AI which can make mistakes.',\n promptLabelText = 'Press Enter to send, or Shift and Enter for new line.',\n promptAriaLabelText = 'Prompt input',\n } = translations;\n\n const managePromptHeight = (): void => {\n if (!promptRef.current) return;\n\n const textArea = promptRef.current;\n const styles = getComputedStyle(textArea);\n\n const lineHeight = parseFloat(styles.lineHeight);\n const paddingTop = parseFloat(styles.paddingTop);\n const paddingBottom = parseFloat(styles.paddingBottom);\n const padding = paddingTop + paddingBottom;\n\n textArea.style.height = 'auto';\n\n const fullHeight = textArea.scrollHeight;\n const maxHeight = MAX_PROMPT_ROWS * lineHeight + padding;\n\n textArea.style.overflowY = fullHeight > maxHeight ? 'auto' : 'hidden';\n textArea.style.height = `${Math.min(fullHeight, maxHeight)}px`;\n };\n\n const handleSend = (): void => {\n if (isStreaming) return;\n\n const prompt = userPrompt.trim();\n\n if (prompt === '') return;\n\n onSend(prompt);\n\n setUserPrompt('');\n\n requestAnimationFrame(() => {\n promptRef.current?.focus();\n\n managePromptHeight();\n });\n };\n\n const handleKeyDown = (\n e: React.KeyboardEvent<HTMLTextAreaElement>\n ): void => {\n // Allow Enter to work normally (new line) when streaming\n if (isStreaming) return;\n\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n\n handleSend();\n }\n };\n\n React.useLayoutEffect(() => {\n managePromptHeight();\n }, [isMobile]);\n\n let promptPlaceholder = promptPlaceholderText;\n\n if (isStreaming) {\n promptPlaceholder = promptAnsweringText;\n } else if (exchanges.length > 0) {\n promptPlaceholder = promptAskAnotherQuestionText;\n }\n\n return (\n <div className=\"DocSearch-Sidepanel-Prompt\">\n <form\n className=\"DocSearch-Sidepanel-Prompt--form\"\n onSubmit={(e) => {\n e.preventDefault();\n\n if (isStreaming) return;\n\n handleSend();\n }}\n >\n <textarea\n ref={promptRef}\n placeholder={promptPlaceholder}\n className=\"DocSearch-Sidepanel-Prompt--textarea\"\n value={userPrompt}\n aria-label={promptAriaLabelText}\n aria-labelledby=\"prompt-label\"\n autoComplete=\"off\"\n translate=\"no\"\n rows={isMobile ? 1 : 2}\n onKeyDown={handleKeyDown}\n onInput={managePromptHeight}\n onChange={(e) => setUserPrompt(e.target.value)}\n />\n <span id=\"prompt-label\" className=\"sr-only\">\n {promptLabelText}\n </span>\n <div className=\"DocSearch-Sidepanel-Prompt--actions\">\n {isStreaming && (\n <button\n type=\"button\"\n title=\"Stop streaming\"\n className=\"DocSearch-Sidepanel-Prompt--stop\"\n onClick={onStopStreaming}\n >\n <StopIcon />\n </button>\n )}\n {!isStreaming && (\n <button\n type=\"submit\"\n aria-label=\"Send question\"\n title=\"Send question\"\n className=\"DocSearch-Sidepanel-Prompt--submit\"\n aria-disabled={userPrompt === ''}\n >\n <SendIcon />\n </button>\n )}\n </div>\n </form>\n <p className=\"DocSearch-Sidepanel-Prompt--disclaimer\">\n {promptDisclaimerText}\n </p>\n </div>\n );\n }\n);\n","import type { DocSearchTransformClient } from '..';\nimport { version } from '../version';\n\nexport const setSidepanelSearchClient = (\n client: DocSearchTransformClient\n): DocSearchTransformClient => {\n if (\n /docsearch-sidepanel.js \\(.*\\)/.test(\n client.transporter.algoliaAgent.value\n ) === false\n ) {\n client.addAlgoliaAgent('docsearch-sidepanel', version);\n }\n\n return client;\n};\n","import type { JSX } from 'react';\nimport React from 'react';\n\nimport type { Exchange } from '../AskAiScreen';\nimport {\n CloseIcon,\n ConversationHistoryIcon,\n EditIcon,\n ExpandIcon,\n FolderIcon,\n MoreVerticalIcon,\n NewConversationIcon,\n SparklesIcon,\n} from '../icons';\nimport { BackIcon } from '../icons/BackIcon';\nimport { Menu } from '../Menu';\nimport { useIsMobile } from '../useIsMobile';\n\nimport type { SidepanelState } from './types';\n\ntype BackButtonProps = {\n mobile?: boolean;\n onBack: () => void;\n disabled?: boolean;\n};\n\nconst BackButton = ({\n onBack,\n mobile = false,\n disabled = false,\n}: BackButtonProps): JSX.Element => {\n return (\n <button\n type=\"button\"\n className={`DocSearch-Action DocSearch-Sidepanel-Action-back${mobile ? ' mobile' : ''}`}\n title=\"Go back to previous screen\"\n aria-disabled={disabled}\n onClick={disabled ? undefined : onBack}\n >\n <BackIcon />\n </button>\n );\n};\n\nexport type HeaderTranslations = Partial<{\n /** The main title text shown on the header. */\n title: string;\n /** The title text shown on the conversation history screen. */\n conversationHistoryTitle: string;\n /** The text shown on the start a conversation button. */\n newConversationText: string;\n /** The text shown on the view conversation history button. */\n viewConversationHistoryText: string;\n}>;\n\ntype SidepanelHeaderProps = {\n sidepanelState: SidepanelState;\n exchanges: Exchange[];\n setSidepanelState: (state: SidepanelState) => void;\n onNewConversation: () => void;\n onToggleExpanded: () => void;\n onClose: () => void;\n translations?: HeaderTranslations;\n hasConversations: boolean;\n isStreaming: boolean;\n};\n\nexport const SidepanelHeader = React.memo(\n ({\n sidepanelState,\n exchanges,\n setSidepanelState,\n onNewConversation,\n onToggleExpanded,\n onClose,\n translations = {},\n hasConversations,\n isStreaming,\n }: SidepanelHeaderProps): JSX.Element => {\n const {\n title = 'Ask AI',\n conversationHistoryTitle = 'My conversation history',\n newConversationText = 'Start a new conversation',\n viewConversationHistoryText = 'Conversation history',\n } = translations;\n\n const isMobile = useIsMobile();\n\n const goToConversationHistory = (): void => {\n setSidepanelState('conversation-history');\n };\n\n const onBack = React.useCallback((): void => {\n if (exchanges.length > 0) {\n setSidepanelState('conversation');\n } else {\n setSidepanelState('new-conversation');\n }\n }, [exchanges, setSidepanelState]);\n\n const newConversationDisabled =\n sidepanelState === 'new-conversation' && exchanges.length < 1;\n\n let header = title;\n\n if (sidepanelState === 'conversation-history') {\n header = conversationHistoryTitle;\n }\n\n if (isMobile) {\n header = title;\n }\n\n return (\n <header className=\"DocSearch-Sidepanel-Header\">\n <div className=\"DocSearch-Sidepanel-Header--left\">\n <BackButton mobile={true} disabled={isStreaming} onBack={onBack} />\n\n {sidepanelState === 'conversation-history' && (\n <div className=\"DocSearch-Divider\" />\n )}\n\n <button\n type=\"button\"\n className=\"DocSearch-Action\"\n title={newConversationText}\n onClick={onNewConversation}\n >\n <EditIcon />\n </button>\n\n <div className=\"DocSearch-Divider\" />\n\n <button\n type=\"button\"\n className=\"DocSearch-Action\"\n title={viewConversationHistoryText}\n onClick={goToConversationHistory}\n >\n <FolderIcon />\n </button>\n </div>\n <div className=\"DocSearch-Sidepanel-Header--center\">\n <BackButton disabled={isStreaming} onBack={onBack} />\n <SparklesIcon className=\"DocSearch-Sidepanel-Header-TitleIcon\" />\n <h2 className=\"DocSearch-Sidepanel-Title\">{header}</h2>\n </div>\n <div className=\"DocSearch-Sidepanel-Header--right\">\n {sidepanelState !== 'conversation-history' &&\n (!newConversationDisabled || hasConversations) && (\n <Menu>\n <Menu.Trigger\n className=\"DocSearch-Action DocSearch-Sidepanel-Action-menu\"\n disabled={isStreaming}\n >\n <MoreVerticalIcon />\n </Menu.Trigger>\n <Menu.Content>\n {!newConversationDisabled && (\n <Menu.Item onClick={onNewConversation}>\n <NewConversationIcon />\n {newConversationText}\n </Menu.Item>\n )}\n {hasConversations && (\n <Menu.Item onClick={goToConversationHistory}>\n <ConversationHistoryIcon />\n {viewConversationHistoryText}\n </Menu.Item>\n )}\n </Menu.Content>\n </Menu>\n )}\n <button\n type=\"button\"\n className=\"DocSearch-Action DocSearch-Sidepanel-Action-expand\"\n title=\"Expand or collapse Sidepanel\"\n onClick={onToggleExpanded}\n >\n <ExpandIcon />\n </button>\n <button\n type=\"button\"\n className=\"DocSearch-Action DocSearch-Sidepanel-Action-close\"\n title=\"Close Sidepanel\"\n onClick={onClose}\n >\n <CloseIcon />\n </button>\n </div>\n </header>\n );\n }\n);\n","import { useLayoutEffect, useRef } from 'react';\n\nimport { useIsMobile } from '../useIsMobile';\n\nimport type { PanelSide, PanelVariant } from './types';\n\ntype UseManageSidepanelLayoutProps = {\n variant: PanelVariant;\n side: PanelSide;\n selectors: string;\n isOpen: boolean;\n expectedWidth: string;\n};\n\nexport function useManageSidepanelLayout({\n variant,\n selectors,\n isOpen,\n expectedWidth,\n side,\n}: UseManageSidepanelLayoutProps): void {\n const targetRef = useRef<HTMLElement | null>(null);\n const lastSelectorRef = useRef<string | null>(null);\n const isMobile = useIsMobile();\n\n useLayoutEffect(() => {\n if (variant === 'floating' || isMobile) return;\n\n if (lastSelectorRef.current !== selectors) {\n if (targetRef.current) {\n if (side === 'left') {\n targetRef.current.style.marginLeft = '';\n } else {\n targetRef.current.style.marginRight = '';\n }\n targetRef.current.style.transition = '';\n }\n\n const candidates = Array.from(document.querySelectorAll(selectors));\n const nextTarget: HTMLElement | null =\n (candidates[0] as HTMLElement) || document.body;\n targetRef.current = nextTarget;\n lastSelectorRef.current = selectors;\n\n if (targetRef.current) {\n targetRef.current.style.transition = `margin-${side} 280ms cubic-bezier(0.22, 1, 0.36, 1)`;\n }\n }\n\n const target = targetRef.current;\n if (!target) return;\n\n const offset = isOpen ? expectedWidth : '0px';\n\n if (side === 'left') {\n target.style.marginLeft = offset;\n } else {\n target.style.marginRight = offset;\n }\n }, [isOpen, expectedWidth, variant, selectors, side, isMobile]);\n\n useLayoutEffect(() => {\n return (): void => {\n if (targetRef.current) {\n if (side === 'left') {\n targetRef.current.style.marginLeft = '';\n } else {\n targetRef.current.style.marginRight = '';\n }\n targetRef.current.style.transition = '';\n }\n };\n }, [side]);\n}\n","import type { SidepanelShortcuts } from '@docsearch/core';\nimport { useEffect } from 'react';\n\ntype UseSidepanelKeyboardEventsProps = {\n onClose: () => void;\n onOpen: () => void;\n isOpen: boolean;\n keyboardShortcuts?: SidepanelShortcuts;\n};\n\nexport function useSidepanelKeyboardEvents({\n onClose,\n onOpen,\n isOpen,\n keyboardShortcuts,\n}: UseSidepanelKeyboardEventsProps): void {\n useEffect(() => {\n function onKeyDown(e: KeyboardEvent): void {\n if (isOpen && e.code === 'Escape') {\n onClose();\n return;\n }\n\n const cmdIEnabled = keyboardShortcuts?.['Ctrl/Cmd+I'] !== false;\n\n if (!cmdIEnabled) return;\n\n const isCmdI = e.key?.toLowerCase() === 'i' && (e.metaKey || e.ctrlKey);\n\n if (isCmdI) {\n e.preventDefault();\n\n if (isOpen) {\n onClose();\n } else {\n onOpen();\n }\n }\n }\n\n window.addEventListener('keydown', onKeyDown);\n\n return (): void => {\n window.removeEventListener('keydown', onKeyDown);\n };\n }, [isOpen, onClose, onOpen, keyboardShortcuts]);\n}\n","import React from 'react';\n\nconst BASE_WIDTH = 360;\nconst EXPANDED_WIDTH = 580;\n\ntype UseSidepanelWidthProps = {\n isExpanded: boolean;\n width?: number | string;\n expandedWidth?: number | string;\n};\n\nexport const useSidepanelWidth = ({\n isExpanded,\n width,\n expandedWidth,\n}: UseSidepanelWidthProps): string => {\n const baseWidth = React.useMemo(() => {\n return typeof width === 'number'\n ? `${width}px`\n : (width ?? `${BASE_WIDTH}px`);\n }, [width]);\n\n const resolvedExpandedWidth = React.useMemo(() => {\n return typeof expandedWidth === 'number'\n ? `${expandedWidth}px`\n : (expandedWidth ?? `${EXPANDED_WIDTH}px`);\n }, [expandedWidth]);\n\n const expectedWidth = isExpanded ? resolvedExpandedWidth : baseWidth;\n\n return expectedWidth;\n};\n","import type { SidepanelShortcuts, InitialAskAiMessage } from '@docsearch/core';\nimport React, { useCallback } from 'react';\nimport type { JSX } from 'react';\n\nimport { AlgoliaLogo, type AlgoliaLogoTranslations } from '../AlgoliaLogo';\nimport type {\n DocSearchSidepanelProps,\n SidepanelSearchParameters,\n} from '../Sidepanel';\nimport type { StoredAskAiState, SuggestedQuestionHit } from '../types';\nimport { useAskAi } from '../useAskAi';\nimport { useIsMobile } from '../useIsMobile';\nimport { useSearchClient } from '../useSearchClient';\nimport { useSuggestedQuestions } from '../useSuggestedQuestions';\nimport { EMPTY_TOOLS, buildDummyAskAiHit } from '../utils/ai';\n\nimport { ConversationHistoryScreen } from './ConversationHistoryScreen';\nimport type { ConversationScreenTranslations } from './ConversationScreen';\nimport { ConversationScreen } from './ConversationScreen';\nimport type { NewConversationScreenTranslations } from './NewConversationScreen';\nimport { NewConversationScreen } from './NewConversationScreen';\nimport { PromptForm, type PromptFormTranslations } from './PromptForm';\nimport { setSidepanelSearchClient } from './setSidepanelSearchClient';\nimport type { HeaderTranslations } from './SidepanelHeader';\nimport { SidepanelHeader } from './SidepanelHeader';\nimport type { PanelSide, PanelVariant, SidepanelState } from './types';\nimport { useManageSidepanelLayout } from './useManageSidepanelLayout';\nimport { useSidepanelKeyboardEvents } from './useSidepanelKeyboardEvents';\nimport { useSidepanelWidth } from './useSidepanelWidth';\n\n/**\n * Imperative handle exposed by the Sidepanel component for programmatic\n * control.\n */\nexport interface SidepanelRef {\n /** Opens the sidepanel. */\n open: () => void;\n /** Closes the sidepanel. */\n close: () => void;\n /** Returns true once the component is mounted and ready. */\n readonly isReady: boolean;\n /** Returns true if the sidepanel is currently open. */\n readonly isOpen: boolean;\n}\n\nexport type SidepanelTranslations = Partial<{\n /** Translation texts for the Sidepanel header. */\n header: HeaderTranslations;\n /** Translation texts for the prompt form. */\n promptForm: PromptFormTranslations;\n /** Translation texts for the conversation screen. */\n conversationScreen: ConversationScreenTranslations;\n /** Translation texts for the new conversation/starting screen. */\n newConversationScreen: NewConversationScreenTranslations;\n /** Translation text for the Algolia logo. */\n logo: AlgoliaLogoTranslations;\n}>;\n\nexport type SidepanelProps = Pick<\n DocSearchSidepanelProps,\n 'indices' | 'memory' | 'tools'\n> & {\n /**\n * Variant of the Sidepanel positioning.\n *\n * - `inline` pushes page content when opened\n * - `floating` is positioned above all other content on page.\n *\n * @default 'floating'\n */\n variant?: PanelVariant;\n /**\n * Side of the page which the panel will originate from.\n *\n * @default 'right'\n */\n side?: PanelSide;\n /**\n * The selector of the element to push when Sidepanel opens with `inline`\n * variant.\n *\n * @default `'#root, main, .app, body'`\n */\n pushSelector?: string;\n /**\n * Width of the Sidepanel (px or any CSS width).\n *\n * @default `360px`\n */\n width?: number | string;\n /**\n * Width when expanded (px or any CSS width).\n *\n * @default `580px`\n */\n expandedWidth?: number | string;\n /**\n * The container element where the panel should be portaled to.\n *\n * @default `document.body`\n */\n portalContainer?: DocumentFragment | Element | null;\n /**\n * Enables displaying suggested questions on new conversation screen.\n *\n * @default false\n */\n suggestedQuestions?: boolean;\n /** Translations specific to the Sidepanel panel. */\n translations?: SidepanelTranslations;\n /**\n * Configuration for keyboard shortcuts. Allows enabling/disabling specific\n * shortcuts.\n *\n * @default `{ 'Ctrl/Cmd+I': true }`\n */\n keyboardShortcuts?: SidepanelShortcuts;\n};\n\ntype Props = Omit<\n DocSearchSidepanelProps,\n 'button' | 'indices' | 'memory' | 'panel' | 'tools'\n> &\n SidepanelProps &\n SidepanelSearchParameters & {\n isOpen?: boolean;\n onOpen: () => void;\n onClose: () => void;\n initialMessage?: InitialAskAiMessage;\n };\n\nfunction SidepanelInner(\n {\n isOpen = false,\n onOpen,\n onClose,\n assistantId,\n apiKey,\n appId,\n indexName,\n variant = 'floating',\n searchParameters,\n pushSelector,\n width,\n expandedWidth,\n suggestedQuestions: suggestedQuestionsEnabled = false,\n translations = {},\n keyboardShortcuts,\n side = 'right',\n initialMessage,\n tools = EMPTY_TOOLS,\n memory,\n indices,\n }: Props,\n ref: React.ForwardedRef<SidepanelRef>\n): JSX.Element {\n const [isExpanded, setIsExpanded] = React.useState(false);\n const [sidepanelState, setSidepanelState] =\n React.useState<SidepanelState>('new-conversation');\n const [stoppedStreaming, setStoppedStreaming] = React.useState(false);\n const sidepanelContainerRef = React.useRef<HTMLDivElement>(null);\n const promptInputRef = React.useRef<HTMLTextAreaElement>(null);\n const isMobile = useIsMobile();\n\n const expectedWidth = useSidepanelWidth({\n isExpanded,\n width,\n expandedWidth,\n });\n\n const selectors = React.useMemo(\n () => pushSelector ?? '#root, main, .app, body',\n [pushSelector]\n );\n\n const toggleIsExpanded = useCallback((): void => {\n setIsExpanded(!isExpanded);\n }, [isExpanded]);\n\n const searchClient = useSearchClient(appId, apiKey, setSidepanelSearchClient);\n\n const {\n chatId,\n status,\n sendMessage,\n stopAskAiStreaming,\n isStreaming,\n exchanges,\n conversations,\n messages,\n sendFeedback,\n askAiError,\n startNewConversation,\n restoreConversation,\n } = useAskAi({\n appId,\n indexName,\n assistantId,\n apiKey,\n searchParameters,\n tools,\n memory,\n indices,\n });\n\n const suggestedQuestions = useSuggestedQuestions({\n assistantId,\n suggestedQuestionsEnabled,\n searchClient,\n });\n\n const prevStatus = React.useRef(status);\n\n const handleSend = React.useCallback(\n (prompt: string): void => {\n setStoppedStreaming(false);\n\n sendMessage({ text: prompt });\n setSidepanelState('conversation');\n },\n [sendMessage]\n );\n\n const handleStartNewConversation = (): void => {\n startNewConversation();\n setSidepanelState('new-conversation');\n };\n\n const handleSelectQuestion = (question: SuggestedQuestionHit): void => {\n setStoppedStreaming(false);\n startNewConversation();\n sendMessage(\n { text: question.question },\n {\n body: {\n suggestedQuestionId: question.objectID,\n },\n }\n );\n setSidepanelState('conversation');\n };\n\n const handleStopStreaming = (): void => {\n setStoppedStreaming(true);\n stopAskAiStreaming();\n };\n\n const handleSelectConversation = React.useCallback(\n (conversation: StoredAskAiState): void => {\n if (conversation.messages) {\n restoreConversation(conversation.messages, conversation.chatId);\n } else if (conversation.query) {\n sendMessage({ text: conversation.query });\n }\n\n setSidepanelState('conversation');\n },\n [sendMessage, restoreConversation]\n );\n\n useManageSidepanelLayout({\n variant,\n expectedWidth,\n selectors,\n isOpen,\n side,\n });\n\n useSidepanelKeyboardEvents({\n onClose,\n onOpen,\n isOpen,\n keyboardShortcuts,\n });\n\n // Expose imperative handle for programmatic control\n React.useImperativeHandle(\n ref,\n () => ({\n open: onOpen,\n close: onClose,\n get isReady(): boolean {\n return true;\n },\n get isOpen(): boolean {\n return isOpen;\n },\n }),\n [onOpen, onClose, isOpen]\n );\n\n React.useEffect(() => {\n if (prevStatus.current === 'streaming' && status === 'ready') {\n if (stoppedStreaming && messages.at(-1)) {\n messages.at(-1)!.metadata = {\n stopped: true,\n };\n }\n\n for (const part of messages[0].parts) {\n if (part.type === 'text') {\n conversations.add(buildDummyAskAiHit(part.text, messages, chatId));\n }\n }\n }\n\n prevStatus.current = status;\n }, [conversations, status, messages, stoppedStreaming, chatId]);\n\n React.useEffect(() => {\n function setFullViewportHeight(): void {\n if (sidepanelContainerRef.current) {\n const vh = window.innerHeight * 0.01;\n sidepanelContainerRef.current.style.setProperty('--sp-vh', `${vh}px`);\n }\n }\n\n setFullViewportHeight();\n\n window.addEventListener('resize', setFullViewportHeight);\n\n return (): void => {\n window.removeEventListener('resize', setFullViewportHeight);\n };\n }, []);\n\n React.useEffect(() => {\n if (!initialMessage) return;\n\n let selectedConversation: StoredAskAiState | undefined;\n\n if (initialMessage.messageId) {\n selectedConversation = conversations.getConversation?.(\n initialMessage.messageId\n );\n }\n\n if (selectedConversation) {\n handleSelectConversation(selectedConversation);\n } else {\n startNewConversation();\n sendMessage(\n {\n text: initialMessage.query,\n },\n initialMessage.suggestedQuestionId\n ? {\n body: {\n suggestedQuestionId: initialMessage.suggestedQuestionId,\n },\n }\n : {}\n );\n setSidepanelState('conversation');\n }\n }, [\n initialMessage,\n sendMessage,\n conversations,\n handleSelectConversation,\n startNewConversation,\n ]);\n\n // Autofocus the prompt input when the sidepanel opens and blur it when\n // it closes. Disabled on mobile because focusing the textarea triggers the\n // virtual keyboard which disrupts the layout — this is a known issue that\n // has not been resolved yet.\n React.useEffect(() => {\n if (isOpen && !isMobile) {\n promptInputRef.current?.focus();\n }\n\n if (!isOpen) {\n promptInputRef.current?.blur();\n }\n }, [isOpen, isMobile]);\n\n return (\n <div\n className={`DocSearch-Sidepanel-Container ${variant} side-${side}${isOpen ? ' is-open' : ''}${isExpanded ? ' is-expanded' : ''}`}\n style={\n {\n '--sp-width': expectedWidth,\n } as React.CSSProperties\n }\n role=\"dialog\"\n tabIndex={-1}\n ref={sidepanelContainerRef}\n >\n <aside\n id=\"docsearch-sidepanel\"\n className={`DocSearch-Sidepanel ${sidepanelState}`}\n >\n <SidepanelHeader\n sidepanelState={sidepanelState}\n exchanges={exchanges}\n setSidepanelState={setSidepanelState}\n hasConversations={conversations.getAll().length > 0}\n isStreaming={isStreaming}\n onNewConversation={handleStartNewConversation}\n onToggleExpanded={toggleIsExpanded}\n onClose={onClose}\n />\n <div className=\"DocSearch-Sidepanel-Content\">\n {sidepanelState === 'new-conversation' && (\n <NewConversationScreen\n suggestedQuestions={suggestedQuestions}\n translations={translations.newConversationScreen}\n onSelectQuestion={handleSelectQuestion}\n />\n )}\n {sidepanelState === 'conversation' && (\n <ConversationScreen\n exchanges={exchanges}\n status={status}\n conversations={conversations}\n handleFeedback={sendFeedback}\n translations={translations.conversationScreen}\n streamError={askAiError}\n memoryEnabled={memory?.enabled ?? false}\n tools={tools}\n onSelectPromptSuggestion={handleSend}\n />\n )}\n {sidepanelState === 'conversation-history' && (\n <ConversationHistoryScreen\n conversations={conversations}\n selectConversation={handleSelectConversation}\n />\n )}\n </div>\n <PromptForm\n ref={promptInputRef}\n exchanges={exchanges}\n isStreaming={isStreaming}\n translations={translations.promptForm}\n onSend={handleSend}\n onStopStreaming={handleStopStreaming}\n />\n <footer className=\"DocSearch-Sidepanel-Footer\">\n <span className=\"DocSearch-Logo DocSearch-Sidepanel--powered-by\">\n <AlgoliaLogo translations={translations.logo} />\n </span>\n </footer>\n </aside>\n </div>\n );\n}\n\nexport const Sidepanel = React.forwardRef(SidepanelInner);\n","import type { SidepanelShortcuts } from '@docsearch/core';\nimport React, { useEffect, useState } from 'react';\nimport type { JSX } from 'react';\n\nimport { SparklesIcon } from '../icons';\nimport { ACTION_KEY_APPLE, ACTION_KEY_DEFAULT, isAppleDevice } from '../utils';\n\nexport type SidepanelButtonTranslations = Partial<{\n /**\n * Text to be displayed when button has variant: `inline`.\n *\n * @default 'Ask AI'\n */\n buttonText: string;\n /**\n * Aria label text for the button.\n *\n * @default 'Ask AI'\n */\n buttonAriaLabel: string;\n}>;\n\nexport type ButtonVariant = 'floating' | 'inline';\n\nexport type SidepanelButtonProps = {\n /**\n * Variant of the button positioning and styling.\n *\n * - `inline` displays the button inline where rendered, with extra text\n * - `floating` displays the button floating in bottom right of screen with just\n * icon.\n *\n * @default 'floating'\n */\n variant?: ButtonVariant;\n /** Translations specific to the Sidepanel button. */\n translations?: SidepanelButtonTranslations;\n /**\n * Configuration for keyboard shortcuts. Allows enabling/disabling specific\n * shortcuts.\n *\n * @default `{ 'Ctrl/Cmd+I': true }`\n */\n keyboardShortcuts?: SidepanelShortcuts;\n};\n\ntype Props = React.ComponentProps<'button'> & SidepanelButtonProps;\n\nexport const SidepanelButton = ({\n variant = 'floating',\n keyboardShortcuts,\n translations = {},\n ...props\n}: Props): JSX.Element => {\n const { buttonText = 'Ask AI', buttonAriaLabel = 'Ask AI' } = translations;\n const [key, setKey] = useState<\n typeof ACTION_KEY_APPLE | typeof ACTION_KEY_DEFAULT | null\n >(null);\n\n useEffect(() => {\n if (typeof navigator !== 'undefined') {\n isAppleDevice() ? setKey(ACTION_KEY_APPLE) : setKey(ACTION_KEY_DEFAULT);\n }\n }, []);\n\n const actionKeyAltText = key === ACTION_KEY_DEFAULT ? 'Control' : 'Meta';\n const isCtrlCmdIEnabled = keyboardShortcuts?.['Ctrl/Cmd+I'] !== false;\n const shortcut = `${actionKeyAltText}+i`;\n\n return (\n <button\n className={`DocSearch-SidepanelButton ${variant}`}\n type=\"button\"\n aria-label={\n isCtrlCmdIEnabled ? `${buttonAriaLabel} (${shortcut})` : buttonAriaLabel\n }\n aria-keyshortcuts={isCtrlCmdIEnabled ? shortcut : undefined}\n {...(variant === 'floating' ? { tabIndex: -1 } : {})}\n {...props}\n >\n <SparklesIcon />\n {variant !== 'floating' && buttonText}\n </button>\n );\n};\n","import { DocSearch, useDocSearch } from '@docsearch/core';\nimport type {\n DocSearchCallbacks,\n DocSearchRef,\n DocSearchTheme,\n SidepanelShortcuts,\n} from '@docsearch/core';\nimport type { JSX } from 'react';\nimport React from 'react';\nimport { createPortal } from 'react-dom';\n\nimport type {\n AgentStudioIndices,\n AgentStudioSearchParameters,\n Memory,\n} from './DocSearchAI';\nimport type {\n SidepanelButtonProps,\n SidepanelProps as SidepanelPanelProps,\n} from './Sidepanel/index';\nimport { SidepanelButton, Sidepanel } from './Sidepanel/index';\nimport type { ToolCalls } from './types/AskiAi';\n\nexport type { DocSearchRef, DocSearchCallbacks } from '@docsearch/core';\n\nexport type SidepanelSearchParameters = {\n /**\n * The search parameters to use for the ask AI feature. Keyed by the index\n * name.\n *\n * @example\n * {\n * \"INDEX_NAME\": { distinct: false }\n * }\n */\n searchParameters?: AgentStudioSearchParameters;\n};\n\nexport type DocSearchSidepanelProps = DocSearchCallbacks & {\n /** The assistant ID to use for the ask AI feature. */\n assistantId: string;\n /** Public api key with search permissions for the index. */\n apiKey: string;\n /** Algolia application id used by the search client. */\n appId: string;\n /**\n * The index name to use for the ask AI feature. Your assistant will search\n * this index for relevant documents.\n */\n indexName: string;\n /**\n * Configuration for keyboard shortcuts. Allows enabling/disabling specific\n * shortcuts.\n *\n * @default `{ 'Ctrl/Cmd+I': true }`\n */\n keyboardShortcuts?: SidepanelShortcuts;\n /**\n * Theme overrides applied to the Sidepanel button and panel.\n *\n * @default 'light'\n */\n theme?: DocSearchTheme;\n /** Props specific to the Sidepanel button. */\n button?: Omit<SidepanelButtonProps, 'keyboardShortcuts'>;\n /** Props specific to the Sidepanel panel. */\n panel?: Omit<SidepanelPanelProps, 'keyboardShortcuts'>;\n /**\n * Use custom tools driven by Agent Studio.\n *\n * For best performance, memoize this object with `useMemo` or define it\n * outside the component. Inline object literals will be recreated every\n * render but will not affect correctness.\n */\n tools?: ToolCalls;\n /**\n * Configuration for the Agent Studio memory feature.\n *\n * @example\n * { enabled: true, userToken: '{{SERVER_GENERATED_JWT_TOKEN}}' }\n *\n * @see https://www.algolia.com/doc/guides/algolia-ai/agent-studio/how-to/memory/overview\n */\n memory?: Memory;\n /** List of dynamic indices for the Agent Studio search tool to use. */\n indices?: AgentStudioIndices[];\n};\n\ntype SidepanelProps = DocSearchSidepanelProps & SidepanelSearchParameters;\n\nfunction DocSearchSidepanelComponent(\n {\n keyboardShortcuts,\n theme,\n onReady,\n onOpen,\n onClose,\n onSidepanelOpen,\n onSidepanelClose,\n ...props\n }: SidepanelProps,\n ref: React.ForwardedRef<DocSearchRef>\n): JSX.Element {\n return (\n <DocSearch\n keyboardShortcuts={keyboardShortcuts}\n theme={theme}\n ref={ref}\n onReady={onReady}\n onOpen={onOpen}\n onClose={onClose}\n onSidepanelOpen={onSidepanelOpen}\n onSidepanelClose={onSidepanelClose}\n >\n <DocSearchSidepanelComp {...props} />\n </DocSearch>\n );\n}\n\nexport const DocSearchSidepanel = React.forwardRef(DocSearchSidepanelComponent);\n\nfunction DocSearchSidepanelComp({\n button: buttonProps = {},\n panel: { portalContainer, ...panelProps } = {},\n ...rootProps\n}: DocSearchSidepanelProps): JSX.Element {\n const {\n docsearchState,\n setDocsearchState,\n keyboardShortcuts,\n registerView,\n initialAskAiMessage,\n } = useDocSearch();\n\n const toggleSidepanelState = React.useCallback(() => {\n setDocsearchState(docsearchState === 'sidepanel' ? 'ready' : 'sidepanel');\n }, [docsearchState, setDocsearchState]);\n\n const handleClose = (): void => {\n setDocsearchState('ready');\n };\n\n const handleOpen = (): void => {\n setDocsearchState('sidepanel');\n };\n\n const containerElement = React.useMemo(\n () => portalContainer ?? document.body,\n [portalContainer]\n );\n\n React.useEffect(() => {\n registerView('sidepanel');\n }, [registerView]);\n\n const ButtonComp = React.useMemo(\n () => (\n <SidepanelButton\n keyboardShortcuts={keyboardShortcuts}\n onClick={toggleSidepanelState}\n {...buttonProps}\n />\n ),\n [keyboardShortcuts, toggleSidepanelState, buttonProps]\n );\n\n return (\n <>\n {buttonProps.variant === 'inline'\n ? ButtonComp\n : createPortal(ButtonComp, containerElement)}\n {createPortal(\n <Sidepanel\n initialMessage={initialAskAiMessage}\n isOpen={docsearchState === 'sidepanel'}\n onClose={handleClose}\n onOpen={handleOpen}\n {...rootProps}\n {...panelProps}\n keyboardShortcuts={keyboardShortcuts}\n />,\n containerElement\n )}\n </>\n );\n}\n\nexport * from './Sidepanel/index';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sidepanel.js","names":[],"sources":["../../src/icons/SendIcon.tsx","../../src/icons/ExpandIcon.tsx","../../src/icons/FolderIcon.tsx","../../src/icons/EditIcon.tsx","../../src/useIsMobile.ts","../../src/Sidepanel/ConversationHistoryScreen.tsx","../../src/Sidepanel/AggregatedSearchBlock.tsx","../../src/Sidepanel/ConversationScreen.tsx","../../src/Sidepanel/NewConversationScreen.tsx","../../src/Sidepanel/PromptForm.tsx","../../src/Sidepanel/setSidepanelSearchClient.ts","../../src/Sidepanel/SidepanelHeader.tsx","../../src/Sidepanel/useManageSidepanelLayout.ts","../../src/Sidepanel/useSidepanelKeyboardEvents.ts","../../src/Sidepanel/useSidepanelWidth.ts","../../src/Sidepanel/Sidepanel.tsx","../../src/Sidepanel/SidepanelButton.tsx","../../src/Sidepanel.tsx"],"sourcesContent":["import type { JSX } from 'react';\nimport React from 'react';\n\nexport const SendIcon = (): JSX.Element => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m5 12 7-7 7 7\" />\n <path d=\"M12 19V5\" />\n </svg>\n );\n};\n","import type { JSX } from 'react';\nimport React from 'react';\n\nexport const ExpandIcon = (): JSX.Element => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 13 13\"\n fill=\"none\"\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n 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\"\n fill=\"currentColor\"\n />\n </svg>\n );\n};\n","import React from 'react';\nimport type { JSX } from 'react';\n\nexport const FolderIcon = (): JSX.Element => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <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\" />\n </svg>\n );\n};\n","import React from 'react';\nimport type { JSX } from 'react';\n\nexport const EditIcon = (): JSX.Element => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\" />\n <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\" />\n </svg>\n );\n};\n","import React from 'react';\n\nexport const useIsMobile = (): boolean => {\n const [isMobile, setIsMobile] = React.useState(false);\n\n React.useEffect(() => {\n const checkForMobile = (): void => {\n const isMobileMediaQuery = window.matchMedia('(max-width: 768px)');\n\n setIsMobile(isMobileMediaQuery.matches);\n };\n\n checkForMobile();\n\n window.addEventListener('resize', checkForMobile);\n\n return (): void => {\n window.removeEventListener('resize', checkForMobile);\n };\n }, []);\n\n return isMobile;\n};\n","/* eslint-disable jsx-a11y/no-noninteractive-element-to-interactive-role */\nimport React from 'react';\nimport type { JSX } from 'react';\n\nimport { CloseIcon, RecentIcon } from '../icons';\nimport type { StoredSearchPlugin } from '../stored-searches';\nimport type { StoredAskAiState } from '../types';\n\ntype ConversationHistoryScreenProps = {\n conversations: StoredSearchPlugin<StoredAskAiState>;\n selectConversation: (conversation: StoredAskAiState) => void;\n};\n\nexport const ConversationHistoryScreen = ({\n conversations,\n selectConversation,\n}: ConversationHistoryScreenProps): JSX.Element => {\n const [items, setItems] = React.useState(() => conversations.getAll());\n\n const handleRemoveConversation = (item: StoredAskAiState): void => {\n conversations.remove(item);\n setItems(conversations.getAll());\n };\n\n return (\n <div className=\"DocSearch-Sidepanel-ConversationHistoryScreen\">\n <ul>\n {items.map((item) => (\n <li\n key={item.objectID}\n className=\"DocSearch-Sidepanel-RecentConversation\"\n >\n <a\n href={item.url}\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n\n selectConversation(item);\n }}\n >\n <div className=\"DocSearch-Sidepanel-RecentConversation-container\">\n <div className=\"DocSearch-Sidepanel-RecentConversation-icon\">\n <RecentIcon />\n </div>\n\n <div className=\"DocSearch-Sidepanel-RecentConversation-content\">\n <span className=\"DocSearch-Sidepanel-RecentConversation-title\">\n {item.hierarchy.lvl1}\n </span>\n </div>\n\n <div className=\"DocSearch-Hit-action\">\n <button\n className=\"DocSearch-Hit-action-button\"\n type=\"button\"\n title=\"Remove conversation from history\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n handleRemoveConversation(item);\n }}\n >\n <CloseIcon />\n </button>\n </div>\n </div>\n </a>\n </li>\n ))}\n </ul>\n </div>\n );\n};\n","import React, { Fragment } from 'react';\nimport type { JSX } from 'react';\n\nimport { SearchIcon } from '../icons';\n\ntype AggregatedSearchBlockProps = {\n queries: string[];\n};\n\nconst before = 'Searched for ';\nconst separator = ', ';\nconst lastSeparator = ' and ';\nconst after = '';\n\nexport function AggregatedSearchBlock({\n queries,\n}: AggregatedSearchBlockProps): JSX.Element {\n return (\n <div className=\"DocSearch-AskAiScreen-MessageContent-Tool Tool--AggregatedResult\">\n <SearchIcon size={18} />\n <span>\n {before && <span>{before}</span>}\n {queries.map((q, idx) => (\n // eslint-disable-next-line react/no-array-index-key\n <Fragment key={q + idx}>\n <span className=\"DocSearch-AskAiScreen-MessageContent-Tool-Query\">\n "{q}"\n </span>\n {idx < queries.length - 2 && separator}\n {idx === queries.length - 2 && lastSeparator}\n </Fragment>\n ))}\n {after && <span>{after}</span>}\n </span>\n </div>\n );\n}\n","import type { UseChatHelpers } from '@ai-sdk/react';\nimport type { JSX } from 'react';\nimport React, { memo, useMemo } from 'react';\n\nimport { type Exchange } from '../AskAiScreen';\nimport { ConversationPromptSuggestions } from '../components/ConversationPromptSuggestions';\nimport { FeedbackActions } from '../components/FeedbackActions';\nimport { SourcesPanel } from '../components/SourcesPanel';\nimport { ToolCall, type ToolCallTranslations } from '../components/ToolCall';\nimport { AlertIcon, LoadingIcon } from '../icons';\nimport { MemoizedMarkdown } from '../MemoizedMarkdown';\nimport type { StoredSearchPlugin } from '../stored-searches';\nimport type { OnAskAiFeedback, StoredAskAiState } from '../types';\nimport { type AIMessage, type ToolCalls } from '../types/AskiAi';\nimport {\n extractLinksFromMessage,\n getMessageContent,\n EMPTY_TOOLS,\n isAIToolPart,\n getAgentPromptSuggestions,\n} from '../utils/ai';\nimport { groupConsecutiveToolResults } from '../utils/groupConsecutiveToolResults';\n\nimport { AggregatedSearchBlock } from './AggregatedSearchBlock';\n\nexport type ConversationScreenTranslations = Partial<\n ToolCallTranslations & {\n /** Text shown as an LLM disclaimer. */\n conversationDisclaimer: string;\n /** Text shown while assistant is reasoning. */\n reasoningText: string;\n /** Text show while assistant is thinking. */\n thinkingText: string;\n /** Text shown describing a singular related source. */\n relatedSourcesText: string;\n /** Text shown describing multiple related sources. */\n relatedSourcesTextPlural: string;\n /** Message that's shown when user has stopped the streaming of a message. */\n stoppedStreamingText: string;\n /** Text shown for copy button on code snippets. */\n copyButtonText: string;\n /** Message shown after clicking copy. */\n copyButtonCopiedText: string;\n /** Title for thumbs up feedback icon. */\n likeButtonTitle: string;\n /** Title for thumbs down feedback icon. */\n dislikeButtonTitle: string;\n /** Message displayed after feedback action. */\n thanksForFeedbackText: string;\n /** Title shown at the top of the negative feedback note panel. */\n feedbackPanelTitle: string;\n /** Placeholder for the negative feedback details textarea. */\n feedbackDetailsPlaceholder: string;\n /** Disclaimer shown inside the negative feedback note panel. */\n feedbackDisclaimerText: string;\n /** Submit button text for the negative feedback note panel. */\n feedbackSubmitButtonText: string;\n /** Accessible title for the negative feedback note panel close button. */\n feedbackCloseButtonTitle: string;\n /** Reason chip labels for the negative feedback note panel. */\n feedbackTagIncorrect: string;\n feedbackTagNotWhatIAsked: string;\n feedbackTagSlowOrBuggy: string;\n feedbackTagStyleOrTone: string;\n feedbackTagSafetyOrLegal: string;\n feedbackTagOther: string;\n /** Error title shown if there is an error while chatting. */\n errorTitleText: string;\n suggestedPromptsTitleText: string;\n }\n>;\n\nexport type ConversationScreenProps = {\n exchanges: Exchange[];\n conversations: StoredSearchPlugin<StoredAskAiState>;\n translations?: ConversationScreenTranslations;\n status: UseChatHelpers<AIMessage>['status'];\n handleFeedback?: OnAskAiFeedback;\n streamError?: Error;\n memoryEnabled?: boolean;\n tools?: ToolCalls;\n onSelectPromptSuggestion: (prompt: string) => void;\n};\n\ntype ConversationnExchangeProps = {\n exchange: Exchange;\n isLastExchange: boolean;\n status: ConversationScreenProps['status'];\n conversations: ConversationScreenProps['conversations'];\n translations?: ConversationScreenTranslations;\n onFeedback?: ConversationScreenProps['handleFeedback'];\n streamError?: ConversationScreenProps['streamError'];\n memoryEnabled?: boolean;\n tools: ToolCalls;\n onSelectPromptSuggestion: (prompt: string) => void;\n};\n\nconst ConversationExchange = React.forwardRef<\n HTMLDivElement,\n ConversationnExchangeProps\n>(\n (\n {\n exchange,\n translations = {},\n isLastExchange,\n conversations,\n onFeedback,\n status,\n streamError,\n memoryEnabled,\n tools,\n onSelectPromptSuggestion,\n },\n conversationRef\n ): JSX.Element => {\n const { userMessage, assistantMessage } = exchange;\n\n const {\n reasoningText = 'Reasoning...',\n thinkingText = 'Thinking...',\n searchingText = 'Searching...',\n relatedSourcesText,\n relatedSourcesTextPlural,\n stoppedStreamingText = 'You stopped this response',\n preToolCallText = 'Searching...',\n toolCallResultText = 'Searched for',\n copyButtonText = 'Copy',\n copyButtonCopiedText = 'Copied!',\n errorTitleText = 'Chat error',\n savedMemoryToolResultText = 'Saved to memory',\n memoryToolResultText = 'Used memory to enhance results',\n suggestedPromptsTitleText = 'Suggested prompts',\n } = translations;\n\n const assistantContent = useMemo(\n () => getMessageContent(assistantMessage),\n [assistantMessage]\n );\n const userContent = useMemo(\n () => getMessageContent(userMessage),\n [userMessage]\n );\n\n const assistantParts = useMemo(\n () => groupConsecutiveToolResults(assistantMessage?.parts || []),\n [assistantMessage]\n );\n const urlsToDisplay = React.useMemo(\n () => extractLinksFromMessage(assistantMessage),\n [assistantMessage]\n );\n const suggestedPrompts = React.useMemo(() => {\n if (!isLastExchange) return [];\n return getAgentPromptSuggestions(assistantMessage?.parts || []);\n }, [assistantMessage, isLastExchange]);\n\n const wasStopped =\n userMessage.metadata?.stopped || assistantMessage?.metadata?.stopped;\n const isThinking =\n ['submitted', 'streaming'].includes(status) &&\n !assistantParts.some((part) => part.type !== 'step-start');\n const showActions =\n !wasStopped &&\n (!isLastExchange ||\n (isLastExchange && status === 'ready' && Boolean(assistantMessage)));\n\n const messageId = assistantMessage?.id || exchange.id;\n\n return (\n <div\n className=\"DocSearch-AskAiScreen-Response-Container\"\n ref={conversationRef}\n >\n <div className=\"DocSearch-AskAiScreen-Response\">\n <div className=\"DocSearch-AskAiScreen-Message DocSearch-AskAiScreen-Message--user\">\n <p className=\"DocSearch-AskAiScreen-Query\">{userContent ?? ''}</p>\n </div>\n <div className=\"DocSearch-AskAiScreen-Message DocSearch-AskAiScreen-Message--assistant\">\n <div className=\"DocSearch-AskAiScreen-MessageContent\">\n {status === 'error' && streamError && isLastExchange && (\n <div className=\"DocSearch-AskAiScreen-Error\" role=\"alert\">\n <AlertIcon aria-hidden=\"true\" />\n <div className=\"DocSearch-AskAiScreen-Error-Content\">\n <h4 className=\"DocSearch-AskAiScreen-Error-Title\">\n {errorTitleText}\n </h4>\n <MemoizedMarkdown\n content={streamError.message}\n copyButtonText=\"\"\n copyButtonCopiedText=\"\"\n isStreaming={false}\n />\n </div>\n </div>\n )}\n\n {assistantParts.map((part, idx) => {\n const index = idx;\n\n if (part.type === 'reasoning' && part.state === 'streaming') {\n return (\n <div\n key={index}\n className=\"DocSearch-AskAiScreen-MessageContent-Reasoning DocSearch-shimmer\"\n >\n <LoadingIcon className=\"DocSearch-AskAiScreen-SmallerLoadingIcon\" />\n <span className=\"DocSearch-shimmer\">{reasoningText}</span>\n </div>\n );\n }\n\n if (part.type === 'aggregated-tool-call') {\n return (\n <AggregatedSearchBlock key={index} queries={part.queries} />\n );\n }\n\n if (isAIToolPart(part)) {\n return (\n <ToolCall\n key={index}\n part={part}\n translations={{\n preToolCallText,\n searchingText,\n toolCallResultText,\n savedMemoryToolResultText,\n memoryToolResultText,\n }}\n tools={tools}\n memoryEnabled={memoryEnabled}\n />\n );\n }\n\n if (typeof part === 'string') {\n return (\n <MemoizedMarkdown\n key={index}\n content={part}\n copyButtonText={copyButtonText}\n copyButtonCopiedText={copyButtonCopiedText}\n isStreaming={false}\n />\n );\n }\n\n if (part.type === 'text') {\n return (\n <MemoizedMarkdown\n key={index}\n content={part.text}\n copyButtonText={copyButtonText}\n copyButtonCopiedText={copyButtonCopiedText}\n isStreaming={part.state === 'streaming'}\n />\n );\n }\n\n return null;\n })}\n\n {isThinking && isLastExchange && assistantParts.length === 0 && (\n <div\n className=\"DocSearch-AskAiScreen-MessageContent-Thinking\"\n role=\"status\"\n >\n <span className=\"DocSearch-shimmer\">{thinkingText}</span>\n <span className=\"DocSearch-AskAi-Thinking-Skeleton DocSearch-shimmer\" />\n <span className=\"DocSearch-AskAi-Thinking-Skeleton DocSearch-AskAi-Thinking-Skeleton--short DocSearch-shimmer\" />\n </div>\n )}\n </div>\n\n {wasStopped && (\n <p className=\"DocSearch-AskAiScreen-MessageContent-Stopped\">\n {stoppedStreamingText}\n </p>\n )}\n </div>\n\n <div className=\"DocSearch-AskAiScreen-Answer-Footer\">\n <SourcesPanel\n links={urlsToDisplay}\n titleText={relatedSourcesText}\n pluralTitleText={relatedSourcesTextPlural}\n />\n <FeedbackActions\n isSidepanel={true}\n id={messageId}\n showActions={showActions}\n latestAssistantMessageContent={assistantContent || null}\n translations={translations}\n conversations={conversations}\n onFeedback={onFeedback}\n />\n </div>\n\n {suggestedPrompts.length > 0 && (\n <ConversationPromptSuggestions\n title={suggestedPromptsTitleText}\n suggestions={suggestedPrompts}\n onSelectPromptSuggestion={onSelectPromptSuggestion}\n />\n )}\n </div>\n </div>\n );\n }\n);\n\nexport const ConversationScreen = memo(\n ({\n exchanges,\n translations = {},\n handleFeedback,\n tools = EMPTY_TOOLS,\n status,\n conversations,\n streamError,\n memoryEnabled,\n onSelectPromptSuggestion,\n }: ConversationScreenProps): JSX.Element => {\n const {\n conversationDisclaimer = 'Answers are generated with AI which can make mistakes. Verify responses.',\n } = translations;\n\n const mostRecentExchangeRef = React.useRef<HTMLDivElement>(null);\n const totalExchanges = exchanges.length;\n\n // Only scroll the most recent exchange into view when needed\n React.useEffect(() => {\n if (mostRecentExchangeRef.current) {\n mostRecentExchangeRef.current.scrollIntoView({\n behavior: 'smooth',\n block: 'start',\n });\n }\n }, [totalExchanges]);\n\n return (\n <div className=\"DocSearch-Sidepanel-ConversationScreen\">\n <p className=\"DocSearch-Sidepanel-ConversationScreen-disclaimer\">\n {conversationDisclaimer}\n </p>\n\n {exchanges.slice().map((exchange, idx) => {\n const isLastExchange = idx === exchanges.length - 1;\n return (\n <ConversationExchange\n key={exchange.id}\n exchange={exchange}\n translations={translations}\n isLastExchange={isLastExchange}\n ref={isLastExchange ? mostRecentExchangeRef : null}\n tools={tools}\n status={status}\n conversations={conversations}\n streamError={streamError}\n memoryEnabled={memoryEnabled}\n onFeedback={handleFeedback}\n onSelectPromptSuggestion={onSelectPromptSuggestion}\n />\n );\n })}\n </div>\n );\n }\n);\n","import type { JSX } from 'react';\nimport React from 'react';\n\nimport type { SuggestedQuestionHit } from '../types';\n\nexport type NewConversationScreenTranslations = Partial<{\n /** Title to be shown on the new conversation/starting screen. */\n titleText: string;\n /** Introduction text displayed on the new conversation/starting screen. */\n introductionText: string;\n}>;\n\ntype NewConversationScreenProps = {\n suggestedQuestions: SuggestedQuestionHit[];\n onSelectQuestion: (question: SuggestedQuestionHit) => void;\n translations?: NewConversationScreenTranslations;\n};\n\nexport const NewConversationScreen = ({\n suggestedQuestions,\n onSelectQuestion,\n translations = {},\n}: NewConversationScreenProps): JSX.Element => {\n const {\n titleText = 'How can I help you today?',\n introductionText = 'I search through your documentation to help you find setup guides, feature details and troubleshooting tips, fast.',\n } = translations;\n\n return (\n <div className=\"DocSearch-Sidepanel-NewConversationScreen\">\n <h4 className=\"DocSearch-Sidepanel-Screen--title\">{titleText}</h4>\n <p className=\"DocSearch-Sidepanel-Screen--introduction\">\n {introductionText}\n </p>\n\n <div className=\"DocSearch-Sidepanel-List\">\n {suggestedQuestions.map((q) => (\n <button\n key={q.objectID}\n type=\"button\"\n className=\"DocSearch-Sidepanel-SuggestedQuestion\"\n title=\"View conversation\"\n onClick={() => {\n onSelectQuestion(q);\n }}\n >\n <span>{q.question}</span>\n </button>\n ))}\n </div>\n </div>\n );\n};\n","import React from 'react';\nimport type { JSX } from 'react';\n\nimport type { Exchange } from '../AskAiScreen';\nimport { SendIcon, StopIcon } from '../icons';\nimport { useIsMobile } from '../useIsMobile';\n\nexport type PromptFormTranslations = Partial<{\n /** Initial placeholder for the prompt input. */\n promptPlaceholderText: string;\n /** Placeholder text for wile a conversation is streaming. */\n promptAnsweringText: string;\n /** Placeholder text for after a question has already been asked. */\n promptAskAnotherQuestionText: string;\n /** Disclaimer text displayed beneath the prompt form. */\n promptDisclaimerText: string;\n promptLabelText: string;\n promptAriaLabelText: string;\n}>;\n\ntype Props = {\n exchanges: Exchange[];\n isStreaming: boolean;\n translations?: PromptFormTranslations;\n onSend: (prompt: string) => void;\n onStopStreaming: () => void;\n};\n\nconst MAX_PROMPT_ROWS = 8;\n\nexport const PromptForm = React.forwardRef<HTMLTextAreaElement, Props>(\n (\n { exchanges, isStreaming, translations = {}, onSend, onStopStreaming },\n ref\n ): JSX.Element => {\n const isMobile = useIsMobile();\n const [userPrompt, setUserPrompt] = React.useState('');\n const promptRef = React.useRef<HTMLTextAreaElement>(null);\n\n React.useImperativeHandle(\n ref,\n () => promptRef.current as HTMLTextAreaElement\n );\n\n const {\n promptPlaceholderText = 'Ask a question',\n promptAnsweringText = 'Answering...',\n promptAskAnotherQuestionText = 'Ask another question',\n promptDisclaimerText = 'Answers are generated with AI which can make mistakes.',\n promptLabelText = 'Press Enter to send, or Shift and Enter for new line.',\n promptAriaLabelText = 'Prompt input',\n } = translations;\n\n const managePromptHeight = (): void => {\n if (!promptRef.current) return;\n\n const textArea = promptRef.current;\n const styles = getComputedStyle(textArea);\n\n const lineHeight = parseFloat(styles.lineHeight);\n const paddingTop = parseFloat(styles.paddingTop);\n const paddingBottom = parseFloat(styles.paddingBottom);\n const padding = paddingTop + paddingBottom;\n\n textArea.style.height = 'auto';\n\n const fullHeight = textArea.scrollHeight;\n const maxHeight = MAX_PROMPT_ROWS * lineHeight + padding;\n\n textArea.style.overflowY = fullHeight > maxHeight ? 'auto' : 'hidden';\n textArea.style.height = `${Math.min(fullHeight, maxHeight)}px`;\n };\n\n const handleSend = (): void => {\n if (isStreaming) return;\n\n const prompt = userPrompt.trim();\n\n if (prompt === '') return;\n\n onSend(prompt);\n\n setUserPrompt('');\n\n requestAnimationFrame(() => {\n promptRef.current?.focus();\n\n managePromptHeight();\n });\n };\n\n const handleKeyDown = (\n e: React.KeyboardEvent<HTMLTextAreaElement>\n ): void => {\n // Allow Enter to work normally (new line) when streaming\n if (isStreaming) return;\n\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n\n handleSend();\n }\n };\n\n React.useLayoutEffect(() => {\n managePromptHeight();\n }, [isMobile]);\n\n let promptPlaceholder = promptPlaceholderText;\n\n if (isStreaming) {\n promptPlaceholder = promptAnsweringText;\n } else if (exchanges.length > 0) {\n promptPlaceholder = promptAskAnotherQuestionText;\n }\n\n return (\n <div className=\"DocSearch-Sidepanel-Prompt\">\n <form\n className=\"DocSearch-Sidepanel-Prompt--form\"\n onSubmit={(e) => {\n e.preventDefault();\n\n if (isStreaming) return;\n\n handleSend();\n }}\n >\n <textarea\n ref={promptRef}\n placeholder={promptPlaceholder}\n className=\"DocSearch-Sidepanel-Prompt--textarea\"\n value={userPrompt}\n aria-label={promptAriaLabelText}\n aria-labelledby=\"prompt-label\"\n autoComplete=\"off\"\n translate=\"no\"\n rows={isMobile ? 1 : 2}\n onKeyDown={handleKeyDown}\n onInput={managePromptHeight}\n onChange={(e) => setUserPrompt(e.target.value)}\n />\n <span id=\"prompt-label\" className=\"sr-only\">\n {promptLabelText}\n </span>\n <div className=\"DocSearch-Sidepanel-Prompt--actions\">\n {isStreaming && (\n <button\n type=\"button\"\n title=\"Stop streaming\"\n className=\"DocSearch-Sidepanel-Prompt--stop\"\n onClick={onStopStreaming}\n >\n <StopIcon />\n </button>\n )}\n {!isStreaming && (\n <button\n type=\"submit\"\n aria-label=\"Send question\"\n title=\"Send question\"\n className=\"DocSearch-Sidepanel-Prompt--submit\"\n aria-disabled={userPrompt === ''}\n >\n <SendIcon />\n </button>\n )}\n </div>\n </form>\n <p className=\"DocSearch-Sidepanel-Prompt--disclaimer\">\n {promptDisclaimerText}\n </p>\n </div>\n );\n }\n);\n","import type { DocSearchTransformClient } from '..';\nimport { version } from '../version';\n\nexport const setSidepanelSearchClient = (\n client: DocSearchTransformClient\n): DocSearchTransformClient => {\n if (\n /docsearch-sidepanel.js \\(.*\\)/.test(\n client.transporter.algoliaAgent.value\n ) === false\n ) {\n client.addAlgoliaAgent('docsearch-sidepanel', version);\n }\n\n return client;\n};\n","import type { JSX } from 'react';\nimport React from 'react';\n\nimport type { Exchange } from '../AskAiScreen';\nimport {\n CloseIcon,\n ConversationHistoryIcon,\n EditIcon,\n ExpandIcon,\n FolderIcon,\n MoreVerticalIcon,\n NewConversationIcon,\n SparklesIcon,\n} from '../icons';\nimport { BackIcon } from '../icons/BackIcon';\nimport { Menu } from '../Menu';\nimport { useIsMobile } from '../useIsMobile';\n\nimport type { SidepanelState } from './types';\n\ntype BackButtonProps = {\n mobile?: boolean;\n onBack: () => void;\n disabled?: boolean;\n};\n\nconst BackButton = ({\n onBack,\n mobile = false,\n disabled = false,\n}: BackButtonProps): JSX.Element => {\n return (\n <button\n type=\"button\"\n className={`DocSearch-Action DocSearch-Sidepanel-Action-back${mobile ? ' mobile' : ''}`}\n title=\"Go back to previous screen\"\n aria-disabled={disabled}\n onClick={disabled ? undefined : onBack}\n >\n <BackIcon />\n </button>\n );\n};\n\nexport type HeaderTranslations = Partial<{\n /** The main title text shown on the header. */\n title: string;\n /** The title text shown on the conversation history screen. */\n conversationHistoryTitle: string;\n /** The text shown on the start a conversation button. */\n newConversationText: string;\n /** The text shown on the view conversation history button. */\n viewConversationHistoryText: string;\n}>;\n\ntype SidepanelHeaderProps = {\n sidepanelState: SidepanelState;\n exchanges: Exchange[];\n setSidepanelState: (state: SidepanelState) => void;\n onNewConversation: () => void;\n onToggleExpanded: () => void;\n onClose: () => void;\n translations?: HeaderTranslations;\n hasConversations: boolean;\n isStreaming: boolean;\n};\n\nexport const SidepanelHeader = React.memo(\n ({\n sidepanelState,\n exchanges,\n setSidepanelState,\n onNewConversation,\n onToggleExpanded,\n onClose,\n translations = {},\n hasConversations,\n isStreaming,\n }: SidepanelHeaderProps): JSX.Element => {\n const {\n title = 'Ask AI',\n conversationHistoryTitle = 'My conversation history',\n newConversationText = 'Start a new conversation',\n viewConversationHistoryText = 'Conversation history',\n } = translations;\n\n const isMobile = useIsMobile();\n\n const goToConversationHistory = (): void => {\n setSidepanelState('conversation-history');\n };\n\n const onBack = React.useCallback((): void => {\n if (exchanges.length > 0) {\n setSidepanelState('conversation');\n } else {\n setSidepanelState('new-conversation');\n }\n }, [exchanges, setSidepanelState]);\n\n const newConversationDisabled =\n sidepanelState === 'new-conversation' && exchanges.length < 1;\n\n let header = title;\n\n if (sidepanelState === 'conversation-history') {\n header = conversationHistoryTitle;\n }\n\n if (isMobile) {\n header = title;\n }\n\n return (\n <header className=\"DocSearch-Sidepanel-Header\">\n <div className=\"DocSearch-Sidepanel-Header--left\">\n <BackButton mobile={true} disabled={isStreaming} onBack={onBack} />\n\n {sidepanelState === 'conversation-history' && (\n <div className=\"DocSearch-Divider\" />\n )}\n\n <button\n type=\"button\"\n className=\"DocSearch-Action\"\n title={newConversationText}\n onClick={onNewConversation}\n >\n <EditIcon />\n </button>\n\n <div className=\"DocSearch-Divider\" />\n\n <button\n type=\"button\"\n className=\"DocSearch-Action\"\n title={viewConversationHistoryText}\n onClick={goToConversationHistory}\n >\n <FolderIcon />\n </button>\n </div>\n <div className=\"DocSearch-Sidepanel-Header--center\">\n <BackButton disabled={isStreaming} onBack={onBack} />\n <SparklesIcon className=\"DocSearch-Sidepanel-Header-TitleIcon\" />\n <h2 className=\"DocSearch-Sidepanel-Title\">{header}</h2>\n </div>\n <div className=\"DocSearch-Sidepanel-Header--right\">\n {sidepanelState !== 'conversation-history' &&\n (!newConversationDisabled || hasConversations) && (\n <Menu>\n <Menu.Trigger\n className=\"DocSearch-Action DocSearch-Sidepanel-Action-menu\"\n disabled={isStreaming}\n >\n <MoreVerticalIcon />\n </Menu.Trigger>\n <Menu.Content>\n {!newConversationDisabled && (\n <Menu.Item onClick={onNewConversation}>\n <NewConversationIcon />\n {newConversationText}\n </Menu.Item>\n )}\n {hasConversations && (\n <Menu.Item onClick={goToConversationHistory}>\n <ConversationHistoryIcon />\n {viewConversationHistoryText}\n </Menu.Item>\n )}\n </Menu.Content>\n </Menu>\n )}\n <button\n type=\"button\"\n className=\"DocSearch-Action DocSearch-Sidepanel-Action-expand\"\n title=\"Expand or collapse Sidepanel\"\n onClick={onToggleExpanded}\n >\n <ExpandIcon />\n </button>\n <button\n type=\"button\"\n className=\"DocSearch-Action DocSearch-Sidepanel-Action-close\"\n title=\"Close Sidepanel\"\n onClick={onClose}\n >\n <CloseIcon />\n </button>\n </div>\n </header>\n );\n }\n);\n","import { useLayoutEffect, useRef } from 'react';\n\nimport { useIsMobile } from '../useIsMobile';\n\nimport type { PanelSide, PanelVariant } from './types';\n\ntype UseManageSidepanelLayoutProps = {\n variant: PanelVariant;\n side: PanelSide;\n selectors: string;\n isOpen: boolean;\n expectedWidth: string;\n};\n\nexport function useManageSidepanelLayout({\n variant,\n selectors,\n isOpen,\n expectedWidth,\n side,\n}: UseManageSidepanelLayoutProps): void {\n const targetRef = useRef<HTMLElement | null>(null);\n const lastSelectorRef = useRef<string | null>(null);\n const isMobile = useIsMobile();\n\n useLayoutEffect(() => {\n if (variant === 'floating' || isMobile) return;\n\n if (lastSelectorRef.current !== selectors) {\n if (targetRef.current) {\n if (side === 'left') {\n targetRef.current.style.marginLeft = '';\n } else {\n targetRef.current.style.marginRight = '';\n }\n targetRef.current.style.transition = '';\n }\n\n const candidates = Array.from(document.querySelectorAll(selectors));\n const nextTarget: HTMLElement | null =\n (candidates[0] as HTMLElement) || document.body;\n targetRef.current = nextTarget;\n lastSelectorRef.current = selectors;\n\n if (targetRef.current) {\n targetRef.current.style.transition = `margin-${side} 280ms cubic-bezier(0.22, 1, 0.36, 1)`;\n }\n }\n\n const target = targetRef.current;\n if (!target) return;\n\n const offset = isOpen ? expectedWidth : '0px';\n\n if (side === 'left') {\n target.style.marginLeft = offset;\n } else {\n target.style.marginRight = offset;\n }\n }, [isOpen, expectedWidth, variant, selectors, side, isMobile]);\n\n useLayoutEffect(() => {\n return (): void => {\n if (targetRef.current) {\n if (side === 'left') {\n targetRef.current.style.marginLeft = '';\n } else {\n targetRef.current.style.marginRight = '';\n }\n targetRef.current.style.transition = '';\n }\n };\n }, [side]);\n}\n","import type { SidepanelShortcuts } from '@docsearch/core';\nimport { useEffect } from 'react';\n\ntype UseSidepanelKeyboardEventsProps = {\n onClose: () => void;\n onOpen: () => void;\n isOpen: boolean;\n keyboardShortcuts?: SidepanelShortcuts;\n};\n\nexport function useSidepanelKeyboardEvents({\n onClose,\n onOpen,\n isOpen,\n keyboardShortcuts,\n}: UseSidepanelKeyboardEventsProps): void {\n useEffect(() => {\n function onKeyDown(e: KeyboardEvent): void {\n if (isOpen && e.code === 'Escape') {\n onClose();\n return;\n }\n\n const cmdIEnabled = keyboardShortcuts?.['Ctrl/Cmd+I'] !== false;\n\n if (!cmdIEnabled) return;\n\n const isCmdI = e.key?.toLowerCase() === 'i' && (e.metaKey || e.ctrlKey);\n\n if (isCmdI) {\n e.preventDefault();\n\n if (isOpen) {\n onClose();\n } else {\n onOpen();\n }\n }\n }\n\n window.addEventListener('keydown', onKeyDown);\n\n return (): void => {\n window.removeEventListener('keydown', onKeyDown);\n };\n }, [isOpen, onClose, onOpen, keyboardShortcuts]);\n}\n","import React from 'react';\n\nconst BASE_WIDTH = 360;\nconst EXPANDED_WIDTH = 580;\n\ntype UseSidepanelWidthProps = {\n isExpanded: boolean;\n width?: number | string;\n expandedWidth?: number | string;\n};\n\nexport const useSidepanelWidth = ({\n isExpanded,\n width,\n expandedWidth,\n}: UseSidepanelWidthProps): string => {\n const baseWidth = React.useMemo(() => {\n return typeof width === 'number'\n ? `${width}px`\n : (width ?? `${BASE_WIDTH}px`);\n }, [width]);\n\n const resolvedExpandedWidth = React.useMemo(() => {\n return typeof expandedWidth === 'number'\n ? `${expandedWidth}px`\n : (expandedWidth ?? `${EXPANDED_WIDTH}px`);\n }, [expandedWidth]);\n\n const expectedWidth = isExpanded ? resolvedExpandedWidth : baseWidth;\n\n return expectedWidth;\n};\n","import type { SidepanelShortcuts, InitialAskAiMessage } from '@docsearch/core';\nimport React, { useCallback } from 'react';\nimport type { JSX } from 'react';\n\nimport { AlgoliaLogo, type AlgoliaLogoTranslations } from '../AlgoliaLogo';\nimport type {\n DocSearchSidepanelProps,\n SidepanelSearchParameters,\n} from '../Sidepanel';\nimport type { StoredAskAiState, SuggestedQuestionHit } from '../types';\nimport { useAskAi } from '../useAskAi';\nimport { useIsMobile } from '../useIsMobile';\nimport { useSearchClient } from '../useSearchClient';\nimport { useSuggestedQuestions } from '../useSuggestedQuestions';\nimport { EMPTY_TOOLS, buildDummyAskAiHit } from '../utils/ai';\n\nimport { ConversationHistoryScreen } from './ConversationHistoryScreen';\nimport type { ConversationScreenTranslations } from './ConversationScreen';\nimport { ConversationScreen } from './ConversationScreen';\nimport type { NewConversationScreenTranslations } from './NewConversationScreen';\nimport { NewConversationScreen } from './NewConversationScreen';\nimport { PromptForm, type PromptFormTranslations } from './PromptForm';\nimport { setSidepanelSearchClient } from './setSidepanelSearchClient';\nimport type { HeaderTranslations } from './SidepanelHeader';\nimport { SidepanelHeader } from './SidepanelHeader';\nimport type { PanelSide, PanelVariant, SidepanelState } from './types';\nimport { useManageSidepanelLayout } from './useManageSidepanelLayout';\nimport { useSidepanelKeyboardEvents } from './useSidepanelKeyboardEvents';\nimport { useSidepanelWidth } from './useSidepanelWidth';\n\n/**\n * Imperative handle exposed by the Sidepanel component for programmatic\n * control.\n */\nexport interface SidepanelRef {\n /** Opens the sidepanel. */\n open: () => void;\n /** Closes the sidepanel. */\n close: () => void;\n /** Returns true once the component is mounted and ready. */\n readonly isReady: boolean;\n /** Returns true if the sidepanel is currently open. */\n readonly isOpen: boolean;\n}\n\nexport type SidepanelTranslations = Partial<{\n /** Translation texts for the Sidepanel header. */\n header: HeaderTranslations;\n /** Translation texts for the prompt form. */\n promptForm: PromptFormTranslations;\n /** Translation texts for the conversation screen. */\n conversationScreen: ConversationScreenTranslations;\n /** Translation texts for the new conversation/starting screen. */\n newConversationScreen: NewConversationScreenTranslations;\n /** Translation text for the Algolia logo. */\n logo: AlgoliaLogoTranslations;\n}>;\n\nexport type SidepanelProps = Pick<\n DocSearchSidepanelProps,\n 'indices' | 'memory' | 'tools'\n> & {\n /**\n * Variant of the Sidepanel positioning.\n *\n * - `inline` pushes page content when opened\n * - `floating` is positioned above all other content on page.\n *\n * @default 'floating'\n */\n variant?: PanelVariant;\n /**\n * Side of the page which the panel will originate from.\n *\n * @default 'right'\n */\n side?: PanelSide;\n /**\n * The selector of the element to push when Sidepanel opens with `inline`\n * variant.\n *\n * @default `'#root, main, .app, body'`\n */\n pushSelector?: string;\n /**\n * Width of the Sidepanel (px or any CSS width).\n *\n * @default `360px`\n */\n width?: number | string;\n /**\n * Width when expanded (px or any CSS width).\n *\n * @default `580px`\n */\n expandedWidth?: number | string;\n /**\n * The container element where the panel should be portaled to.\n *\n * @default `document.body`\n */\n portalContainer?: DocumentFragment | Element | null;\n /**\n * Enables displaying suggested questions on new conversation screen.\n *\n * @default false\n */\n suggestedQuestions?: boolean;\n /** Translations specific to the Sidepanel panel. */\n translations?: SidepanelTranslations;\n /**\n * Configuration for keyboard shortcuts. Allows enabling/disabling specific\n * shortcuts.\n *\n * @default `{ 'Ctrl/Cmd+I': true }`\n */\n keyboardShortcuts?: SidepanelShortcuts;\n};\n\ntype Props = Omit<\n DocSearchSidepanelProps,\n 'button' | 'indices' | 'memory' | 'panel' | 'tools'\n> &\n SidepanelProps &\n SidepanelSearchParameters & {\n isOpen?: boolean;\n onOpen: () => void;\n onClose: () => void;\n initialMessage?: InitialAskAiMessage;\n };\n\nfunction SidepanelInner(\n {\n isOpen = false,\n onOpen,\n onClose,\n agentId,\n apiKey,\n appId,\n variant = 'floating',\n searchParameters,\n pushSelector,\n width,\n expandedWidth,\n suggestedQuestions: suggestedQuestionsEnabled = false,\n translations = {},\n keyboardShortcuts,\n side = 'right',\n initialMessage,\n tools = EMPTY_TOOLS,\n memory,\n indices,\n }: Props,\n ref: React.ForwardedRef<SidepanelRef>\n): JSX.Element {\n const [isExpanded, setIsExpanded] = React.useState(false);\n const [sidepanelState, setSidepanelState] =\n React.useState<SidepanelState>('new-conversation');\n const [stoppedStreaming, setStoppedStreaming] = React.useState(false);\n const sidepanelContainerRef = React.useRef<HTMLDivElement>(null);\n const promptInputRef = React.useRef<HTMLTextAreaElement>(null);\n const isMobile = useIsMobile();\n\n const expectedWidth = useSidepanelWidth({\n isExpanded,\n width,\n expandedWidth,\n });\n\n const selectors = React.useMemo(\n () => pushSelector ?? '#root, main, .app, body',\n [pushSelector]\n );\n\n const toggleIsExpanded = useCallback((): void => {\n setIsExpanded(!isExpanded);\n }, [isExpanded]);\n\n const searchClient = useSearchClient(appId, apiKey, setSidepanelSearchClient);\n\n const {\n chatId,\n status,\n sendMessage,\n stopAskAiStreaming,\n isStreaming,\n exchanges,\n conversations,\n messages,\n sendFeedback,\n askAiError,\n startNewConversation,\n restoreConversation,\n } = useAskAi({\n appId,\n agentId,\n apiKey,\n searchParameters,\n tools,\n memory,\n indices,\n });\n\n const suggestedQuestions = useSuggestedQuestions({\n agentId,\n suggestedQuestionsEnabled,\n searchClient,\n });\n\n const prevStatus = React.useRef(status);\n\n const handleSend = React.useCallback(\n (prompt: string): void => {\n setStoppedStreaming(false);\n\n sendMessage({ text: prompt });\n setSidepanelState('conversation');\n },\n [sendMessage]\n );\n\n const handleStartNewConversation = (): void => {\n startNewConversation();\n setSidepanelState('new-conversation');\n };\n\n const handleSelectQuestion = (question: SuggestedQuestionHit): void => {\n setStoppedStreaming(false);\n startNewConversation();\n sendMessage(\n { text: question.question },\n {\n body: {\n suggestedQuestionId: question.objectID,\n },\n }\n );\n setSidepanelState('conversation');\n };\n\n const handleStopStreaming = (): void => {\n setStoppedStreaming(true);\n stopAskAiStreaming();\n };\n\n const handleSelectConversation = React.useCallback(\n (conversation: StoredAskAiState): void => {\n if (conversation.messages) {\n restoreConversation(conversation.messages, conversation.chatId);\n } else if (conversation.query) {\n sendMessage({ text: conversation.query });\n }\n\n setSidepanelState('conversation');\n },\n [sendMessage, restoreConversation]\n );\n\n useManageSidepanelLayout({\n variant,\n expectedWidth,\n selectors,\n isOpen,\n side,\n });\n\n useSidepanelKeyboardEvents({\n onClose,\n onOpen,\n isOpen,\n keyboardShortcuts,\n });\n\n // Expose imperative handle for programmatic control\n React.useImperativeHandle(\n ref,\n () => ({\n open: onOpen,\n close: onClose,\n get isReady(): boolean {\n return true;\n },\n get isOpen(): boolean {\n return isOpen;\n },\n }),\n [onOpen, onClose, isOpen]\n );\n\n React.useEffect(() => {\n if (prevStatus.current === 'streaming' && status === 'ready') {\n if (stoppedStreaming && messages.at(-1)) {\n messages.at(-1)!.metadata = {\n stopped: true,\n };\n }\n\n for (const part of messages[0].parts) {\n if (part.type === 'text') {\n conversations.add(buildDummyAskAiHit(part.text, messages, chatId));\n }\n }\n }\n\n prevStatus.current = status;\n }, [conversations, status, messages, stoppedStreaming, chatId]);\n\n React.useEffect(() => {\n function setFullViewportHeight(): void {\n if (sidepanelContainerRef.current) {\n const vh = window.innerHeight * 0.01;\n sidepanelContainerRef.current.style.setProperty('--sp-vh', `${vh}px`);\n }\n }\n\n setFullViewportHeight();\n\n window.addEventListener('resize', setFullViewportHeight);\n\n return (): void => {\n window.removeEventListener('resize', setFullViewportHeight);\n };\n }, []);\n\n React.useEffect(() => {\n if (!initialMessage) return;\n\n let selectedConversation: StoredAskAiState | undefined;\n\n if (initialMessage.messageId) {\n selectedConversation = conversations.getConversation?.(\n initialMessage.messageId\n );\n }\n\n if (selectedConversation) {\n handleSelectConversation(selectedConversation);\n } else {\n startNewConversation();\n sendMessage(\n {\n text: initialMessage.query,\n },\n initialMessage.suggestedQuestionId\n ? {\n body: {\n suggestedQuestionId: initialMessage.suggestedQuestionId,\n },\n }\n : {}\n );\n setSidepanelState('conversation');\n }\n }, [\n initialMessage,\n sendMessage,\n conversations,\n handleSelectConversation,\n startNewConversation,\n ]);\n\n // Autofocus the prompt input when the sidepanel opens and blur it when\n // it closes. Disabled on mobile because focusing the textarea triggers the\n // virtual keyboard which disrupts the layout — this is a known issue that\n // has not been resolved yet.\n React.useEffect(() => {\n if (isOpen && !isMobile) {\n promptInputRef.current?.focus();\n }\n\n if (!isOpen) {\n promptInputRef.current?.blur();\n }\n }, [isOpen, isMobile]);\n\n return (\n <div\n className={`DocSearch-Sidepanel-Container ${variant} side-${side}${isOpen ? ' is-open' : ''}${isExpanded ? ' is-expanded' : ''}`}\n style={\n {\n '--sp-width': expectedWidth,\n } as React.CSSProperties\n }\n role=\"dialog\"\n tabIndex={-1}\n ref={sidepanelContainerRef}\n >\n <aside\n id=\"docsearch-sidepanel\"\n className={`DocSearch-Sidepanel ${sidepanelState}`}\n >\n <SidepanelHeader\n sidepanelState={sidepanelState}\n exchanges={exchanges}\n setSidepanelState={setSidepanelState}\n hasConversations={conversations.getAll().length > 0}\n isStreaming={isStreaming}\n onNewConversation={handleStartNewConversation}\n onToggleExpanded={toggleIsExpanded}\n onClose={onClose}\n />\n <div className=\"DocSearch-Sidepanel-Content\">\n {sidepanelState === 'new-conversation' && (\n <NewConversationScreen\n suggestedQuestions={suggestedQuestions}\n translations={translations.newConversationScreen}\n onSelectQuestion={handleSelectQuestion}\n />\n )}\n {sidepanelState === 'conversation' && (\n <ConversationScreen\n exchanges={exchanges}\n status={status}\n conversations={conversations}\n handleFeedback={sendFeedback}\n translations={translations.conversationScreen}\n streamError={askAiError}\n memoryEnabled={memory?.enabled ?? false}\n tools={tools}\n onSelectPromptSuggestion={handleSend}\n />\n )}\n {sidepanelState === 'conversation-history' && (\n <ConversationHistoryScreen\n conversations={conversations}\n selectConversation={handleSelectConversation}\n />\n )}\n </div>\n <PromptForm\n ref={promptInputRef}\n exchanges={exchanges}\n isStreaming={isStreaming}\n translations={translations.promptForm}\n onSend={handleSend}\n onStopStreaming={handleStopStreaming}\n />\n <footer className=\"DocSearch-Sidepanel-Footer\">\n <span className=\"DocSearch-Logo DocSearch-Sidepanel--powered-by\">\n <AlgoliaLogo translations={translations.logo} />\n </span>\n </footer>\n </aside>\n </div>\n );\n}\n\nexport const Sidepanel = React.forwardRef(SidepanelInner);\n","import type { SidepanelShortcuts } from '@docsearch/core';\nimport React, { useEffect, useState } from 'react';\nimport type { JSX } from 'react';\n\nimport { SparklesIcon } from '../icons';\nimport { ACTION_KEY_APPLE, ACTION_KEY_DEFAULT, isAppleDevice } from '../utils';\n\nexport type SidepanelButtonTranslations = Partial<{\n /**\n * Text to be displayed when button has variant: `inline`.\n *\n * @default 'Ask AI'\n */\n buttonText: string;\n /**\n * Aria label text for the button.\n *\n * @default 'Ask AI'\n */\n buttonAriaLabel: string;\n}>;\n\nexport type ButtonVariant = 'floating' | 'inline';\n\nexport type SidepanelButtonProps = {\n /**\n * Variant of the button positioning and styling.\n *\n * - `inline` displays the button inline where rendered, with extra text\n * - `floating` displays the button floating in bottom right of screen with just\n * icon.\n *\n * @default 'floating'\n */\n variant?: ButtonVariant;\n /** Translations specific to the Sidepanel button. */\n translations?: SidepanelButtonTranslations;\n /**\n * Configuration for keyboard shortcuts. Allows enabling/disabling specific\n * shortcuts.\n *\n * @default `{ 'Ctrl/Cmd+I': true }`\n */\n keyboardShortcuts?: SidepanelShortcuts;\n};\n\ntype Props = React.ComponentProps<'button'> & SidepanelButtonProps;\n\nexport const SidepanelButton = ({\n variant = 'floating',\n keyboardShortcuts,\n translations = {},\n ...props\n}: Props): JSX.Element => {\n const { buttonText = 'Ask AI', buttonAriaLabel = 'Ask AI' } = translations;\n const [key, setKey] = useState<\n typeof ACTION_KEY_APPLE | typeof ACTION_KEY_DEFAULT | null\n >(null);\n\n useEffect(() => {\n if (typeof navigator !== 'undefined') {\n isAppleDevice() ? setKey(ACTION_KEY_APPLE) : setKey(ACTION_KEY_DEFAULT);\n }\n }, []);\n\n const actionKeyAltText = key === ACTION_KEY_DEFAULT ? 'Control' : 'Meta';\n const isCtrlCmdIEnabled = keyboardShortcuts?.['Ctrl/Cmd+I'] !== false;\n const shortcut = `${actionKeyAltText}+i`;\n\n return (\n <button\n className={`DocSearch-SidepanelButton ${variant}`}\n type=\"button\"\n aria-label={\n isCtrlCmdIEnabled ? `${buttonAriaLabel} (${shortcut})` : buttonAriaLabel\n }\n aria-keyshortcuts={isCtrlCmdIEnabled ? shortcut : undefined}\n {...(variant === 'floating' ? { tabIndex: -1 } : {})}\n {...props}\n >\n <SparklesIcon />\n {variant !== 'floating' && buttonText}\n </button>\n );\n};\n","import { DocSearch, useDocSearch } from '@docsearch/core';\nimport type {\n DocSearchCallbacks,\n DocSearchRef,\n DocSearchTheme,\n SidepanelShortcuts,\n} from '@docsearch/core';\nimport type { JSX } from 'react';\nimport React from 'react';\nimport { createPortal } from 'react-dom';\n\nimport type {\n AgentStudioIndices,\n AgentStudioSearchParameters,\n Memory,\n} from './DocSearchAI';\nimport type {\n SidepanelButtonProps,\n SidepanelProps as SidepanelPanelProps,\n} from './Sidepanel/index';\nimport { SidepanelButton, Sidepanel } from './Sidepanel/index';\nimport type { ToolCalls } from './types/AskiAi';\n\nexport type { DocSearchRef, DocSearchCallbacks } from '@docsearch/core';\n\nexport type SidepanelSearchParameters = {\n /**\n * The search parameters to use for the ask AI feature. Keyed by the index\n * name.\n *\n * @example\n * {\n * \"INDEX_NAME\": { distinct: false }\n * }\n */\n searchParameters?: AgentStudioSearchParameters;\n};\n\nexport type DocSearchSidepanelProps = DocSearchCallbacks & {\n /** The Agent Studio agent ID to use for Ask AI. */\n agentId: string;\n /** Search only API key. */\n apiKey: string;\n /** Algolia application ID that hosts the Agent Studio agent. */\n appId: string;\n /**\n * Configuration for keyboard shortcuts. Allows enabling/disabling specific\n * shortcuts.\n *\n * @default `{ 'Ctrl/Cmd+I': true }`\n */\n keyboardShortcuts?: SidepanelShortcuts;\n /**\n * Theme overrides applied to the Sidepanel button and panel.\n *\n * @default 'light'\n */\n theme?: DocSearchTheme;\n /** Props specific to the Sidepanel button. */\n button?: Omit<SidepanelButtonProps, 'keyboardShortcuts'>;\n /** Props specific to the Sidepanel panel. */\n panel?: Omit<SidepanelPanelProps, 'keyboardShortcuts'>;\n /**\n * Use custom tools driven by Agent Studio.\n *\n * For best performance, memoize this object with `useMemo` or define it\n * outside the component. Inline object literals will be recreated every\n * render but will not affect correctness.\n */\n tools?: ToolCalls;\n /**\n * Configuration for the Agent Studio memory feature.\n *\n * @example\n * { enabled: true, userToken: '{{SERVER_GENERATED_JWT_TOKEN}}' }\n *\n * @see https://www.algolia.com/doc/guides/algolia-ai/agent-studio/how-to/memory/overview\n */\n memory?: Memory;\n /** List of dynamic indices for the Agent Studio search tool to use. */\n indices?: AgentStudioIndices[];\n};\n\ntype SidepanelProps = DocSearchSidepanelProps & SidepanelSearchParameters;\n\nfunction DocSearchSidepanelComponent(\n {\n keyboardShortcuts,\n theme,\n onReady,\n onOpen,\n onClose,\n onSidepanelOpen,\n onSidepanelClose,\n ...props\n }: SidepanelProps,\n ref: React.ForwardedRef<DocSearchRef>\n): JSX.Element {\n return (\n <DocSearch\n appId={props.appId}\n apiKey={props.apiKey}\n keyboardShortcuts={keyboardShortcuts}\n theme={theme}\n ref={ref}\n onReady={onReady}\n onOpen={onOpen}\n onClose={onClose}\n onSidepanelOpen={onSidepanelOpen}\n onSidepanelClose={onSidepanelClose}\n >\n <DocSearchSidepanelComp {...props} />\n </DocSearch>\n );\n}\n\nexport const DocSearchSidepanel = React.forwardRef(DocSearchSidepanelComponent);\n\nfunction DocSearchSidepanelComp({\n button: buttonProps = {},\n panel: { portalContainer, ...panelProps } = {},\n ...rootProps\n}: DocSearchSidepanelProps): JSX.Element {\n const {\n docsearchState,\n setDocsearchState,\n keyboardShortcuts,\n registerView,\n initialAskAiMessage,\n appId,\n apiKey,\n } = useDocSearch();\n\n if (!appId || !apiKey) {\n throw new Error(\n '`Sidepanel` requires `appId` and `apiKey` props or values configured on the `DocSearch` provider.'\n );\n }\n\n const toggleSidepanelState = React.useCallback(() => {\n setDocsearchState(docsearchState === 'sidepanel' ? 'ready' : 'sidepanel');\n }, [docsearchState, setDocsearchState]);\n\n const handleClose = (): void => {\n setDocsearchState('ready');\n };\n\n const handleOpen = (): void => {\n setDocsearchState('sidepanel');\n };\n\n const containerElement = React.useMemo(\n () => portalContainer ?? document.body,\n [portalContainer]\n );\n\n React.useEffect(() => {\n registerView('sidepanel');\n }, [registerView]);\n\n const ButtonComp = React.useMemo(\n () => (\n <SidepanelButton\n keyboardShortcuts={keyboardShortcuts}\n onClick={toggleSidepanelState}\n {...buttonProps}\n />\n ),\n [keyboardShortcuts, toggleSidepanelState, buttonProps]\n );\n\n return (\n <>\n {buttonProps.variant === 'inline'\n ? ButtonComp\n : createPortal(ButtonComp, containerElement)}\n {createPortal(\n <Sidepanel\n initialMessage={initialAskAiMessage}\n isOpen={docsearchState === 'sidepanel'}\n onClose={handleClose}\n onOpen={handleOpen}\n {...rootProps}\n {...panelProps}\n keyboardShortcuts={keyboardShortcuts}\n />,\n containerElement\n )}\n </>\n );\n}\n\nexport * from './Sidepanel/index';\n"],"mappings":"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"}
|