@redocly/theme 0.48.0 → 0.48.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/DatePicker/variables.js +1 -1
- package/lib/components/Feedback/Mood.js +14 -9
- package/lib/components/Search/SearchDialog.js +9 -3
- package/lib/components/Search/variables.js +4 -0
- package/lib/components/Segmented/Segmented.d.ts +4 -4
- package/lib/components/Segmented/Segmented.js +4 -7
- package/lib/components/Tag/Tag.d.ts +1 -0
- package/lib/components/Tag/Tag.js +3 -2
- package/lib/core/contexts/CodeWalkthrough/CodeWalkthroughControlsContext.js +2 -6
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.d.ts +7 -10
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.js +63 -97
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.d.ts +1 -2
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.js +20 -15
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough.d.ts +2 -7
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough.js +10 -3
- package/lib/core/hooks/code-walkthrough/use-renderable-files.d.ts +9 -0
- package/lib/core/hooks/code-walkthrough/use-renderable-files.js +28 -0
- package/lib/core/hooks/index.d.ts +1 -0
- package/lib/core/hooks/index.js +1 -0
- package/lib/core/styles/global.js +18 -0
- package/lib/core/types/l10n.d.ts +1 -1
- package/lib/core/utils/download-code-walkthrough.d.ts +4 -2
- package/lib/core/utils/download-code-walkthrough.js +9 -1
- package/lib/core/utils/find-closest-common-directory.d.ts +6 -0
- package/lib/core/utils/find-closest-common-directory.js +51 -0
- package/lib/core/utils/get-code-walkthrough-file-text.d.ts +4 -2
- package/lib/core/utils/get-file-icon.js +6 -0
- package/lib/core/utils/index.d.ts +1 -0
- package/lib/core/utils/index.js +1 -0
- package/lib/core/utils/replace-inputs-with-value.d.ts +1 -1
- package/lib/core/utils/replace-inputs-with-value.js +9 -10
- package/lib/icons/DocumentJavaIcon/DocumentJavaIcon.d.ts +9 -0
- package/lib/icons/DocumentJavaIcon/DocumentJavaIcon.js +22 -0
- package/lib/icons/DocumentJavaIcon/index.d.ts +1 -0
- package/lib/icons/DocumentJavaIcon/index.js +6 -0
- package/lib/icons/DocumentPythonIcon/DocumentPythonIcon.d.ts +9 -0
- package/lib/icons/DocumentPythonIcon/DocumentPythonIcon.js +23 -0
- package/lib/icons/DocumentPythonIcon/index.d.ts +1 -0
- package/lib/icons/DocumentPythonIcon/index.js +6 -0
- package/lib/icons/DocumentShellIcon/DocumentShellIcon.d.ts +9 -0
- package/lib/icons/DocumentShellIcon/DocumentShellIcon.js +22 -0
- package/lib/icons/DocumentShellIcon/index.d.ts +1 -0
- package/lib/icons/DocumentShellIcon/index.js +6 -0
- package/lib/icons/__tests__/IconTestUtils.d.ts +7 -0
- package/lib/icons/__tests__/IconTestUtils.js +33 -0
- package/lib/layouts/CodeWalkthroughLayout.js +4 -1
- package/lib/markdoc/components/CodeWalkthrough/CodeContainer.js +25 -4
- package/lib/markdoc/components/CodeWalkthrough/CodeFilters.d.ts +5 -4
- package/lib/markdoc/components/CodeWalkthrough/CodeFilters.js +15 -2
- package/lib/markdoc/components/CodeWalkthrough/CodePanel.js +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodePanelHeader.js +29 -23
- package/lib/markdoc/components/CodeWalkthrough/CodePanelPreview.js +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodePanelToolbar.js +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodeStep.js +5 -2
- package/lib/markdoc/components/CodeWalkthrough/CodeToggle.js +5 -5
- package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.js +3 -3
- package/lib/markdoc/components/CodeWalkthrough/Input.js +7 -5
- package/lib/markdoc/tags/code-walkthrough.js +5 -0
- package/package.json +3 -3
- package/src/components/DatePicker/variables.ts +1 -1
- package/src/components/Feedback/Mood.tsx +16 -7
- package/src/components/Search/SearchDialog.tsx +52 -36
- package/src/components/Search/variables.ts +4 -0
- package/src/components/Segmented/Segmented.tsx +10 -10
- package/src/components/Tag/Tag.tsx +1 -1
- package/src/core/contexts/CodeWalkthrough/CodeWalkthroughControlsContext.tsx +2 -8
- package/src/core/hooks/code-walkthrough/use-code-walkthrough-controls.ts +90 -142
- package/src/core/hooks/code-walkthrough/use-code-walkthrough-steps.ts +30 -18
- package/src/core/hooks/code-walkthrough/use-code-walkthrough.ts +13 -13
- package/src/core/hooks/code-walkthrough/use-renderable-files.ts +51 -0
- package/src/core/hooks/index.ts +1 -0
- package/src/core/styles/global.ts +18 -0
- package/src/core/types/l10n.ts +3 -1
- package/src/core/utils/download-code-walkthrough.ts +16 -4
- package/src/core/utils/find-closest-common-directory.ts +51 -0
- package/src/core/utils/get-code-walkthrough-file-text.ts +3 -3
- package/src/core/utils/get-file-icon.ts +7 -0
- package/src/core/utils/index.ts +1 -0
- package/src/core/utils/replace-inputs-with-value.ts +12 -9
- package/src/icons/DocumentJavaIcon/DocumentJavaIcon.tsx +33 -0
- package/src/icons/DocumentJavaIcon/index.ts +1 -0
- package/src/icons/DocumentPythonIcon/DocumentPythonIcon.tsx +37 -0
- package/src/icons/DocumentPythonIcon/index.ts +1 -0
- package/src/icons/DocumentShellIcon/DocumentShellIcon.tsx +33 -0
- package/src/icons/DocumentShellIcon/index.ts +1 -0
- package/src/icons/__tests__/IconTestUtils.tsx +31 -0
- package/src/layouts/CodeWalkthroughLayout.tsx +5 -1
- package/src/markdoc/components/CodeWalkthrough/CodeContainer.tsx +28 -3
- package/src/markdoc/components/CodeWalkthrough/CodeFilters.tsx +21 -4
- package/src/markdoc/components/CodeWalkthrough/CodePanel.tsx +1 -1
- package/src/markdoc/components/CodeWalkthrough/CodePanelHeader.tsx +64 -47
- package/src/markdoc/components/CodeWalkthrough/CodePanelPreview.tsx +1 -1
- package/src/markdoc/components/CodeWalkthrough/CodePanelToolbar.tsx +1 -1
- package/src/markdoc/components/CodeWalkthrough/CodeStep.tsx +5 -1
- package/src/markdoc/components/CodeWalkthrough/CodeToggle.tsx +5 -5
- package/src/markdoc/components/CodeWalkthrough/CodeWalkthrough.tsx +11 -5
- package/src/markdoc/components/CodeWalkthrough/Input.tsx +8 -6
- package/src/markdoc/tags/code-walkthrough.ts +5 -0
|
@@ -27,7 +27,6 @@ exports.CodePanelHeader = CodePanelHeader;
|
|
|
27
27
|
const react_1 = __importStar(require("react"));
|
|
28
28
|
const styled_components_1 = __importStar(require("styled-components"));
|
|
29
29
|
const hooks_1 = require("../../../core/hooks");
|
|
30
|
-
const utils_1 = require("../../../core/utils");
|
|
31
30
|
const OverflowMenuVerticalIcon_1 = require("../../../icons/OverflowMenuVerticalIcon/OverflowMenuVerticalIcon");
|
|
32
31
|
const Dropdown_1 = require("../../../components/Dropdown/Dropdown");
|
|
33
32
|
const DropdownMenu_1 = require("../../../components/Dropdown/DropdownMenu");
|
|
@@ -35,6 +34,7 @@ const DropdownMenuItem_1 = require("../../../components/Dropdown/DropdownMenuIte
|
|
|
35
34
|
const DownloadIcon_1 = require("../../../icons/DownloadIcon/DownloadIcon");
|
|
36
35
|
const Button_1 = require("../../../components/Button/Button");
|
|
37
36
|
function CodePanelHeader({ files, handleTabSwitch, activeTabName, onDownloadCode, }) {
|
|
37
|
+
const renderableFiles = (0, hooks_1.useRenderableFiles)(files);
|
|
38
38
|
const { useTranslate } = (0, hooks_1.useThemeHooks)();
|
|
39
39
|
const { translate } = useTranslate();
|
|
40
40
|
const tabRefs = (0, react_1.useRef)([]);
|
|
@@ -42,47 +42,49 @@ function CodePanelHeader({ files, handleTabSwitch, activeTabName, onDownloadCode
|
|
|
42
42
|
const [hiddenFiles, setHiddenFiles] = (0, react_1.useState)([]);
|
|
43
43
|
(0, react_1.useEffect)(() => {
|
|
44
44
|
const activeTab = tabRefs.current.find((tab) => (tab === null || tab === void 0 ? void 0 : tab.dataset.name) === activeTabName);
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
const tabsWrapper = tabsWrapperRef.current;
|
|
46
|
+
if (activeTab && tabsWrapper) {
|
|
47
|
+
const { left: wrapperLeft, right: wrapperRight } = tabsWrapper.getBoundingClientRect();
|
|
48
|
+
const { left: tabLeft, right: tabRight } = activeTab.getBoundingClientRect();
|
|
49
|
+
const tabHidden = tabLeft < wrapperLeft || tabRight > wrapperRight;
|
|
50
|
+
if (tabHidden) {
|
|
51
|
+
activeTab.scrollIntoView({ block: 'nearest', inline: 'nearest' });
|
|
52
|
+
}
|
|
47
53
|
}
|
|
48
|
-
}, [activeTabName]);
|
|
49
|
-
(0, react_1.useEffect)(() => {
|
|
50
54
|
const calculateHiddenFiles = () => {
|
|
51
55
|
if (!tabsWrapperRef.current)
|
|
52
56
|
return;
|
|
53
57
|
const { left: wrapperLeft, right: wrapperRight } = tabsWrapperRef.current.getBoundingClientRect();
|
|
54
|
-
const hidden =
|
|
58
|
+
const hidden = [];
|
|
59
|
+
for (let i = 0; i < renderableFiles.length; i++) {
|
|
55
60
|
const tab = tabRefs.current[i];
|
|
56
61
|
if (!tab)
|
|
57
|
-
|
|
62
|
+
continue;
|
|
58
63
|
const { left: tabLeft, right: tabRight } = tab.getBoundingClientRect();
|
|
59
|
-
|
|
60
|
-
|
|
64
|
+
const visible = tabLeft > wrapperLeft && tabRight < wrapperRight;
|
|
65
|
+
if (!visible) {
|
|
66
|
+
hidden.push(renderableFiles[i]);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
61
69
|
setHiddenFiles(hidden);
|
|
62
70
|
};
|
|
63
71
|
calculateHiddenFiles();
|
|
64
72
|
window.addEventListener('resize', calculateHiddenFiles);
|
|
65
73
|
return () => window.removeEventListener('resize', calculateHiddenFiles);
|
|
66
|
-
}, [files]);
|
|
67
|
-
const getFileTypeIcon = (0, react_1.useCallback)((basename) => {
|
|
68
|
-
var _a;
|
|
69
|
-
const extension = ((_a = basename.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
70
|
-
return (0, utils_1.getFileIconByExt)(extension);
|
|
71
|
-
}, []);
|
|
74
|
+
}, [activeTabName, files, renderableFiles]);
|
|
72
75
|
return (react_1.default.createElement(CodePanelHeaderWrapper, { "data-component-name": "Markdoc/CodeWalkthrough/CodePanelHeader" },
|
|
73
76
|
react_1.default.createElement(TabsWrapper, { ref: tabsWrapperRef },
|
|
74
|
-
react_1.default.createElement(Tabs, null,
|
|
75
|
-
const FileIcon = getFileTypeIcon(basename);
|
|
77
|
+
react_1.default.createElement(Tabs, null, renderableFiles.map(({ path, basename, FileIcon, parentFolder, isNameDuplicate, inRootDir }, i) => {
|
|
76
78
|
return (react_1.default.createElement(Tab, { ref: (el) => (tabRefs.current[i] = el), "data-name": path, active: path === activeTabName, key: i, onClick: () => handleTabSwitch(path) },
|
|
77
79
|
react_1.default.createElement(FileIcon, null),
|
|
78
|
-
basename
|
|
80
|
+
basename,
|
|
81
|
+
isNameDuplicate && !inRootDir ? react_1.default.createElement(Dirname, null, parentFolder) : null));
|
|
79
82
|
})),
|
|
80
83
|
react_1.default.createElement(Gradient, null)),
|
|
81
84
|
react_1.default.createElement(ActionBar, null,
|
|
82
85
|
hiddenFiles.length ? (react_1.default.createElement(Dropdown_1.Dropdown, { trigger: react_1.default.createElement(StyledOverflowMenuVerticalIcon, { size: "14px" }), alignment: "end" },
|
|
83
|
-
react_1.default.createElement(StyledDropdownMenu, null, hiddenFiles.map(({ path, basename }, i) => {
|
|
84
|
-
|
|
85
|
-
return (react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { active: path === activeTabName, key: i, onAction: () => handleTabSwitch(path), prefix: react_1.default.createElement(FileIcon, null), content: basename }));
|
|
86
|
+
react_1.default.createElement(StyledDropdownMenu, null, hiddenFiles.map(({ path, basename, FileIcon, isNameDuplicate, inRootDir, parentFolder }, i) => {
|
|
87
|
+
return (react_1.default.createElement(DropdownMenuItem_1.DropdownMenuItem, { active: path === activeTabName, key: i, onAction: () => handleTabSwitch(path), prefix: react_1.default.createElement(FileIcon, null), content: isNameDuplicate && !inRootDir ? `${parentFolder}/${basename}` : basename }));
|
|
86
88
|
})))) : null,
|
|
87
89
|
react_1.default.createElement(Button_1.Button, { variant: "text", icon: react_1.default.createElement(DownloadIcon_1.DownloadIcon, null), onClick: onDownloadCode, size: "small" }, translate('codeWalkthrough.download', 'Download')))));
|
|
88
90
|
}
|
|
@@ -108,13 +110,17 @@ const Gradient = styled_components_1.default.div `
|
|
|
108
110
|
`;
|
|
109
111
|
const Tabs = styled_components_1.default.div `
|
|
110
112
|
display: flex;
|
|
111
|
-
overflow-x:
|
|
113
|
+
overflow-x: hidden;
|
|
112
114
|
padding-right: var(--spacing-base);
|
|
113
115
|
|
|
114
116
|
&::-webkit-scrollbar {
|
|
115
117
|
display: none;
|
|
116
118
|
}
|
|
117
119
|
`;
|
|
120
|
+
const Dirname = styled_components_1.default.span `
|
|
121
|
+
font-size: var(--font-size-sm);
|
|
122
|
+
color: var(--text-color-description);
|
|
123
|
+
`;
|
|
118
124
|
const ActionBar = styled_components_1.default.div `
|
|
119
125
|
display: flex;
|
|
120
126
|
`;
|
|
@@ -129,7 +135,7 @@ const Tab = styled_components_1.default.button `
|
|
|
129
135
|
gap: var(--spacing-xs);
|
|
130
136
|
color: var(--text-color-secondary);
|
|
131
137
|
white-space: nowrap;
|
|
132
|
-
|
|
138
|
+
scroll-margin-right: var(--spacing-base);
|
|
133
139
|
${({ active }) => active
|
|
134
140
|
? (0, styled_components_1.css) `
|
|
135
141
|
color: var(--text-color-primary);
|
|
@@ -36,7 +36,7 @@ function CodePanelPreview({ children }) {
|
|
|
36
36
|
const [isOpen, setIsOpen] = (0, react_1.useState)(false);
|
|
37
37
|
const { useTranslate } = (0, hooks_1.useThemeHooks)();
|
|
38
38
|
const { translate } = useTranslate();
|
|
39
|
-
return (react_1.default.createElement(CodePanelPreviewWrapper,
|
|
39
|
+
return (react_1.default.createElement(CodePanelPreviewWrapper, { "data-component-name": "Markdoc/CodeWalkthrough/CodePanelPreview" },
|
|
40
40
|
react_1.default.createElement(PreviewDropdown, { onClick: () => setIsOpen(!isOpen) },
|
|
41
41
|
translate('codeWalkthrough.preview', 'Preview'),
|
|
42
42
|
isOpen ? react_1.default.createElement(ChevronUpIcon_1.ChevronUpIcon, null) : react_1.default.createElement(ChevronDownIcon_1.ChevronDownIcon, null)),
|
|
@@ -34,7 +34,7 @@ const CopyButton_1 = require("../../../components/Buttons/CopyButton");
|
|
|
34
34
|
function CodePanelToolbar({ file }) {
|
|
35
35
|
const { getFileText } = (0, react_1.useContext)(contexts_1.CodeWalkthroughControlsStateContext);
|
|
36
36
|
const fileContent = getFileText(file);
|
|
37
|
-
return (react_1.default.createElement(CodeToolbarWrapper,
|
|
37
|
+
return (react_1.default.createElement(CodeToolbarWrapper, { "data-component-name": "Markdoc/CodeWalkthrough/CodePanelToolbar" },
|
|
38
38
|
react_1.default.createElement(CopyButton_1.CopyButton, { data: fileContent, type: "compound", variant: "secondary", size: "medium" })));
|
|
39
39
|
}
|
|
40
40
|
const CodeToolbarWrapper = styled_components_1.default.div `
|
|
@@ -71,7 +71,7 @@ function CodeStep({ id, heading, stepKey, when, unless, children, }) {
|
|
|
71
71
|
}
|
|
72
72
|
const filtersElementHeight = ((_a = filtersElementRef === null || filtersElementRef === void 0 ? void 0 : filtersElementRef.current) === null || _a === void 0 ? void 0 : _a.clientHeight) || 0;
|
|
73
73
|
const navbarHeight = ((_b = document.querySelector('nav')) === null || _b === void 0 ? void 0 : _b.clientHeight) || 0;
|
|
74
|
-
setScrollMarginTop(filtersElementHeight + navbarHeight);
|
|
74
|
+
setScrollMarginTop(filtersElementHeight + navbarHeight + 10);
|
|
75
75
|
return () => {
|
|
76
76
|
if (currentCompRef) {
|
|
77
77
|
unregister(currentCompRef);
|
|
@@ -79,9 +79,12 @@ function CodeStep({ id, heading, stepKey, when, unless, children, }) {
|
|
|
79
79
|
};
|
|
80
80
|
}, [activeStep, register, unregister, filtersElementRef]);
|
|
81
81
|
if (!areConditionsMet({ when, unless })) {
|
|
82
|
+
if (isActive) {
|
|
83
|
+
setActiveStep(null);
|
|
84
|
+
}
|
|
82
85
|
return null;
|
|
83
86
|
}
|
|
84
|
-
return (react_1.default.createElement(exports.StepWrapper, { ref: compRef, isActive: isActive, scrollMarginTop: scrollMarginTop, "data-step-key": stepKey, "data-step-active": isActive, onClick: handleActivateStep, onFocus: handleActivateStep, tabIndex: 0 },
|
|
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 },
|
|
85
88
|
react_1.default.createElement(StepContent, { isActive: isActive },
|
|
86
89
|
heading ? react_1.default.createElement(StepHeading, null, heading) : null,
|
|
87
90
|
children)));
|
|
@@ -35,16 +35,16 @@ const CodeStep_1 = require("../../../markdoc/components/CodeWalkthrough/CodeStep
|
|
|
35
35
|
const Switch_1 = require("../../../components/Switch/Switch");
|
|
36
36
|
function CodeToggle(props) {
|
|
37
37
|
const { id, label, description, children } = props;
|
|
38
|
-
const {
|
|
39
|
-
const toggleState =
|
|
40
|
-
if (!(toggleState && toggleState.render)) {
|
|
38
|
+
const { getControlState, changeControlState } = (0, react_1.useContext)(contexts_1.CodeWalkthroughControlsStateContext);
|
|
39
|
+
const toggleState = getControlState(id);
|
|
40
|
+
if (!(toggleState && toggleState.render && typeof toggleState.value === 'boolean')) {
|
|
41
41
|
return null;
|
|
42
42
|
}
|
|
43
43
|
const checked = toggleState.value;
|
|
44
|
-
return (react_1.default.createElement(exports.ToggleWrapper,
|
|
44
|
+
return (react_1.default.createElement(exports.ToggleWrapper, { "data-component-name": "Markdoc/CodeWalkthrough/CodeToggle" },
|
|
45
45
|
react_1.default.createElement(ToggleContentWrapper, null,
|
|
46
46
|
react_1.default.createElement(exports.ToggleSubtitle, null,
|
|
47
|
-
react_1.default.createElement(Switch_1.Switch, { value: checked, onChange: (newValue) =>
|
|
47
|
+
react_1.default.createElement(Switch_1.Switch, { value: checked, onChange: (newValue) => changeControlState(id, newValue) }),
|
|
48
48
|
react_1.default.createElement("div", null, label)),
|
|
49
49
|
description ? (react_1.default.createElement("div", null, description.map((paragraph, idx) => (react_1.default.createElement(react_1.default.Fragment, { key: idx }, paragraph))))) : null),
|
|
50
50
|
checked ? children : null));
|
|
@@ -51,13 +51,13 @@ function CodeWalkthrough(_a) {
|
|
|
51
51
|
// This is a workaround to prevent the observer from being recreated
|
|
52
52
|
const [initialSteps] = (0, react_1.useState)([...steps]);
|
|
53
53
|
const { controlsState, stepsState, files, downloadAssociatedFiles } = (0, hooks_1.useCodeWalkthrough)(initialSteps, attributes);
|
|
54
|
-
const { activeFilters,
|
|
54
|
+
const { activeFilters, getControlState, changeControlState } = controlsState;
|
|
55
55
|
const { filtersElementRef } = stepsState;
|
|
56
56
|
return (react_1.default.createElement(contexts_1.CodeWalkthroughStepsContext.Provider, { value: stepsState },
|
|
57
57
|
react_1.default.createElement(contexts_1.CodeWalkthroughControlsStateContext.Provider, { value: controlsState },
|
|
58
|
-
react_1.default.createElement(CodeWalkthroughWrapper, { className: "code-walkthrough" },
|
|
58
|
+
react_1.default.createElement(CodeWalkthroughWrapper, { className: "code-walkthrough", "data-component-name": "Markdoc/CodeWalkthrough/CodeWalkthrough" },
|
|
59
59
|
react_1.default.createElement(DocsPanel, null,
|
|
60
|
-
react_1.default.createElement(CodeFilters_1.CodeFilters, { filters: activeFilters, getFilterState:
|
|
60
|
+
react_1.default.createElement(CodeFilters_1.CodeFilters, { filters: activeFilters, getFilterState: getControlState, handleFilterSelect: changeControlState, filtersElementRef: filtersElementRef }),
|
|
61
61
|
react_1.default.createElement(ContentWrapper, null, children)),
|
|
62
62
|
react_1.default.createElement(CodePanel_1.CodePanel, { files: files, downloadAssociatedFiles: downloadAssociatedFiles, preview: preview })))));
|
|
63
63
|
}
|
|
@@ -34,12 +34,12 @@ const contexts_1 = require("../../../core/contexts");
|
|
|
34
34
|
const DEBOUNCE_TIME = 500;
|
|
35
35
|
function Input(props) {
|
|
36
36
|
const { id, label, placeholder } = props;
|
|
37
|
-
const {
|
|
38
|
-
const inputState =
|
|
37
|
+
const { getControlState, changeControlState } = (0, react_1.useContext)(contexts_1.CodeWalkthroughControlsStateContext);
|
|
38
|
+
const inputState = getControlState(id);
|
|
39
39
|
const [value, setValue] = (0, react_1.useState)((inputState === null || inputState === void 0 ? void 0 : inputState.value) || '');
|
|
40
40
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
41
41
|
const debouncedSave = (0, react_1.useCallback)((0, lodash_debounce_1.default)((id, value) => {
|
|
42
|
-
|
|
42
|
+
changeControlState(id, value);
|
|
43
43
|
}, DEBOUNCE_TIME), []);
|
|
44
44
|
if (!(inputState === null || inputState === void 0 ? void 0 : inputState.render)) {
|
|
45
45
|
return null;
|
|
@@ -49,14 +49,15 @@ function Input(props) {
|
|
|
49
49
|
setValue(inputValue);
|
|
50
50
|
debouncedSave(id, inputValue);
|
|
51
51
|
};
|
|
52
|
-
return (react_1.default.createElement(InputWrapper,
|
|
52
|
+
return (react_1.default.createElement(InputWrapper, { "data-component-name": "Markdoc/CodeWalkthrough/Input" },
|
|
53
53
|
label && react_1.default.createElement(Label, null, label),
|
|
54
54
|
react_1.default.createElement(StyledInput, { id: id, value: value, onChange: handleChange, "aria-label": label, placeholder: placeholder })));
|
|
55
55
|
}
|
|
56
56
|
const InputWrapper = styled_components_1.default.div `
|
|
57
57
|
display: flex;
|
|
58
58
|
flex-direction: column;
|
|
59
|
-
margin: var(--
|
|
59
|
+
margin-top: var(--spacing-base);
|
|
60
|
+
margin-bottom: var(--spacing-base);
|
|
60
61
|
`;
|
|
61
62
|
const Label = styled_components_1.default.p `
|
|
62
63
|
color: var(--text-color-secondary);
|
|
@@ -64,6 +65,7 @@ const Label = styled_components_1.default.p `
|
|
|
64
65
|
line-height: var(--line-height-base);
|
|
65
66
|
font-family: var(--font-family-base);
|
|
66
67
|
font-weight: var(--font-weight-medium);
|
|
68
|
+
margin-bottom: var(--spacing-xxs) !important;
|
|
67
69
|
`;
|
|
68
70
|
const StyledInput = styled_components_1.default.input `
|
|
69
71
|
border: 1px solid var(--border-color-primary);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/theme",
|
|
3
|
-
"version": "0.48.
|
|
3
|
+
"version": "0.48.2",
|
|
4
4
|
"description": "Shared UI components lib",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"theme",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@types/jest-when": "3.5.5",
|
|
47
47
|
"@types/lodash.debounce": "4.0.9",
|
|
48
48
|
"@types/lodash.throttle": "4.1.9",
|
|
49
|
-
"@types/node": "
|
|
49
|
+
"@types/node": "22.10.5",
|
|
50
50
|
"@types/react": "18.3.9",
|
|
51
51
|
"@types/react-dom": "18.3.5",
|
|
52
52
|
"@types/styled-components": "5.1.34",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"timeago.js": "4.0.2",
|
|
87
87
|
"i18next": "22.4.15",
|
|
88
88
|
"nprogress": "0.2.0",
|
|
89
|
-
"@redocly/config": "0.20.
|
|
89
|
+
"@redocly/config": "0.20.2"
|
|
90
90
|
},
|
|
91
91
|
"scripts": {
|
|
92
92
|
"watch": "tsc -p tsconfig.build.json && (concurrently \"tsc -w -p tsconfig.build.json\" \"tsc-alias -w -p tsconfig.build.json\")",
|
|
@@ -4,7 +4,7 @@ export const datePicker = css`
|
|
|
4
4
|
--date-picker-nav-color: #000000;
|
|
5
5
|
--date-picker-tile-bg-color: var(--color-blue-2);
|
|
6
6
|
--date-picker-tile-color: var(--text-color-primary);
|
|
7
|
-
--date-picker-tile-bg-color-hover: var(--color-blue-3)
|
|
7
|
+
--date-picker-tile-bg-color-hover: var(--color-blue-3);
|
|
8
8
|
--date-picker-tile-color-hover: var(--text-color-primary);
|
|
9
9
|
--date-picker-input-width: var(--spacing-md);
|
|
10
10
|
--date-picker-invalid-input-bg-color: var(--bg-color-raised);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { useEffect } from 'react';
|
|
3
|
-
import styled from 'styled-components';
|
|
3
|
+
import styled, { css } from 'styled-components';
|
|
4
4
|
|
|
5
5
|
import type { OptionalEmailSettings, ReasonsSettingsSchema } from '@redocly/config';
|
|
6
6
|
import type { ReasonsProps } from '@redocly/theme/components/Feedback/Reasons';
|
|
@@ -161,7 +161,7 @@ export function Mood({ settings, onSubmit, className }: MoodProps): JSX.Element
|
|
|
161
161
|
return (
|
|
162
162
|
<MoodWrapper data-component-name="Feedback/Mood">
|
|
163
163
|
<StyledFormMandatoryFields>
|
|
164
|
-
<Label data-translation-key="feedback.settings.submitText">
|
|
164
|
+
<Label standAlone={true} data-translation-key="feedback.settings.submitText">
|
|
165
165
|
{submitText ||
|
|
166
166
|
translate(
|
|
167
167
|
'feedback.settings.submitText',
|
|
@@ -178,7 +178,7 @@ export function Mood({ settings, onSubmit, className }: MoodProps): JSX.Element
|
|
|
178
178
|
<MoodWrapper data-component-name="Feedback/Mood" className={className}>
|
|
179
179
|
<StyledForm onSubmit={onSubmitMoodForm}>
|
|
180
180
|
<StyledFormMandatoryFields>
|
|
181
|
-
<Label data-translation-key="feedback.settings.label">
|
|
181
|
+
<Label standAlone={true} data-translation-key="feedback.settings.label">
|
|
182
182
|
{label || translate('feedback.settings.label', 'Was this helpful?')}
|
|
183
183
|
</Label>
|
|
184
184
|
<StyledMandatoryFieldContainer>
|
|
@@ -294,12 +294,21 @@ const MoodWrapper = styled.div`
|
|
|
294
294
|
align-items: center;
|
|
295
295
|
`;
|
|
296
296
|
|
|
297
|
-
const Label = styled.h4
|
|
297
|
+
const Label = styled.h4<{ standAlone?: boolean }>`
|
|
298
298
|
font-family: var(--feedback-font-family);
|
|
299
299
|
font-weight: var(--font-weight-regular);
|
|
300
|
-
font-size: var(--feedback-
|
|
301
|
-
line-height: var(--feedback-
|
|
302
|
-
color: var(--feedback-
|
|
300
|
+
font-size: var(--feedback-font-size);
|
|
301
|
+
line-height: var(--feedback-line-height);
|
|
302
|
+
color: var(--feedback-text-color);
|
|
303
|
+
|
|
304
|
+
${({ standAlone = false }) =>
|
|
305
|
+
standAlone &&
|
|
306
|
+
css`
|
|
307
|
+
font-size: var(--feedback-header-font-size);
|
|
308
|
+
line-height: var(--feedback-header-line-height);
|
|
309
|
+
color: var(--feedback-header-text-color);
|
|
310
|
+
`}
|
|
311
|
+
|
|
303
312
|
margin: 0;
|
|
304
313
|
`;
|
|
305
314
|
|
|
@@ -153,7 +153,7 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
|
|
|
153
153
|
}
|
|
154
154
|
}}
|
|
155
155
|
>
|
|
156
|
-
{translate('search.
|
|
156
|
+
{translate('search.ai.button', 'Search with AI')}
|
|
157
157
|
</SearchAiButton>
|
|
158
158
|
) : null}
|
|
159
159
|
{showSearchFilterButton && (
|
|
@@ -236,41 +236,50 @@ export function SearchDialog({ onClose, className }: SearchDialogProps): JSX.Ele
|
|
|
236
236
|
/>
|
|
237
237
|
)}
|
|
238
238
|
</SearchDialogBody>
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
<
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
<
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
239
|
+
<SearchDialogFooter>
|
|
240
|
+
{mode === 'ai-dialog' ? (
|
|
241
|
+
<AiDisclaimer>
|
|
242
|
+
{translate(
|
|
243
|
+
'search.ai.disclaimer',
|
|
244
|
+
'AI search might provide incomplete or incorrect results. Verify important information.',
|
|
245
|
+
)}
|
|
246
|
+
</AiDisclaimer>
|
|
247
|
+
) : (
|
|
248
|
+
<>
|
|
249
|
+
<SearchShortcuts>
|
|
250
|
+
<SearchShortcut
|
|
251
|
+
data-translation-key="search.keys.navigate"
|
|
252
|
+
combination="Tab"
|
|
253
|
+
text={translate('search.keys.navigate', 'to navigate')}
|
|
254
|
+
/>
|
|
255
|
+
<SearchShortcut
|
|
256
|
+
data-translation-key="search.keys.select"
|
|
257
|
+
combination="⏎"
|
|
258
|
+
text={translate('search.keys.select', 'to select')}
|
|
259
|
+
/>
|
|
260
|
+
<SearchShortcut
|
|
261
|
+
data-translation-key="search.keys.exit"
|
|
262
|
+
combination="Esc"
|
|
263
|
+
text={translate('search.keys.exit', 'to exit')}
|
|
264
|
+
/>
|
|
265
|
+
</SearchShortcuts>
|
|
266
|
+
{isSearchLoading && (
|
|
267
|
+
<SearchLoading>
|
|
268
|
+
<SpinnerLoader size="16px" color="var(--search-input-icon-color)" />
|
|
269
|
+
{translate('search.loading', 'Loading...')}
|
|
270
|
+
</SearchLoading>
|
|
271
|
+
)}
|
|
272
|
+
<SearchCancelButton
|
|
273
|
+
data-translation-key="search.cancel"
|
|
274
|
+
variant="secondary"
|
|
275
|
+
size="small"
|
|
276
|
+
onClick={onClose}
|
|
277
|
+
>
|
|
278
|
+
{translate('search.cancel', 'Cancel')}
|
|
279
|
+
</SearchCancelButton>
|
|
280
|
+
</>
|
|
281
|
+
)}
|
|
282
|
+
</SearchDialogFooter>
|
|
274
283
|
</SearchDialogWrapper>
|
|
275
284
|
</SearchOverlay>
|
|
276
285
|
);
|
|
@@ -439,3 +448,10 @@ const SearchHeaderButtons = styled.div`
|
|
|
439
448
|
padding-left: var(--search-header-buttons-padding-left);
|
|
440
449
|
border-left: var(--search-header-buttons-border-left);
|
|
441
450
|
`;
|
|
451
|
+
|
|
452
|
+
const AiDisclaimer = styled.div`
|
|
453
|
+
font-size: var(--search-ai-disclaimer-font-size);
|
|
454
|
+
line-height: var(--search-ai-disclaimer-line-height);
|
|
455
|
+
color: var(--search-ai-disclaimer-text-color);
|
|
456
|
+
margin: 0 auto;
|
|
457
|
+
`;
|
|
@@ -176,5 +176,9 @@ export const search = css`
|
|
|
176
176
|
--search-ai-resource-tag-text-color: var(--text-color-secondary);
|
|
177
177
|
--search-ai-resource-tag-icon-color: var(--text-color-secondary);
|
|
178
178
|
|
|
179
|
+
--search-ai-disclaimer-font-size: var(--font-size-sm);
|
|
180
|
+
--search-ai-disclaimer-line-height: var(--line-height-sm);
|
|
181
|
+
--search-ai-disclaimer-text-color: var(--text-color-secondary);
|
|
182
|
+
|
|
179
183
|
// @tokens End
|
|
180
184
|
`;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
2
|
import styled, { css } from 'styled-components';
|
|
3
3
|
|
|
4
|
-
import type { ReactElement } from 'react';
|
|
4
|
+
import type { ForwardedRef, ReactElement } from 'react';
|
|
5
5
|
import type { SelectOption } from '@redocly/theme/core/types/select';
|
|
6
6
|
|
|
7
7
|
import { typedMemo } from '@redocly/theme/core/hoc/typedMemo';
|
|
@@ -14,15 +14,13 @@ export type SegmentedProps<T> = {
|
|
|
14
14
|
size?: 'regular' | 'small';
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
function SegmentedComponent<T>(
|
|
18
|
-
options,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
className = '',
|
|
22
|
-
size = 'regular',
|
|
23
|
-
}: SegmentedProps<T>): ReactElement {
|
|
17
|
+
function SegmentedComponent<T>(
|
|
18
|
+
{ options, onChange, value, className = '', size = 'regular' }: SegmentedProps<T>,
|
|
19
|
+
ref?: ForwardedRef<HTMLDivElement>,
|
|
20
|
+
): ReactElement {
|
|
24
21
|
return (
|
|
25
22
|
<SegmentedGroup
|
|
23
|
+
ref={ref}
|
|
26
24
|
data-component-name="Segmented/Segmented"
|
|
27
25
|
className={`tag-grey ${size} ${className}`}
|
|
28
26
|
role="tablist"
|
|
@@ -43,7 +41,9 @@ function SegmentedComponent<T>({
|
|
|
43
41
|
);
|
|
44
42
|
}
|
|
45
43
|
|
|
46
|
-
export const Segmented = typedMemo(SegmentedComponent)
|
|
44
|
+
export const Segmented = typedMemo(forwardRef(SegmentedComponent)) as <T>(
|
|
45
|
+
props: SegmentedProps<T> & { ref?: ForwardedRef<HTMLDivElement> },
|
|
46
|
+
) => ReactElement;
|
|
47
47
|
|
|
48
48
|
const SegmentedGroup = styled.div`
|
|
49
49
|
display: flex;
|
|
@@ -5,14 +5,8 @@ import type { WalkthroughControlsState } from '@redocly/theme/core/hooks';
|
|
|
5
5
|
export const CodeWalkthroughControlsStateContext = createContext<WalkthroughControlsState>({
|
|
6
6
|
activeFilters: [],
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
getInputState: () => null,
|
|
12
|
-
changeInputState: () => {},
|
|
13
|
-
|
|
14
|
-
getFilterState: () => null,
|
|
15
|
-
changeFilterState: () => {},
|
|
8
|
+
getControlState: () => null,
|
|
9
|
+
changeControlState: () => {},
|
|
16
10
|
|
|
17
11
|
getFileText: () => '',
|
|
18
12
|
areConditionsMet: () => false,
|