@redocly/theme 0.50.0 → 0.50.1
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/lib/components/Search/SearchAiResponse.d.ts +1 -0
- package/lib/components/Search/SearchAiResponse.js +35 -14
- package/lib/components/Search/SearchDialog.js +5 -2
- package/lib/core/hooks/use-color-switcher.d.ts +1 -1
- package/lib/core/hooks/use-color-switcher.js +10 -7
- package/lib/core/types/api-functions.d.ts +5 -0
- package/lib/core/types/api-functions.js +3 -0
- package/lib/core/types/hooks.d.ts +2 -0
- package/lib/core/types/index.d.ts +1 -0
- package/lib/core/types/index.js +1 -0
- package/lib/core/types/l10n.d.ts +1 -1
- package/lib/icons/ErrorFilledIcon/ErrorFilledIcon.d.ts +9 -0
- package/lib/icons/ErrorFilledIcon/ErrorFilledIcon.js +22 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/package.json +1 -1
- package/src/components/Search/SearchAiResponse.tsx +69 -37
- package/src/components/Search/SearchDialog.tsx +5 -1
- package/src/core/hooks/use-color-switcher.ts +12 -7
- package/src/core/types/api-functions.ts +5 -0
- package/src/core/types/hooks.ts +2 -0
- package/src/core/types/index.ts +1 -0
- package/src/core/types/l10n.ts +2 -0
- package/src/icons/ErrorFilledIcon/ErrorFilledIcon.tsx +33 -0
- package/src/index.ts +1 -0
|
@@ -13,25 +13,46 @@ const Tag_1 = require("../../components/Tag/Tag");
|
|
|
13
13
|
const Link_1 = require("../../components/Link/Link");
|
|
14
14
|
const hooks_1 = require("../../core/hooks");
|
|
15
15
|
const Markdown_1 = require("../../components/Markdown/Markdown");
|
|
16
|
+
const Admonition_1 = require("../../components/Admonition/Admonition");
|
|
17
|
+
const ErrorFilledIcon_1 = require("../../icons/ErrorFilledIcon/ErrorFilledIcon");
|
|
16
18
|
function SearchAiResponse(props) {
|
|
17
19
|
const { useMarkdownText } = (0, hooks_1.useThemeHooks)();
|
|
18
|
-
const { question, response, isGeneratingResponse, resources } = props;
|
|
20
|
+
const { question, response, isGeneratingResponse, resources, error } = props;
|
|
19
21
|
const { useTranslate } = (0, hooks_1.useThemeHooks)();
|
|
20
22
|
const { translate } = useTranslate();
|
|
21
23
|
const markdownResponse = useMarkdownText(response || '');
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
24
|
+
let responseContainer = null;
|
|
25
|
+
const hasPendingOrReceivedResponse = response || isGeneratingResponse || error;
|
|
26
|
+
if (hasPendingOrReceivedResponse) {
|
|
27
|
+
let icon;
|
|
28
|
+
switch (true) {
|
|
29
|
+
case error !== null:
|
|
30
|
+
icon = react_1.default.createElement(ErrorFilledIcon_1.ErrorFilledIcon, { size: "20px", color: "--error-bubble-content-color" });
|
|
31
|
+
break;
|
|
32
|
+
case isGeneratingResponse:
|
|
33
|
+
icon = react_1.default.createElement(Spinner_1.Spinner, { size: "20px", color: "--search-ai-spinner-icon-color" });
|
|
34
|
+
break;
|
|
35
|
+
case Boolean(response):
|
|
36
|
+
icon = react_1.default.createElement(CheckmarkFilledIcon_1.CheckmarkFilledIcon, { size: "20px", color: "--search-ai-checkmark-icon-color" });
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
responseContainer = (react_1.default.createElement(react_1.default.Fragment, null,
|
|
40
|
+
react_1.default.createElement(ResponseHeader, null,
|
|
41
|
+
icon,
|
|
42
|
+
react_1.default.createElement(Question, null, question)),
|
|
43
|
+
react_1.default.createElement(ResponseBody, null,
|
|
44
|
+
response && react_1.default.createElement(ResponseText, Object.assign({ children: markdownResponse, as: "div" }, props)),
|
|
45
|
+
!response && isGeneratingResponse && (react_1.default.createElement(ThinkingResponseText, { "data-translation-key": "search.ai.thinkingText" }, translate('search.ai.thinkingText', 'Thinking...'))),
|
|
46
|
+
error && (react_1.default.createElement(Admonition_1.Admonition, { type: "danger", name: translate('search.ai.error.header', 'Oops! Something went wrong.') }, translate('search.ai.error.description', 'We encountered an issue while processing your search. Please try again later or refine your query. If the problem persists, feel free to contact support.'))),
|
|
47
|
+
resources.length && !isGeneratingResponse ? (react_1.default.createElement(Resources, null,
|
|
48
|
+
react_1.default.createElement(ResourcesTitle, { "data-translation-key": "search.ai.resourcesFound" },
|
|
49
|
+
resources.length,
|
|
50
|
+
" ",
|
|
51
|
+
translate('search.ai.resourcesFound', 'resources found')),
|
|
52
|
+
react_1.default.createElement(ResourceTags, null, resources.map((resource, idx) => (react_1.default.createElement(Link_1.Link, { key: idx, to: resource.url, target: "_blank" },
|
|
53
|
+
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)));
|
|
54
|
+
}
|
|
55
|
+
return (react_1.default.createElement(ResponseWrapper, { "data-component-name": "Search/SearchAiResponse" }, responseContainer));
|
|
35
56
|
}
|
|
36
57
|
const ResponseWrapper = styled_components_1.default.div `
|
|
37
58
|
display: flex;
|
|
@@ -116,7 +116,10 @@ function SearchDialog({ onClose, className }) {
|
|
|
116
116
|
react_1.default.createElement(CloseIcon_1.CloseIcon, { onClick: () => setProduct(undefined), color: "--icon-color-additional" })))),
|
|
117
117
|
react_1.default.createElement(SearchInput_1.SearchInput, { value: query, onChange: setQuery, placeholder: mode === 'search'
|
|
118
118
|
? translate('search.label', 'Search docs...')
|
|
119
|
-
: translate('search.ai.label', 'Ask AI assistant'), isLoading: isSearchLoading, showReturnButton: mode === 'ai-dialog', onReturn: () =>
|
|
119
|
+
: translate('search.ai.label', 'Ask AI assistant'), isLoading: isSearchLoading, showReturnButton: mode === 'ai-dialog', onReturn: () => {
|
|
120
|
+
setMode('search');
|
|
121
|
+
aiSearch.clearAiSearchState();
|
|
122
|
+
}, onSubmit: mode === 'ai-dialog'
|
|
120
123
|
? () => {
|
|
121
124
|
setQuery('');
|
|
122
125
|
aiSearch.askQuestion(query);
|
|
@@ -147,7 +150,7 @@ function SearchDialog({ onClose, className }) {
|
|
|
147
150
|
react_1.default.createElement(SearchRecent_1.SearchRecent, { onSelect: setQuery }),
|
|
148
151
|
react_1.default.createElement(SearchSuggestedPages_1.SearchSuggestedPages, null)))),
|
|
149
152
|
advancedSearch && mode === 'search' && isFilterOpen && (react_1.default.createElement(SearchDialogBodyFilterView, null,
|
|
150
|
-
react_1.default.createElement(SearchFilter_1.SearchFilter, { facets: facets, filter: filter, query: query, quickFilterFields: [groupField], onFilterChange: onFilterChange, onFilterReset: onFilterReset, onFacetReset: onFacetReset }))))) : (react_1.default.createElement(SearchAiResponse_1.SearchAiResponse, { question: aiSearch.question, isGeneratingResponse: aiSearch.isGeneratingResponse, response: aiSearch.response, resources: aiSearch.resources }))),
|
|
153
|
+
react_1.default.createElement(SearchFilter_1.SearchFilter, { facets: facets, filter: filter, query: query, quickFilterFields: [groupField], onFilterChange: onFilterChange, onFilterReset: onFilterReset, onFacetReset: onFacetReset }))))) : (react_1.default.createElement(SearchAiResponse_1.SearchAiResponse, { question: aiSearch.question, isGeneratingResponse: aiSearch.isGeneratingResponse, response: aiSearch.response, resources: aiSearch.resources, error: aiSearch.error }))),
|
|
151
154
|
react_1.default.createElement(SearchDialogFooter, null, mode === 'ai-dialog' ? (react_1.default.createElement(AiDisclaimer, null, translate('search.ai.disclaimer', 'AI search might provide incomplete or incorrect results. Verify important information.'))) : (react_1.default.createElement(react_1.default.Fragment, null,
|
|
152
155
|
react_1.default.createElement(SearchShortcuts, null,
|
|
153
156
|
react_1.default.createElement(SearchShortcut_1.SearchShortcut, { "data-translation-key": "search.keys.navigate", combination: "Tab", text: translate('search.keys.navigate', 'to navigate') }),
|
|
@@ -15,17 +15,20 @@ const useColorSwitcher = () => {
|
|
|
15
15
|
const activeMode = Array.from(document.documentElement.classList).find((c) => modes.includes(c));
|
|
16
16
|
setActiveColorMode(activeMode || defaultColor);
|
|
17
17
|
};
|
|
18
|
-
const switchColorMode = () => {
|
|
18
|
+
const switchColorMode = (mode) => {
|
|
19
|
+
if (mode && !modes.includes(mode)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
19
22
|
const activeIndex = modes.indexOf(activeColorMode);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
// If specific mode is provided, use it, otherwise cycle through modes
|
|
24
|
+
const newMode = mode || (activeIndex < modes.length - 1 ? modes[activeIndex + 1] : modes[0]);
|
|
25
|
+
localStorage.setItem('colorSchema', newMode);
|
|
26
|
+
document.documentElement.className = `${newMode} notransition`;
|
|
23
27
|
window.requestAnimationFrame(() => {
|
|
24
28
|
document.documentElement.classList.remove('notransition');
|
|
25
29
|
});
|
|
26
|
-
telemetry.send('color_mode_switched', { from: activeColorMode, to:
|
|
27
|
-
setActiveColorMode(
|
|
28
|
-
return mode;
|
|
30
|
+
telemetry.send('color_mode_switched', { from: activeColorMode, to: newMode });
|
|
31
|
+
setActiveColorMode(newMode);
|
|
29
32
|
};
|
|
30
33
|
return {
|
|
31
34
|
isSwitcherHidden: colorMode === null || colorMode === void 0 ? void 0 : colorMode.hide,
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { ApiFunctionsRequest as Request } from '@redocly/config';
|
|
2
|
+
export type { ApiFunctionsResponse as Response } from '@redocly/config';
|
|
3
|
+
export type { ApiFunctionsContext as Context } from '@redocly/config';
|
|
4
|
+
export type { PropsContext } from '@redocly/config';
|
|
5
|
+
export type { PageStaticData as PropsData } from '@redocly/config';
|
package/lib/core/types/index.js
CHANGED
|
@@ -26,4 +26,5 @@ __exportStar(require("../../core/types/select"), exports);
|
|
|
26
26
|
__exportStar(require("../../core/types/sidebar"), exports);
|
|
27
27
|
__exportStar(require("../../core/types/filter"), exports);
|
|
28
28
|
__exportStar(require("../../core/types/user-menu"), exports);
|
|
29
|
+
__exportStar(require("../../core/types/api-functions"), exports);
|
|
29
30
|
//# sourceMappingURL=index.js.map
|
package/lib/core/types/l10n.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TOptions } from 'i18next';
|
|
2
|
-
export type TranslationKey = 'dev.newApp' | 'dev.newApp.text' | 'dev.sidebar.header' | 'dev.sidebar.footer.text' | 'dev.create.app.dialog.appName.placeholder' | 'dev.create.app.dialog.appName.error' | 'dev.create.app.dialog.selectAPIs' | 'dev.create.app.dialog.description' | 'dev.create.app.dialog.description.placeholder' | 'dev.create.app.dialog.create' | 'dev.create.app.dialog.cancel' | 'dev.main.tab.appKeys' | 'dev.main.tab.logs' | 'dev.app.description.title' | 'dev.edit.description.dialog.title' | 'dev.edit.description.dialog.save' | 'dev.edit.description.dialog.cancel' | 'dev.edit.apis.dialog.selectedAPIs' | 'dev.app.key.create' | 'dev.create.key.dialog.title' | 'dev.create.key.dialog.create' | 'dev.create.key.dialog.cancel' | 'dev.app.edit' | 'dev.app.delete' | 'dev.edit.app.dialog.title' | 'dev.edit.app.dialog.save' | 'dev.edit.app.dialog.cancel' | 'dev.delete.app.dialog.title' | 'dev.delete.app.dialog.confirmation' | 'dev.delete.app.dialog.delete' | 'dev.delete.app.dialog.cancel' | 'dev.app.key.roll' | 'dev.roll.key.dialog.title' | 'dev.roll.key.dialog.apiKey' | 'dev.roll.key.dialog.expires' | 'dev.roll.key.dialog.confirmation' | 'dev.roll.key.dialog.cancel' | 'dev.roll.key.dialog.roll' | 'dev.update.key.dialog.title' | 'dev.update.key.dialog.update' | 'dev.update.key.dialog.cancel' | 'dev.app.key.api.name' | 'dev.app.key.api.status' | 'dev.app.key.api.edit' | 'dev.edit.apis.dialog.title' | 'dev.edit.apis.dialog.apiKey' | 'dev.edit.apis.dialog.save' | 'dev.edit.apis.dialog.cancel' | 'dev.select.placeholder' | 'dev.app.overview.status.pending' | 'dev.app.overview.status.approved' | 'dev.app.overview.status.revoked' | 'dev.app.overview.status' | 'dev.app.overview.non-production' | 'dev.app.overview.production' | 'dev.app.overview.clientId' | 'dev.app.overview.apiKey' | 'dev.app.key.revoke' | 'dev.revoke.key.dialog.title' | 'dev.revoke.key.dialog.apiKey' | 'dev.revoke.key.dialog.expires' | 'dev.revoke.key.dialog.confirmation' | 'dev.revoke.key.dialog.revoke' | 'dev.revoke.key.dialog.cancel' | 'dev.app.overview.expires' | 'dev.app.overview.created' | 'dev.app.overview.visibilityToggle.hide' | 'dev.app.overview.visibilityToggle.show' | 'search.loading' | 'search.noResults.title' | 'search.keys.navigate' | 'search.keys.select' | 'search.keys.exit' | 'search.label' | 'search.cancel' | 'search.recent' | 'search.navbar.label' | 'search.suggested' | 'search.showMore' | 'search.filter.title' | 'search.filter.reset' | 'search.filter.field.reset' | 'search.ai.thinkingText' | 'search.ai.resourcesFound' | 'search.ai.button' | 'search.ai.label' | 'search.ai.disclaimer' | 'toc.header' | 'footer.copyrightText' | 'page.homeButton' | 'page.forbidden.title' | 'page.notFound.title' | 'page.notFound.description' | 'page.lastUpdated.timeago' | 'page.lastUpdated.on' | 'catalog.filters.placeholder' | 'catalog.filters.title' | 'catalog.filters.clearAll' | 'catalog.filters.select.addFilter' | 'catalog.filters.select.all' | 'catalog.filters.done' | 'sidebar.menu.backLabel' | 'sidebar.menu.backToLabel' | 'sidebar.actions.show' | 'sidebar.actions.hide' | 'sidebar.actions.changeLayout' | 'versionPicker.label' | 'versionPicker.unversioned' | 'codeSnippet.copy.buttonText' | 'codeSnippet.copy.tooltipText' | 'codeSnippet.copy.toasterText' | 'markdown.editPage.text' | 'feedback.settings.comment.submitText' | 'feedback.settings.comment.label' | 'feedback.settings.comment.send' | 'feedback.settings.comment.cancel' | 'feedback.settings.comment.satisfiedLabel' | 'feedback.settings.comment.neutralLabel' | 'feedback.settings.comment.dissatisfiedLabel' | 'feedback.settings.submitText' | 'feedback.settings.label' | 'feedback.settings.reasons.label' | 'feedback.settings.reasons.send' | 'feedback.settings.comment.likeLabel' | 'feedback.settings.comment.dislikeLabel' | 'feedback.sentiment.thumbUp' | 'feedback.sentiment.thumbDown' | 'feedback.settings.leftScaleLabel' | 'feedback.settings.rightScaleLabel' | 'feedback.settings.optionalEmail.placeholder' | 'feedback.settings.optionalEmail.label' | 'codeSnippet.report.buttonText' | 'codeSnippet.report.tooltipText' | 'codeSnippet.report.label' | 'userMenu.login' | 'userMenu.logout' | 'userMenu.devOnboardingLabel' | 'mobileMenu.mainMenu' | 'mobileMenu.previous' | 'mobileMenu.products' | 'page.nextButton' | 'page.previousButton' | 'openapi.download.description.title' | 'openapi.info.title' | 'openapi.info.contact.url' | 'openapi.info.contact.name' | 'openapi.info.license' | 'openapi.info.termsOfService' | 'openapi.info.metadata.title' | 'openapi.key' | 'openapi.value' | 'openapi.enum' | 'openapi.items' | 'openapi.default' | 'openapi.variable' | 'openapi.variables' | 'openapi.actions.show' | 'openapi.actions.hide' | 'openapi.actions.more' | 'openapi.languages.title' | 'openapi.servers.title' | 'openapi.operations' | 'openapi.webhooks' | 'openapi.description' | 'openapi.badges.deprecated' | 'openapi.badges.required' | 'openapi.badges.webhook' | 'openapi.request' | 'openapi.path' | 'openapi.query' | 'openapi.cookie' | 'openapi.header' | 'openapi.body' | 'openapi.responses' | 'openapi.response' | 'openapi.callbacks' | 'openapi.callbackRequest' | 'openapi.callbackResponse' | 'openapi.payload' | 'openapi.discriminator' | 'openapi.contentType' | 'openapi.tryIt' | 'openapi.loading' | 'openapi.example' | 'openapi.examples' | 'openapi.additionalProperties' | 'openapi.patternProperties' | 'openapi.required' | 'openapi.recursive' | 'openapi.complex' | 'openapi.deprecated' | 'openapi.hideExample' | 'openapi.showExample' | 'openapi.expandAll' | 'openapi.collapseAll' | 'openapi.noResponseExample' | 'openapi.noResponseContent' | 'openapi.noRequestPayload' | 'openapi.hidePattern' | 'openapi.showPattern' | 'openapi.authorizationUrl' | 'openapi.tokenUrl' | 'openapi.refreshUrl' | 'openapi.scopes' | 'openapi.security' | 'openapi.httpAuthorizationScheme' | 'openapi.bearerFormat' | 'openapi.parameterName' | 'openapi.flowType' | 'openapi.connectUrl' | 'openapi.requiredScopes' | 'openapi.unsupportedLanguage' | 'openapi.failedToGenerateCodeSample' | 'graphql.queries' | 'graphql.mutations' | 'graphql.subscriptions' | 'graphql.directives' | 'graphql.objects' | 'graphql.interfaces' | 'graphql.unions' | 'graphql.enums' | 'graphql.inputs' | 'graphql.scalars' | 'graphql.arguments.label' | 'graphql.arguments.show' | 'graphql.arguments.hide' | 'graphql.arguments.here' | 'graphql.returnTypes.label' | 'graphql.returnTypes.show' | 'graphql.returnTypes.hide' | 'graphql.possibleTypes' | 'graphql.defaultValue' | 'graphql.deprecationReason' | 'graphql.implementedInterfaces' | 'graphql.nonNull' | 'graphql.required' | 'graphql.deprecated' | 'graphql.variables' | 'graphql.querySample' | 'graphql.mutationSample' | 'graphql.subscriptionSample' | 'graphql.responseSample' | 'graphql.locations' | 'graphql.sample' | 'graphql.referenced' | 'codeWalkthrough.download' | 'codeWalkthrough.preview';
|
|
2
|
+
export type TranslationKey = 'dev.newApp' | 'dev.newApp.text' | 'dev.sidebar.header' | 'dev.sidebar.footer.text' | 'dev.create.app.dialog.appName.placeholder' | 'dev.create.app.dialog.appName.error' | 'dev.create.app.dialog.selectAPIs' | 'dev.create.app.dialog.description' | 'dev.create.app.dialog.description.placeholder' | 'dev.create.app.dialog.create' | 'dev.create.app.dialog.cancel' | 'dev.main.tab.appKeys' | 'dev.main.tab.logs' | 'dev.app.description.title' | 'dev.edit.description.dialog.title' | 'dev.edit.description.dialog.save' | 'dev.edit.description.dialog.cancel' | 'dev.edit.apis.dialog.selectedAPIs' | 'dev.app.key.create' | 'dev.create.key.dialog.title' | 'dev.create.key.dialog.create' | 'dev.create.key.dialog.cancel' | 'dev.app.edit' | 'dev.app.delete' | 'dev.edit.app.dialog.title' | 'dev.edit.app.dialog.save' | 'dev.edit.app.dialog.cancel' | 'dev.delete.app.dialog.title' | 'dev.delete.app.dialog.confirmation' | 'dev.delete.app.dialog.delete' | 'dev.delete.app.dialog.cancel' | 'dev.app.key.roll' | 'dev.roll.key.dialog.title' | 'dev.roll.key.dialog.apiKey' | 'dev.roll.key.dialog.expires' | 'dev.roll.key.dialog.confirmation' | 'dev.roll.key.dialog.cancel' | 'dev.roll.key.dialog.roll' | 'dev.update.key.dialog.title' | 'dev.update.key.dialog.update' | 'dev.update.key.dialog.cancel' | 'dev.app.key.api.name' | 'dev.app.key.api.status' | 'dev.app.key.api.edit' | 'dev.edit.apis.dialog.title' | 'dev.edit.apis.dialog.apiKey' | 'dev.edit.apis.dialog.save' | 'dev.edit.apis.dialog.cancel' | 'dev.select.placeholder' | 'dev.app.overview.status.pending' | 'dev.app.overview.status.approved' | 'dev.app.overview.status.revoked' | 'dev.app.overview.status' | 'dev.app.overview.non-production' | 'dev.app.overview.production' | 'dev.app.overview.clientId' | 'dev.app.overview.apiKey' | 'dev.app.key.revoke' | 'dev.revoke.key.dialog.title' | 'dev.revoke.key.dialog.apiKey' | 'dev.revoke.key.dialog.expires' | 'dev.revoke.key.dialog.confirmation' | 'dev.revoke.key.dialog.revoke' | 'dev.revoke.key.dialog.cancel' | 'dev.app.overview.expires' | 'dev.app.overview.created' | 'dev.app.overview.visibilityToggle.hide' | 'dev.app.overview.visibilityToggle.show' | 'search.loading' | 'search.noResults.title' | 'search.keys.navigate' | 'search.keys.select' | 'search.keys.exit' | 'search.label' | 'search.cancel' | 'search.recent' | 'search.navbar.label' | 'search.suggested' | 'search.showMore' | 'search.filter.title' | 'search.filter.reset' | 'search.filter.field.reset' | 'search.ai.thinkingText' | 'search.ai.resourcesFound' | 'search.ai.button' | 'search.ai.label' | 'search.ai.disclaimer' | 'search.ai.error.description' | 'search.ai.error.header' | 'toc.header' | 'footer.copyrightText' | 'page.homeButton' | 'page.forbidden.title' | 'page.notFound.title' | 'page.notFound.description' | 'page.lastUpdated.timeago' | 'page.lastUpdated.on' | 'catalog.filters.placeholder' | 'catalog.filters.title' | 'catalog.filters.clearAll' | 'catalog.filters.select.addFilter' | 'catalog.filters.select.all' | 'catalog.filters.done' | 'sidebar.menu.backLabel' | 'sidebar.menu.backToLabel' | 'sidebar.actions.show' | 'sidebar.actions.hide' | 'sidebar.actions.changeLayout' | 'versionPicker.label' | 'versionPicker.unversioned' | 'codeSnippet.copy.buttonText' | 'codeSnippet.copy.tooltipText' | 'codeSnippet.copy.toasterText' | 'markdown.editPage.text' | 'feedback.settings.comment.submitText' | 'feedback.settings.comment.label' | 'feedback.settings.comment.send' | 'feedback.settings.comment.cancel' | 'feedback.settings.comment.satisfiedLabel' | 'feedback.settings.comment.neutralLabel' | 'feedback.settings.comment.dissatisfiedLabel' | 'feedback.settings.submitText' | 'feedback.settings.label' | 'feedback.settings.reasons.label' | 'feedback.settings.reasons.send' | 'feedback.settings.comment.likeLabel' | 'feedback.settings.comment.dislikeLabel' | 'feedback.sentiment.thumbUp' | 'feedback.sentiment.thumbDown' | 'feedback.settings.leftScaleLabel' | 'feedback.settings.rightScaleLabel' | 'feedback.settings.optionalEmail.placeholder' | 'feedback.settings.optionalEmail.label' | 'codeSnippet.report.buttonText' | 'codeSnippet.report.tooltipText' | 'codeSnippet.report.label' | 'userMenu.login' | 'userMenu.logout' | 'userMenu.devOnboardingLabel' | 'mobileMenu.mainMenu' | 'mobileMenu.previous' | 'mobileMenu.products' | 'page.nextButton' | 'page.previousButton' | 'openapi.download.description.title' | 'openapi.info.title' | 'openapi.info.contact.url' | 'openapi.info.contact.name' | 'openapi.info.license' | 'openapi.info.termsOfService' | 'openapi.info.metadata.title' | 'openapi.key' | 'openapi.value' | 'openapi.enum' | 'openapi.items' | 'openapi.default' | 'openapi.variable' | 'openapi.variables' | 'openapi.actions.show' | 'openapi.actions.hide' | 'openapi.actions.more' | 'openapi.languages.title' | 'openapi.servers.title' | 'openapi.operations' | 'openapi.webhooks' | 'openapi.description' | 'openapi.badges.deprecated' | 'openapi.badges.required' | 'openapi.badges.webhook' | 'openapi.request' | 'openapi.path' | 'openapi.query' | 'openapi.cookie' | 'openapi.header' | 'openapi.body' | 'openapi.responses' | 'openapi.response' | 'openapi.callbacks' | 'openapi.callbackRequest' | 'openapi.callbackResponse' | 'openapi.payload' | 'openapi.discriminator' | 'openapi.contentType' | 'openapi.tryIt' | 'openapi.loading' | 'openapi.example' | 'openapi.examples' | 'openapi.additionalProperties' | 'openapi.patternProperties' | 'openapi.required' | 'openapi.recursive' | 'openapi.complex' | 'openapi.deprecated' | 'openapi.hideExample' | 'openapi.showExample' | 'openapi.expandAll' | 'openapi.collapseAll' | 'openapi.noResponseExample' | 'openapi.noResponseContent' | 'openapi.noRequestPayload' | 'openapi.hidePattern' | 'openapi.showPattern' | 'openapi.authorizationUrl' | 'openapi.tokenUrl' | 'openapi.refreshUrl' | 'openapi.scopes' | 'openapi.security' | 'openapi.httpAuthorizationScheme' | 'openapi.bearerFormat' | 'openapi.parameterName' | 'openapi.flowType' | 'openapi.connectUrl' | 'openapi.requiredScopes' | 'openapi.unsupportedLanguage' | 'openapi.failedToGenerateCodeSample' | 'graphql.queries' | 'graphql.mutations' | 'graphql.subscriptions' | 'graphql.directives' | 'graphql.objects' | 'graphql.interfaces' | 'graphql.unions' | 'graphql.enums' | 'graphql.inputs' | 'graphql.scalars' | 'graphql.arguments.label' | 'graphql.arguments.show' | 'graphql.arguments.hide' | 'graphql.arguments.here' | 'graphql.returnTypes.label' | 'graphql.returnTypes.show' | 'graphql.returnTypes.hide' | 'graphql.possibleTypes' | 'graphql.defaultValue' | 'graphql.deprecationReason' | 'graphql.implementedInterfaces' | 'graphql.nonNull' | 'graphql.required' | 'graphql.deprecated' | 'graphql.variables' | 'graphql.querySample' | 'graphql.mutationSample' | 'graphql.subscriptionSample' | 'graphql.responseSample' | 'graphql.locations' | 'graphql.sample' | 'graphql.referenced' | 'codeWalkthrough.download' | 'codeWalkthrough.preview';
|
|
3
3
|
export type Locale = {
|
|
4
4
|
code: string;
|
|
5
5
|
name: string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { IconProps } from '../../icons/types';
|
|
3
|
+
export declare const ErrorFilledIcon: import("styled-components").StyledComponent<(props: IconProps) => React.JSX.Element, any, {
|
|
4
|
+
'data-component-name': string;
|
|
5
|
+
} & {
|
|
6
|
+
color?: string;
|
|
7
|
+
size?: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
} & React.SVGProps<SVGSVGElement>, "data-component-name">;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ErrorFilledIcon = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const styled_components_1 = __importDefault(require("styled-components"));
|
|
9
|
+
const utils_1 = require("../../core/utils");
|
|
10
|
+
const Icon = (props) => (react_1.default.createElement("svg", Object.assign({ xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 20 20", fill: "none" }, props),
|
|
11
|
+
react_1.default.createElement("path", { d: "M10.0002 1.24998C8.84911 1.24285 7.70808 1.4643 6.64326 1.9015C5.57844 2.3387 4.61101 2.98295 3.79707 3.79689C2.98313 4.61083 2.33889 5.57826 1.90168 6.64308C1.46448 7.7079 1.24303 8.84892 1.25017 9.99998C1.24303 11.151 1.46448 12.2921 1.90168 13.3569C2.33889 14.4217 2.98313 15.3891 3.79707 16.2031C4.61101 17.017 5.57844 17.6613 6.64326 18.0985C7.70808 18.5357 8.84911 18.7571 10.0002 18.75C11.1512 18.7571 12.2923 18.5357 13.3571 18.0985C14.4219 17.6613 15.3893 17.017 16.2033 16.2031C17.0172 15.3891 17.6614 14.4217 18.0986 13.3569C18.5359 12.2921 18.7573 11.151 18.7502 9.99998C18.7573 8.84892 18.5359 7.7079 18.0986 6.64308C17.6614 5.57826 17.0172 4.61083 16.2033 3.79689C15.3893 2.98295 14.4219 2.3387 13.3571 1.9015C12.2923 1.4643 11.1512 1.24285 10.0002 1.24998ZM13.4032 14.375L5.62517 6.5973L6.59748 5.62498L14.3752 13.403L13.4032 14.375Z", fill: "#F9316D" })));
|
|
12
|
+
exports.ErrorFilledIcon = (0, styled_components_1.default)(Icon).attrs(() => ({
|
|
13
|
+
'data-component-name': 'icons/ErrorFilledIcon/ErrorFilledIcon',
|
|
14
|
+
})) `
|
|
15
|
+
path {
|
|
16
|
+
fill: ${({ color }) => (0, utils_1.getCssColorVariable)(color)};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
height: ${({ size }) => size || '16px'};
|
|
20
|
+
width: ${({ size }) => size || '16px'};
|
|
21
|
+
`;
|
|
22
|
+
//# sourceMappingURL=ErrorFilledIcon.js.map
|
package/lib/index.d.ts
CHANGED
|
@@ -212,6 +212,7 @@ export * from './icons/CharacterIcon/CharacterIcon';
|
|
|
212
212
|
export * from './icons/FileIcon/FileIcon';
|
|
213
213
|
export * from './icons/ExportIcon/ExportIcon';
|
|
214
214
|
export * from './icons/CertificateIcon/CertificateIcon';
|
|
215
|
+
export * from './icons/ErrorFilledIcon/ErrorFilledIcon';
|
|
215
216
|
export * from './layouts/RootLayout';
|
|
216
217
|
export * from './layouts/PageLayout';
|
|
217
218
|
export * from './layouts/NotFound';
|
package/lib/index.js
CHANGED
|
@@ -264,6 +264,7 @@ __exportStar(require("./icons/CharacterIcon/CharacterIcon"), exports);
|
|
|
264
264
|
__exportStar(require("./icons/FileIcon/FileIcon"), exports);
|
|
265
265
|
__exportStar(require("./icons/ExportIcon/ExportIcon"), exports);
|
|
266
266
|
__exportStar(require("./icons/CertificateIcon/CertificateIcon"), exports);
|
|
267
|
+
__exportStar(require("./icons/ErrorFilledIcon/ErrorFilledIcon"), exports);
|
|
267
268
|
/* Layouts */
|
|
268
269
|
__exportStar(require("./layouts/RootLayout"), exports);
|
|
269
270
|
__exportStar(require("./layouts/PageLayout"), exports);
|
package/package.json
CHANGED
|
@@ -8,11 +8,14 @@ import { Tag } from '@redocly/theme/components/Tag/Tag';
|
|
|
8
8
|
import { Link } from '@redocly/theme/components/Link/Link';
|
|
9
9
|
import { useThemeHooks } from '@redocly/theme/core/hooks';
|
|
10
10
|
import { Markdown } from '@redocly/theme/components/Markdown/Markdown';
|
|
11
|
+
import { Admonition } from '@redocly/theme/components/Admonition/Admonition';
|
|
12
|
+
import { ErrorFilledIcon } from '@redocly/theme/icons/ErrorFilledIcon/ErrorFilledIcon';
|
|
11
13
|
|
|
12
14
|
export type SearchAiResponseProps = {
|
|
13
15
|
question: string;
|
|
14
16
|
isGeneratingResponse: boolean;
|
|
15
17
|
response?: string;
|
|
18
|
+
error: string | null;
|
|
16
19
|
resources: {
|
|
17
20
|
url: string;
|
|
18
21
|
title: string;
|
|
@@ -21,50 +24,79 @@ export type SearchAiResponseProps = {
|
|
|
21
24
|
|
|
22
25
|
export function SearchAiResponse(props: SearchAiResponseProps): JSX.Element {
|
|
23
26
|
const { useMarkdownText } = useThemeHooks();
|
|
24
|
-
const { question, response, isGeneratingResponse, resources } = props;
|
|
27
|
+
const { question, response, isGeneratingResponse, resources, error } = props;
|
|
25
28
|
|
|
26
29
|
const { useTranslate } = useThemeHooks();
|
|
27
30
|
const { translate } = useTranslate();
|
|
28
31
|
const markdownResponse = useMarkdownText(response || '');
|
|
29
32
|
|
|
33
|
+
let responseContainer = null;
|
|
34
|
+
|
|
35
|
+
const hasPendingOrReceivedResponse = response || isGeneratingResponse || error;
|
|
36
|
+
if (hasPendingOrReceivedResponse) {
|
|
37
|
+
let icon;
|
|
38
|
+
switch (true) {
|
|
39
|
+
case error !== null:
|
|
40
|
+
icon = <ErrorFilledIcon size="20px" color="--error-bubble-content-color" />;
|
|
41
|
+
break;
|
|
42
|
+
case isGeneratingResponse:
|
|
43
|
+
icon = <Spinner size="20px" color="--search-ai-spinner-icon-color" />;
|
|
44
|
+
break;
|
|
45
|
+
case Boolean(response):
|
|
46
|
+
icon = <CheckmarkFilledIcon size="20px" color="--search-ai-checkmark-icon-color" />;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
responseContainer = (
|
|
50
|
+
<>
|
|
51
|
+
<ResponseHeader>
|
|
52
|
+
{icon}
|
|
53
|
+
<Question>{question}</Question>
|
|
54
|
+
</ResponseHeader>
|
|
55
|
+
<ResponseBody>
|
|
56
|
+
{response && <ResponseText children={markdownResponse} as="div" {...props} />}
|
|
57
|
+
{!response && isGeneratingResponse && (
|
|
58
|
+
<ThinkingResponseText data-translation-key="search.ai.thinkingText">
|
|
59
|
+
{translate('search.ai.thinkingText', 'Thinking...')}
|
|
60
|
+
</ThinkingResponseText>
|
|
61
|
+
)}
|
|
62
|
+
{error && (
|
|
63
|
+
<Admonition
|
|
64
|
+
type="danger"
|
|
65
|
+
name={translate('search.ai.error.header', 'Oops! Something went wrong.')}
|
|
66
|
+
>
|
|
67
|
+
{translate(
|
|
68
|
+
'search.ai.error.description',
|
|
69
|
+
'We encountered an issue while processing your search. Please try again later or refine your query. If the problem persists, feel free to contact support.',
|
|
70
|
+
)}
|
|
71
|
+
</Admonition>
|
|
72
|
+
)}
|
|
73
|
+
{resources.length && !isGeneratingResponse ? (
|
|
74
|
+
<Resources>
|
|
75
|
+
<ResourcesTitle data-translation-key="search.ai.resourcesFound">
|
|
76
|
+
{resources.length} {translate('search.ai.resourcesFound', 'resources found')}
|
|
77
|
+
</ResourcesTitle>
|
|
78
|
+
<ResourceTags>
|
|
79
|
+
{resources.map((resource, idx) => (
|
|
80
|
+
<Link key={idx} to={resource.url} target="_blank">
|
|
81
|
+
<ResourceTag
|
|
82
|
+
borderless
|
|
83
|
+
icon={<DocumentIcon color="--search-ai-resource-tag-icon-color" />}
|
|
84
|
+
>
|
|
85
|
+
{resource.title}
|
|
86
|
+
</ResourceTag>
|
|
87
|
+
</Link>
|
|
88
|
+
))}
|
|
89
|
+
</ResourceTags>
|
|
90
|
+
</Resources>
|
|
91
|
+
) : null}
|
|
92
|
+
</ResponseBody>
|
|
93
|
+
</>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
30
97
|
return (
|
|
31
98
|
<ResponseWrapper data-component-name="Search/SearchAiResponse">
|
|
32
|
-
|
|
33
|
-
{isGeneratingResponse ? (
|
|
34
|
-
<Spinner size="20px" color="--search-ai-spinner-icon-color" />
|
|
35
|
-
) : (
|
|
36
|
-
<CheckmarkFilledIcon size="20px" color="--search-ai-checkmark-icon-color" />
|
|
37
|
-
)}
|
|
38
|
-
<Question>{question}</Question>
|
|
39
|
-
</ResponseHeader>
|
|
40
|
-
<ResponseBody>
|
|
41
|
-
{response ? (
|
|
42
|
-
<ResponseText children={markdownResponse} as="div" {...props} />
|
|
43
|
-
) : (
|
|
44
|
-
<ThinkingResponseText data-translation-key="search.ai.thinkingText">
|
|
45
|
-
{translate('search.ai.thinkingText', 'Thinking...')}
|
|
46
|
-
</ThinkingResponseText>
|
|
47
|
-
)}
|
|
48
|
-
{resources.length && !isGeneratingResponse ? (
|
|
49
|
-
<Resources>
|
|
50
|
-
<ResourcesTitle data-translation-key="search.ai.resourcesFound">
|
|
51
|
-
{resources.length} {translate('search.ai.resourcesFound', 'resources found')}
|
|
52
|
-
</ResourcesTitle>
|
|
53
|
-
<ResourceTags>
|
|
54
|
-
{resources.map((resource, idx) => (
|
|
55
|
-
<Link key={idx} to={resource.url} target="_blank">
|
|
56
|
-
<ResourceTag
|
|
57
|
-
borderless
|
|
58
|
-
icon={<DocumentIcon color="--search-ai-resource-tag-icon-color" />}
|
|
59
|
-
>
|
|
60
|
-
{resource.title}
|
|
61
|
-
</ResourceTag>
|
|
62
|
-
</Link>
|
|
63
|
-
))}
|
|
64
|
-
</ResourceTags>
|
|
65
|
-
</Resources>
|
|
66
|
-
) : null}
|
|
67
|
-
</ResponseBody>
|
|
99
|
+
{responseContainer}
|
|
68
100
|
</ResponseWrapper>
|
|
69
101
|
);
|
|
70
102
|
}
|
|
@@ -146,7 +146,10 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
|
|
|
146
146
|
}
|
|
147
147
|
isLoading={isSearchLoading}
|
|
148
148
|
showReturnButton={mode === 'ai-dialog'}
|
|
149
|
-
onReturn={() =>
|
|
149
|
+
onReturn={() => {
|
|
150
|
+
setMode('search');
|
|
151
|
+
aiSearch.clearAiSearchState();
|
|
152
|
+
}}
|
|
150
153
|
onSubmit={
|
|
151
154
|
mode === 'ai-dialog'
|
|
152
155
|
? () => {
|
|
@@ -250,6 +253,7 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
|
|
|
250
253
|
isGeneratingResponse={aiSearch.isGeneratingResponse}
|
|
251
254
|
response={aiSearch.response}
|
|
252
255
|
resources={aiSearch.resources}
|
|
256
|
+
error={aiSearch.error}
|
|
253
257
|
/>
|
|
254
258
|
)}
|
|
255
259
|
</SearchDialogBody>
|
|
@@ -18,19 +18,24 @@ export const useColorSwitcher = () => {
|
|
|
18
18
|
setActiveColorMode(activeMode || defaultColor);
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
const switchColorMode = ():
|
|
21
|
+
const switchColorMode = (mode?: string): void => {
|
|
22
|
+
if (mode && !modes.includes(mode)) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
22
26
|
const activeIndex = modes.indexOf(activeColorMode);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
// If specific mode is provided, use it, otherwise cycle through modes
|
|
28
|
+
const newMode = mode || (activeIndex < modes.length - 1 ? modes[activeIndex + 1] : modes[0]);
|
|
29
|
+
|
|
30
|
+
localStorage.setItem('colorSchema', newMode);
|
|
31
|
+
document.documentElement.className = `${newMode} notransition`;
|
|
26
32
|
|
|
27
33
|
window.requestAnimationFrame(() => {
|
|
28
34
|
document.documentElement.classList.remove('notransition');
|
|
29
35
|
});
|
|
30
|
-
telemetry.send('color_mode_switched', { from: activeColorMode, to:
|
|
36
|
+
telemetry.send('color_mode_switched', { from: activeColorMode, to: newMode });
|
|
31
37
|
|
|
32
|
-
setActiveColorMode(
|
|
33
|
-
return mode;
|
|
38
|
+
setActiveColorMode(newMode);
|
|
34
39
|
};
|
|
35
40
|
|
|
36
41
|
return {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { ApiFunctionsRequest as Request } from '@redocly/config';
|
|
2
|
+
export type { ApiFunctionsResponse as Response } from '@redocly/config';
|
|
3
|
+
export type { ApiFunctionsContext as Context } from '@redocly/config';
|
|
4
|
+
export type { PropsContext } from '@redocly/config';
|
|
5
|
+
export type { PageStaticData as PropsData } from '@redocly/config';
|
package/src/core/types/hooks.ts
CHANGED
package/src/core/types/index.ts
CHANGED
|
@@ -10,3 +10,4 @@ export * from '@redocly/theme/core/types/select';
|
|
|
10
10
|
export * from '@redocly/theme/core/types/sidebar';
|
|
11
11
|
export * from '@redocly/theme/core/types/filter';
|
|
12
12
|
export * from '@redocly/theme/core/types/user-menu';
|
|
13
|
+
export * from '@redocly/theme/core/types/api-functions';
|
package/src/core/types/l10n.ts
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
|
|
4
|
+
import type { IconProps } from '@redocly/theme/icons/types';
|
|
5
|
+
|
|
6
|
+
import { getCssColorVariable } from '@redocly/theme/core/utils';
|
|
7
|
+
|
|
8
|
+
const Icon = (props: IconProps) => (
|
|
9
|
+
<svg
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
width="20"
|
|
12
|
+
height="20"
|
|
13
|
+
viewBox="0 0 20 20"
|
|
14
|
+
fill="none"
|
|
15
|
+
{...props}
|
|
16
|
+
>
|
|
17
|
+
<path
|
|
18
|
+
d="M10.0002 1.24998C8.84911 1.24285 7.70808 1.4643 6.64326 1.9015C5.57844 2.3387 4.61101 2.98295 3.79707 3.79689C2.98313 4.61083 2.33889 5.57826 1.90168 6.64308C1.46448 7.7079 1.24303 8.84892 1.25017 9.99998C1.24303 11.151 1.46448 12.2921 1.90168 13.3569C2.33889 14.4217 2.98313 15.3891 3.79707 16.2031C4.61101 17.017 5.57844 17.6613 6.64326 18.0985C7.70808 18.5357 8.84911 18.7571 10.0002 18.75C11.1512 18.7571 12.2923 18.5357 13.3571 18.0985C14.4219 17.6613 15.3893 17.017 16.2033 16.2031C17.0172 15.3891 17.6614 14.4217 18.0986 13.3569C18.5359 12.2921 18.7573 11.151 18.7502 9.99998C18.7573 8.84892 18.5359 7.7079 18.0986 6.64308C17.6614 5.57826 17.0172 4.61083 16.2033 3.79689C15.3893 2.98295 14.4219 2.3387 13.3571 1.9015C12.2923 1.4643 11.1512 1.24285 10.0002 1.24998ZM13.4032 14.375L5.62517 6.5973L6.59748 5.62498L14.3752 13.403L13.4032 14.375Z"
|
|
19
|
+
fill="#F9316D"
|
|
20
|
+
/>
|
|
21
|
+
</svg>
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
export const ErrorFilledIcon = styled(Icon).attrs(() => ({
|
|
25
|
+
'data-component-name': 'icons/ErrorFilledIcon/ErrorFilledIcon',
|
|
26
|
+
}))<IconProps>`
|
|
27
|
+
path {
|
|
28
|
+
fill: ${({ color }) => getCssColorVariable(color)};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
height: ${({ size }) => size || '16px'};
|
|
32
|
+
width: ${({ size }) => size || '16px'};
|
|
33
|
+
`;
|
package/src/index.ts
CHANGED
|
@@ -236,6 +236,7 @@ export * from '@redocly/theme/icons/CharacterIcon/CharacterIcon';
|
|
|
236
236
|
export * from '@redocly/theme/icons/FileIcon/FileIcon';
|
|
237
237
|
export * from '@redocly/theme/icons/ExportIcon/ExportIcon';
|
|
238
238
|
export * from '@redocly/theme/icons/CertificateIcon/CertificateIcon';
|
|
239
|
+
export * from '@redocly/theme/icons/ErrorFilledIcon/ErrorFilledIcon';
|
|
239
240
|
/* Layouts */
|
|
240
241
|
export * from '@redocly/theme/layouts/RootLayout';
|
|
241
242
|
export * from '@redocly/theme/layouts/PageLayout';
|