@redocly/theme 0.50.0 → 0.51.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/PageNavigation/NextButton.js +1 -2
- package/lib/components/PageNavigation/PreviousButton.js +2 -2
- package/lib/components/Search/SearchAiResponse.d.ts +1 -0
- package/lib/components/Search/SearchAiResponse.js +35 -14
- package/lib/components/Search/SearchDialog.js +10 -7
- package/lib/core/hooks/code-walkthrough/use-code-panel.js +4 -3
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.js +5 -0
- package/lib/core/hooks/use-color-switcher.d.ts +1 -1
- package/lib/core/hooks/use-color-switcher.js +10 -7
- package/lib/core/hooks/use-theme-hooks.js +1 -0
- 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 +7 -1
- 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/lib/markdoc/components/CodeWalkthrough/CodeStep.js +3 -2
- package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.js +1 -2
- package/package.json +1 -1
- package/src/components/PageNavigation/NextButton.tsx +2 -2
- package/src/components/PageNavigation/PreviousButton.tsx +3 -2
- package/src/components/Search/SearchAiResponse.tsx +69 -37
- package/src/components/Search/SearchDialog.tsx +10 -6
- package/src/core/hooks/code-walkthrough/use-code-panel.ts +4 -3
- package/src/core/hooks/code-walkthrough/use-code-walkthrough-controls.ts +5 -0
- package/src/core/hooks/use-color-switcher.ts +12 -7
- package/src/core/hooks/use-theme-hooks.ts +1 -0
- package/src/core/types/api-functions.ts +5 -0
- package/src/core/types/hooks.ts +11 -2
- 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
- package/src/markdoc/components/CodeWalkthrough/CodeStep.tsx +3 -1
- package/src/markdoc/components/CodeWalkthrough/CodeWalkthrough.tsx +1 -2
|
@@ -41,9 +41,8 @@ function NextButton({ nextPage, className }) {
|
|
|
41
41
|
return React.createElement("div", null, "\u00A0");
|
|
42
42
|
}
|
|
43
43
|
const nextPageText = nextPage.label || nextPage.routeSlug || '';
|
|
44
|
-
const defaultLabel = ((_b = navigation === null || navigation === void 0 ? void 0 : navigation.nextButton) === null || _b === void 0 ? void 0 : _b.text) || 'Next page';
|
|
45
44
|
const translationKey = 'page.nextButton';
|
|
46
|
-
const label = translate(translationKey, { defaultValue:
|
|
45
|
+
const label = ((_b = navigation === null || navigation === void 0 ? void 0 : navigation.nextButton) === null || _b === void 0 ? void 0 : _b.text) || translate(translationKey, { defaultValue: 'Next page' });
|
|
47
46
|
return (React.createElement(NextButtonWrapper, { "data-component-name": "PageNavigation/NextButton", "data-translation-key": translationKey },
|
|
48
47
|
React.createElement(NextPageLabel, null, label),
|
|
49
48
|
React.createElement(NextPageButton, { size: "large", to: nextPage.link, extraClass: className, variant: "link", icon: React.createElement(ArrowRightIcon_1.ArrowRightIcon, null), iconPosition: "right" }, nextPageText)));
|
|
@@ -18,9 +18,9 @@ function PreviousButton({ prevPage, className }) {
|
|
|
18
18
|
return react_1.default.createElement("div", null, "\u00A0");
|
|
19
19
|
}
|
|
20
20
|
const prevPageText = prevPage.label || prevPage.routeSlug || '';
|
|
21
|
-
const defaultLabel = ((_b = navigation === null || navigation === void 0 ? void 0 : navigation.previousButton) === null || _b === void 0 ? void 0 : _b.text) || 'Previous page';
|
|
22
21
|
const translationKey = 'page.previousButton';
|
|
23
|
-
const label =
|
|
22
|
+
const label = ((_b = navigation === null || navigation === void 0 ? void 0 : navigation.previousButton) === null || _b === void 0 ? void 0 : _b.text) ||
|
|
23
|
+
translate(translationKey, { defaultValue: 'Previous page' });
|
|
24
24
|
return (react_1.default.createElement(PreviousButtonWrapper, { "data-component-name": "PageNavigation/PreviousButton", "data-translation-key": translationKey },
|
|
25
25
|
react_1.default.createElement(PreviousPageLabel, null, label),
|
|
26
26
|
react_1.default.createElement(PreviousPageButton, { size: "large", to: prevPage.link, extraClass: className, variant: "link", icon: react_1.default.createElement(ArrowLeftIcon_1.ArrowLeftIcon, null), iconPosition: "left" }, prevPageText)));
|
|
@@ -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;
|
|
@@ -46,8 +46,8 @@ const SpinnerLoader_1 = require("../../components/Loaders/SpinnerLoader");
|
|
|
46
46
|
const SettingsIcon_1 = require("../../icons/SettingsIcon/SettingsIcon");
|
|
47
47
|
const AiStarsIcon_1 = require("../../icons/AiStarsIcon/AiStarsIcon");
|
|
48
48
|
function SearchDialog({ onClose, className }) {
|
|
49
|
-
const { useTranslate, useCurrentProduct, useSearch, useProducts, useAiSearch,
|
|
50
|
-
const
|
|
49
|
+
const { useTranslate, useCurrentProduct, useSearch, useProducts, useAiSearch, useOtelTelemetry } = (0, hooks_1.useThemeHooks)();
|
|
50
|
+
const otelTelemetry = useOtelTelemetry();
|
|
51
51
|
const products = useProducts();
|
|
52
52
|
const currentProduct = useCurrentProduct();
|
|
53
53
|
const [product, setProduct] = (0, react_1.useState)(currentProduct);
|
|
@@ -79,11 +79,11 @@ function SearchDialog({ onClose, className }) {
|
|
|
79
79
|
: undefined;
|
|
80
80
|
}
|
|
81
81
|
return (react_1.default.createElement(SearchItem_1.SearchItem, { key: `${index}-${item.document.id}`, item: item, product: itemProduct, onClick: () => {
|
|
82
|
-
|
|
82
|
+
otelTelemetry.send('search.result.clicked', {
|
|
83
83
|
query,
|
|
84
84
|
url: item.document.url,
|
|
85
|
-
total_results: results.length,
|
|
86
|
-
index,
|
|
85
|
+
total_results: results.length.toString(),
|
|
86
|
+
index: index.toString(),
|
|
87
87
|
search_engine: mode,
|
|
88
88
|
});
|
|
89
89
|
} }));
|
|
@@ -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') }),
|
|
@@ -82,9 +82,10 @@ function getCodeLinesFromNode(node, activeStep, areConditionsMet, populateInputs
|
|
|
82
82
|
}
|
|
83
83
|
else {
|
|
84
84
|
const shouldRenderChunk = areConditionsMet(node.condition);
|
|
85
|
-
const isHighlighted =
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
const isHighlighted = parentHighlighted ||
|
|
86
|
+
(activeStep != null &&
|
|
87
|
+
node.condition.steps.length > 0 &&
|
|
88
|
+
node.condition.steps.includes(activeStep));
|
|
88
89
|
return shouldRenderChunk
|
|
89
90
|
? node.children.flatMap((child) => getCodeLinesFromNode(child, activeStep, areConditionsMet, populateInputsWithValue, isHighlighted))
|
|
90
91
|
: [];
|
|
@@ -75,6 +75,11 @@ function useCodeWalkthroughControls(filters, inputs, toggles, enableDeepLink) {
|
|
|
75
75
|
};
|
|
76
76
|
const walkthroughContext = (0, react_1.useMemo)(() => {
|
|
77
77
|
const areConditionsMet = (conditions) => (0, utils_1.matchCodeWalkthroughConditions)(conditions, controlsState);
|
|
78
|
+
// reset controls
|
|
79
|
+
for (const control of Object.values(controlsState)) {
|
|
80
|
+
control.render = true;
|
|
81
|
+
control.value = control.value || defaultControlsValues[control.type];
|
|
82
|
+
}
|
|
78
83
|
for (const [id, control] of Object.entries(controlsState)) {
|
|
79
84
|
if (control && !areConditionsMet(control)) {
|
|
80
85
|
controlsState[id].render = false;
|
|
@@ -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,
|
|
@@ -9,6 +9,7 @@ const fallbacks = {
|
|
|
9
9
|
}),
|
|
10
10
|
useSubmitFeedback: () => ({ submitFeedback: () => { } }),
|
|
11
11
|
useTelemetry: () => ({ telemetry: () => { } }),
|
|
12
|
+
useOtelTelemetry: () => ({ send: () => { } }),
|
|
12
13
|
useBreadcrumbs: () => [],
|
|
13
14
|
useCodeHighlight: () => ({ highlight: (rawContent) => rawContent }),
|
|
14
15
|
useUserMenu: () => ({}),
|
|
@@ -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';
|
|
@@ -73,6 +73,8 @@ export type ThemeHooks = {
|
|
|
73
73
|
title: string;
|
|
74
74
|
url: string;
|
|
75
75
|
}[];
|
|
76
|
+
error: null | string;
|
|
77
|
+
clearAiSearchState: () => void;
|
|
76
78
|
};
|
|
77
79
|
useMarkdownText: (text: string) => React.ReactNode;
|
|
78
80
|
useFacetQuery: (field: string) => {
|
|
@@ -98,6 +100,9 @@ export type ThemeHooks = {
|
|
|
98
100
|
useTelemetry: () => {
|
|
99
101
|
send(action: TelemetryEvent, data: unknown): void;
|
|
100
102
|
};
|
|
103
|
+
useOtelTelemetry: () => {
|
|
104
|
+
send(action: OtelTelemetryEvent, data: unknown): void;
|
|
105
|
+
};
|
|
101
106
|
useUserTeams: () => string[];
|
|
102
107
|
usePageProps: <T extends Record<string, unknown>>() => PageProps & T;
|
|
103
108
|
useCodeHighlight: () => {
|
|
@@ -121,5 +126,6 @@ export type L10nConfig = {
|
|
|
121
126
|
name: string;
|
|
122
127
|
}[];
|
|
123
128
|
};
|
|
124
|
-
type TelemetryEvent = 'search_opened' | 'client_error_caught' | 'breadcrumb_clicked' | 'color_mode_switched' | 'sidebar_item_clicked' | 'sidebar_item_expanded' | 'sidebar_item_collapsed' | 'edit_page_link_clicked' | 'code_snippet_copied' | 'code_snippet_reported' | 'feedback_sent' | 'navbar_menu_item_clicked' | 'login_button_clicked' | 'login_provider_button_clicked' | 'logout_menu_item_clicked' | 'logo_clicked' | 'toc_item_clicked' | 'version_switched' | 'catalog_filter_changed' | 'catalog_item_clicked' | 'scorecard_link_clicked' | 'markdown_anchor_link_clicked' | 'back_to_catalog_button_clicked' | 'sidebar_drilldown_back_button_clicked' | 'footer_item_clicked' | 'request_api_access_button_clicked' | 'sidebar_samples_button_clicked' | 'change_layout_button_clicked' | 'version_picker_selection_change' | 'openapi_docs' | 'replay' | 'catalog_actions_button_clicked' | 'catalog_item_clicked' | 'filter_checkbox_toggled' | 'language_picker_locale_changed' | 'mobile_menu_button_close_clicked' | 'mobile_menu_button_open_clicked' | 'search_input_reset_button_clicked' | 'search_recent_remove_button_clicked' | 'product_picked'
|
|
129
|
+
type TelemetryEvent = 'search_opened' | 'client_error_caught' | 'breadcrumb_clicked' | 'color_mode_switched' | 'sidebar_item_clicked' | 'sidebar_item_expanded' | 'sidebar_item_collapsed' | 'edit_page_link_clicked' | 'code_snippet_copied' | 'code_snippet_reported' | 'feedback_sent' | 'navbar_menu_item_clicked' | 'login_button_clicked' | 'login_provider_button_clicked' | 'logout_menu_item_clicked' | 'logo_clicked' | 'toc_item_clicked' | 'version_switched' | 'catalog_filter_changed' | 'catalog_item_clicked' | 'scorecard_link_clicked' | 'markdown_anchor_link_clicked' | 'back_to_catalog_button_clicked' | 'sidebar_drilldown_back_button_clicked' | 'footer_item_clicked' | 'request_api_access_button_clicked' | 'sidebar_samples_button_clicked' | 'change_layout_button_clicked' | 'version_picker_selection_change' | 'openapi_docs' | 'replay' | 'catalog_actions_button_clicked' | 'catalog_item_clicked' | 'filter_checkbox_toggled' | 'language_picker_locale_changed' | 'mobile_menu_button_close_clicked' | 'mobile_menu_button_open_clicked' | 'search_input_reset_button_clicked' | 'search_recent_remove_button_clicked' | 'product_picked';
|
|
130
|
+
type OtelTelemetryEvent = 'page.viewed' | 'error' | 'search.ai.query' | 'search.query' | 'search.result.clicked';
|
|
125
131
|
export {};
|
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);
|
|
@@ -53,7 +53,8 @@ function CodeStep({ id, heading, stepKey, when, unless, children, }) {
|
|
|
53
53
|
// If the step is active during first render, scroll to it
|
|
54
54
|
// This is to ensure that the step is visible when the page is loaded
|
|
55
55
|
if (isActive) {
|
|
56
|
-
|
|
56
|
+
// Ensure scrollMarginTop calculated before step being scrolled.
|
|
57
|
+
setTimeout(handleActivateStep, 5);
|
|
57
58
|
}
|
|
58
59
|
// Ignore dependency array because we only need to run this once
|
|
59
60
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -84,7 +85,7 @@ function CodeStep({ id, heading, stepKey, when, unless, children, }) {
|
|
|
84
85
|
}
|
|
85
86
|
return null;
|
|
86
87
|
}
|
|
87
|
-
return (react_1.default.createElement(exports.StepWrapper, { "data-component-name": "Markdoc/CodeWalkthrough/CodeStep", ref: compRef, isActive: isActive, scrollMarginTop: scrollMarginTop, "data-step-key": stepKey, "data-step-active": isActive, onClick: handleActivateStep, onFocus: handleActivateStep, tabIndex: 0 },
|
|
88
|
+
return (react_1.default.createElement(exports.StepWrapper, { "data-component-name": "Markdoc/CodeWalkthrough/CodeStep", ref: compRef, isActive: isActive, scrollMarginTop: scrollMarginTop, "data-step-key": stepKey, "data-step-active": isActive, onClick: handleActivateStep, onFocus: handleActivateStep, tabIndex: 0, className: "code-step-wrapper" },
|
|
88
89
|
react_1.default.createElement(StepContent, { isActive: isActive },
|
|
89
90
|
heading ? react_1.default.createElement(StepHeading, null, heading) : null,
|
|
90
91
|
children)));
|
|
@@ -44,7 +44,6 @@ const contexts_1 = require("../../../core/contexts");
|
|
|
44
44
|
const CodePanel_1 = require("../../../markdoc/components/CodeWalkthrough/CodePanel");
|
|
45
45
|
const hooks_1 = require("../../../core/hooks");
|
|
46
46
|
const CodeFilters_1 = require("../../../markdoc/components/CodeWalkthrough/CodeFilters");
|
|
47
|
-
const CodeStep_1 = require("../../../markdoc/components/CodeWalkthrough/CodeStep");
|
|
48
47
|
function CodeWalkthrough(_a) {
|
|
49
48
|
var { children, steps, preview } = _a, attributes = __rest(_a, ["children", "steps", "preview"]);
|
|
50
49
|
// Steps are being modified causing the observer to be recreated in the useCodeWalkthrough hook
|
|
@@ -95,7 +94,7 @@ const ContentWrapper = styled_components_1.default.div `
|
|
|
95
94
|
min-height: 0;
|
|
96
95
|
max-width: var(--md-content-max-width);
|
|
97
96
|
|
|
98
|
-
& > *:not(
|
|
97
|
+
& > *:not(.code-step-wrapper) {
|
|
99
98
|
padding-left: var(--spacing-xl);
|
|
100
99
|
}
|
|
101
100
|
overflow-y: scroll;
|
package/package.json
CHANGED
|
@@ -22,9 +22,9 @@ export function NextButton({ nextPage, className }: NextPageType): JSX.Element {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const nextPageText = nextPage.label || nextPage.routeSlug || '';
|
|
25
|
-
const defaultLabel = navigation?.nextButton?.text || 'Next page';
|
|
26
25
|
const translationKey = 'page.nextButton';
|
|
27
|
-
const label =
|
|
26
|
+
const label =
|
|
27
|
+
navigation?.nextButton?.text || translate(translationKey, { defaultValue: 'Next page' });
|
|
28
28
|
|
|
29
29
|
return (
|
|
30
30
|
<NextButtonWrapper
|
|
@@ -22,9 +22,10 @@ export function PreviousButton({ prevPage, className }: PreviousPageType): JSX.E
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const prevPageText = prevPage.label || prevPage.routeSlug || '';
|
|
25
|
-
const defaultLabel = navigation?.previousButton?.text || 'Previous page';
|
|
26
25
|
const translationKey = 'page.previousButton';
|
|
27
|
-
const label =
|
|
26
|
+
const label =
|
|
27
|
+
navigation?.previousButton?.text ||
|
|
28
|
+
translate(translationKey, { defaultValue: 'Previous page' });
|
|
28
29
|
|
|
29
30
|
return (
|
|
30
31
|
<PreviousButtonWrapper
|
|
@@ -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
|
}
|
|
@@ -27,9 +27,9 @@ export type SearchDialogProps = {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Element {
|
|
30
|
-
const { useTranslate, useCurrentProduct, useSearch, useProducts, useAiSearch,
|
|
30
|
+
const { useTranslate, useCurrentProduct, useSearch, useProducts, useAiSearch, useOtelTelemetry } =
|
|
31
31
|
useThemeHooks();
|
|
32
|
-
const
|
|
32
|
+
const otelTelemetry = useOtelTelemetry();
|
|
33
33
|
const products = useProducts();
|
|
34
34
|
const currentProduct = useCurrentProduct();
|
|
35
35
|
const [product, setProduct] = useState(currentProduct);
|
|
@@ -88,11 +88,11 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
|
|
|
88
88
|
item={item}
|
|
89
89
|
product={itemProduct}
|
|
90
90
|
onClick={() => {
|
|
91
|
-
|
|
91
|
+
otelTelemetry.send('search.result.clicked', {
|
|
92
92
|
query,
|
|
93
93
|
url: item.document.url,
|
|
94
|
-
total_results: results.length,
|
|
95
|
-
index,
|
|
94
|
+
total_results: results.length.toString(),
|
|
95
|
+
index: index.toString(),
|
|
96
96
|
search_engine: mode,
|
|
97
97
|
});
|
|
98
98
|
}}
|
|
@@ -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>
|
|
@@ -145,9 +145,10 @@ function getCodeLinesFromNode(
|
|
|
145
145
|
const shouldRenderChunk = areConditionsMet(node.condition);
|
|
146
146
|
|
|
147
147
|
const isHighlighted =
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
parentHighlighted ||
|
|
149
|
+
(activeStep != null &&
|
|
150
|
+
node.condition.steps.length > 0 &&
|
|
151
|
+
node.condition.steps.includes(activeStep));
|
|
151
152
|
|
|
152
153
|
return shouldRenderChunk
|
|
153
154
|
? node.children.flatMap((child) =>
|
|
@@ -155,6 +155,11 @@ export function useCodeWalkthroughControls(
|
|
|
155
155
|
const walkthroughContext = useMemo(() => {
|
|
156
156
|
const areConditionsMet = (conditions: CodeWalkthroughConditionsObject) =>
|
|
157
157
|
matchCodeWalkthroughConditions(conditions, controlsState);
|
|
158
|
+
// reset controls
|
|
159
|
+
for (const control of Object.values(controlsState)) {
|
|
160
|
+
control.render = true;
|
|
161
|
+
control.value = control.value || defaultControlsValues[control.type];
|
|
162
|
+
}
|
|
158
163
|
|
|
159
164
|
for (const [id, control] of Object.entries(controlsState)) {
|
|
160
165
|
if (control && !areConditionsMet(control)) {
|
|
@@ -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 {
|
|
@@ -11,6 +11,7 @@ const fallbacks = {
|
|
|
11
11
|
}),
|
|
12
12
|
useSubmitFeedback: () => ({ submitFeedback: () => {} }),
|
|
13
13
|
useTelemetry: () => ({ telemetry: () => {} }),
|
|
14
|
+
useOtelTelemetry: () => ({ send: () => {} }),
|
|
14
15
|
useBreadcrumbs: () => [],
|
|
15
16
|
useCodeHighlight: () => ({ highlight: (rawContent: string) => rawContent }),
|
|
16
17
|
useUserMenu: () => ({}),
|
|
@@ -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
|
@@ -88,6 +88,8 @@ export type ThemeHooks = {
|
|
|
88
88
|
title: string;
|
|
89
89
|
url: string;
|
|
90
90
|
}[];
|
|
91
|
+
error: null | string;
|
|
92
|
+
clearAiSearchState: () => void;
|
|
91
93
|
};
|
|
92
94
|
useMarkdownText: (text: string) => React.ReactNode;
|
|
93
95
|
useFacetQuery: (field: string) => {
|
|
@@ -110,6 +112,7 @@ export type ThemeHooks = {
|
|
|
110
112
|
| undefined;
|
|
111
113
|
useCatalog: (config: CatalogConfig) => FilteredCatalog;
|
|
112
114
|
useTelemetry: () => { send(action: TelemetryEvent, data: unknown): void };
|
|
115
|
+
useOtelTelemetry: () => { send(action: OtelTelemetryEvent, data: unknown): void };
|
|
113
116
|
useUserTeams: () => string[];
|
|
114
117
|
usePageProps: <T extends Record<string, unknown>>() => PageProps & T;
|
|
115
118
|
useCodeHighlight: () => {
|
|
@@ -173,5 +176,11 @@ type TelemetryEvent =
|
|
|
173
176
|
| 'mobile_menu_button_open_clicked'
|
|
174
177
|
| 'search_input_reset_button_clicked'
|
|
175
178
|
| 'search_recent_remove_button_clicked'
|
|
176
|
-
| 'product_picked'
|
|
177
|
-
|
|
179
|
+
| 'product_picked';
|
|
180
|
+
|
|
181
|
+
type OtelTelemetryEvent =
|
|
182
|
+
| 'page.viewed'
|
|
183
|
+
| 'error'
|
|
184
|
+
| 'search.ai.query'
|
|
185
|
+
| 'search.query'
|
|
186
|
+
| 'search.result.clicked';
|
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';
|
|
@@ -49,7 +49,8 @@ export function CodeStep({
|
|
|
49
49
|
// If the step is active during first render, scroll to it
|
|
50
50
|
// This is to ensure that the step is visible when the page is loaded
|
|
51
51
|
if (isActive) {
|
|
52
|
-
|
|
52
|
+
// Ensure scrollMarginTop calculated before step being scrolled.
|
|
53
|
+
setTimeout(handleActivateStep, 5);
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
// Ignore dependency array because we only need to run this once
|
|
@@ -97,6 +98,7 @@ export function CodeStep({
|
|
|
97
98
|
onClick={handleActivateStep}
|
|
98
99
|
onFocus={handleActivateStep}
|
|
99
100
|
tabIndex={0}
|
|
101
|
+
className="code-step-wrapper"
|
|
100
102
|
>
|
|
101
103
|
<StepContent isActive={isActive}>
|
|
102
104
|
{heading ? <StepHeading>{heading}</StepHeading> : null}
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
CodeFilters,
|
|
14
14
|
GetFilterState,
|
|
15
15
|
} from '@redocly/theme/markdoc/components/CodeWalkthrough/CodeFilters';
|
|
16
|
-
import { StepWrapper } from '@redocly/theme/markdoc/components/CodeWalkthrough/CodeStep';
|
|
17
16
|
|
|
18
17
|
export type CodeWalkthroughProps = PropsWithChildren<CodeWalkthroughAttr>;
|
|
19
18
|
|
|
@@ -92,7 +91,7 @@ const ContentWrapper = styled.div`
|
|
|
92
91
|
min-height: 0;
|
|
93
92
|
max-width: var(--md-content-max-width);
|
|
94
93
|
|
|
95
|
-
& > *:not(
|
|
94
|
+
& > *:not(.code-step-wrapper) {
|
|
96
95
|
padding-left: var(--spacing-xl);
|
|
97
96
|
}
|
|
98
97
|
overflow-y: scroll;
|