@redocly/theme
Version:
Shared UI components lib
173 lines (168 loc) • 8.47 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SearchAiResponse = SearchAiResponse;
const react_1 = __importDefault(require("react"));
const styled_components_1 = __importDefault(require("styled-components"));
const Spinner_1 = require("../../icons/Spinner/Spinner");
const CheckmarkFilledIcon_1 = require("../../icons/CheckmarkFilledIcon/CheckmarkFilledIcon");
const DocumentIcon_1 = require("../../icons/DocumentIcon/DocumentIcon");
const Tag_1 = require("../../components/Tag/Tag");
const Link_1 = require("../../components/Link/Link");
const hooks_1 = require("../../core/hooks");
const Markdown_1 = require("../../components/Markdown/Markdown");
const Typography_1 = require("../../components/Typography/Typography");
const Admonition_1 = require("../../components/Admonition/Admonition");
const ErrorFilledIcon_1 = require("../../icons/ErrorFilledIcon/ErrorFilledIcon");
const constants_1 = require("../../core/constants");
const ChatIcon_1 = require("../../icons/ChatIcon/ChatIcon");
function SearchAiResponse(props) {
var _a;
const { useMarkdownText } = (0, hooks_1.useThemeHooks)();
const { question, response, isGeneratingResponse, resources, error, onSuggestionClick } = props;
const { search } = (0, hooks_1.useThemeConfig)();
const { useTranslate } = (0, hooks_1.useThemeHooks)();
const { translate } = useTranslate();
const markdownResponse = useMarkdownText(response || '');
let responseContainer = null;
const suggestions = (_a = search === null || search === void 0 ? void 0 : search.ai) === null || _a === void 0 ? void 0 : _a.suggestions;
const hasPendingOrReceivedResponse = response || isGeneratingResponse || error;
if (hasPendingOrReceivedResponse) {
let icon;
switch (true) {
case error !== null:
icon = react_1.default.createElement(ErrorFilledIcon_1.ErrorFilledIcon, { size: "20px", color: "--error-bubble-content-color" });
break;
case isGeneratingResponse:
icon = react_1.default.createElement(Spinner_1.Spinner, { size: "20px", color: "--search-ai-spinner-icon-color" });
break;
case Boolean(response):
icon = react_1.default.createElement(CheckmarkFilledIcon_1.CheckmarkFilledIcon, { size: "20px", color: "--search-ai-checkmark-icon-color" });
break;
}
responseContainer = (react_1.default.createElement(react_1.default.Fragment, null,
react_1.default.createElement(ResponseHeader, null,
icon,
react_1.default.createElement(Question, null, question)),
react_1.default.createElement(ResponseBody, null,
response && react_1.default.createElement(ResponseText, Object.assign({ children: markdownResponse, as: "div" }, props)),
!response && isGeneratingResponse && (react_1.default.createElement(ThinkingResponseText, { "data-translation-key": "search.ai.thinkingText" }, translate('search.ai.thinkingText', 'Thinking...'))),
error && (react_1.default.createElement(Admonition_1.Admonition, { type: "danger", name: translate(constants_1.AI_SEARCH_ERROR_CONFIG[error].headerKey, constants_1.AI_SEARCH_ERROR_CONFIG[error].headerDefault) }, translate(constants_1.AI_SEARCH_ERROR_CONFIG[error].messageKey, constants_1.AI_SEARCH_ERROR_CONFIG[error].messageDefault))),
resources.length && !isGeneratingResponse ? (react_1.default.createElement(Resources, null,
react_1.default.createElement(ResourcesTitle, { "data-translation-key": "search.ai.resourcesFound" },
resources.length,
" ",
translate('search.ai.resourcesFound', 'resources found')),
react_1.default.createElement(ResourceTags, null, resources.map((resource, idx) => (react_1.default.createElement(Link_1.Link, { key: idx, to: resource.url, target: "_blank" },
react_1.default.createElement(ResourceTag, { borderless: true, icon: react_1.default.createElement(DocumentIcon_1.DocumentIcon, { color: "--search-ai-resource-tag-icon-color" }) }, resource.title))))))) : null)));
}
return (react_1.default.createElement(ResponseWrapper, { "data-component-name": "Search/SearchAiResponse" },
!question && (react_1.default.createElement(react_1.default.Fragment, null, (suggestions === null || suggestions === void 0 ? void 0 : suggestions.length) && (react_1.default.createElement(SuggestionsWrapper, null,
react_1.default.createElement(SuggestionsTitle, null, translate('search.ai.suggestionsTitle', 'Suggestions')),
suggestions.map((suggestion, idx) => (react_1.default.createElement(SuggestionItem, { key: idx.toString(), onClick: () => {
onSuggestionClick(suggestion);
} },
react_1.default.createElement(ChatIcon_1.ChatIcon, { color: "--color-blueberry-6" }),
react_1.default.createElement(Typography_1.Typography, { color: "--search-ai-suggestions-text-color" }, suggestion)))))))),
responseContainer));
}
const ResponseWrapper = styled_components_1.default.div `
display: flex;
flex-direction: column;
flex: 2;
flex-grow: 2;
overflow-y: scroll;
overscroll-behavior: contain;
padding: var(--search-ai-response-padding);
gap: var(--search-ai-response-gap);
`;
const ResponseHeader = styled_components_1.default.div `
display: flex;
flex-direction: row;
gap: var(--search-ai-response-header-gap);
align-items: center;
`;
const Question = styled_components_1.default.div `
font-size: var(--search-ai-question-font-size);
font-weight: var(--search-ai-question-font-weight);
line-height: var(--search-ai-question-line-height);
color: var(--search-ai-question-text-color);
`;
const ResponseBody = styled_components_1.default.div `
display: flex;
flex-direction: column;
gap: var(--search-ai-response-body-gap);
padding: var(--search-ai-response-body-padding);
`;
const ResponseText = (0, styled_components_1.default)(Markdown_1.Markdown) `
color: var(--search-ai-response-text-color);
font-size: var(--search-ai-response-text-font-size);
line-height: var(--search-ai-response-text-line-height);
font-family: inherit;
white-space: break-spaces;
`;
const ThinkingResponseText = styled_components_1.default.pre `
color: var(--search-ai-response-text-color);
font-size: var(--search-ai-response-text-font-size);
line-height: var(--search-ai-response-text-line-height);
font-family: inherit;
white-space: break-spaces;
margin: var(--md-pre-margin) 0;
animation: fadeIn 2s ease-in-out infinite;
@keyframes fadeIn {
0% {
opacity: 1;
}
50% {
opacity: 0.3;
}
100% {
opacity: 1;
}
}
`;
const Resources = styled_components_1.default.div `
gap: var(--search-ai-resources-gap);
display: flex;
flex-direction: column;
`;
const ResourcesTitle = styled_components_1.default.div `
font-weight: var(--search-ai-resources-title-font-weight);
font-size: var(--search-ai-resources-title-font-size);
line-height: var(--search-ai-resources-title-line-height);
`;
const ResourceTags = styled_components_1.default.div `
display: flex;
flex-wrap: wrap;
gap: var(--search-ai-resource-tags-gap);
`;
const ResourceTag = (0, styled_components_1.default)(Tag_1.Tag).attrs({
className: 'tag-resource',
}) `
.tag-default {
--tag-color: --search-ai-resource-tag-text-color;
}
`;
const SuggestionsWrapper = styled_components_1.default.div `
display: flex;
flex-direction: column;
justify-content: flex-start;
gap: var(--spacing-sm);
margin-left: var(--spacing-xs);
`;
const SuggestionsTitle = (0, styled_components_1.default)(Typography_1.Typography) `
font-size: var(--search-ai-suggestions-title-font-size);
line-height: var(--search-ai-suggestions-title-line-height);
font-weight: var(--search-ai-suggestions-title-font-weight);
color: var(--search-ai-suggestions-title-text-color);
`;
const SuggestionItem = styled_components_1.default.div `
cursor: pointer;
display: flex;
align-items: center;
justify-content: flex-start;
gap: var(--spacing-xs);
`;
//# sourceMappingURL=SearchAiResponse.js.map