@redocly/theme 0.48.0 → 0.48.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/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/hooks/code-walkthrough/use-code-walkthrough-controls.d.ts +1 -1
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.js +10 -5
- 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/types/l10n.d.ts +1 -1
- 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-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 +1 -1
- 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 +6 -3
- package/lib/markdoc/components/CodeWalkthrough/CodeToggle.js +1 -1
- package/lib/markdoc/components/CodeWalkthrough/CodeWalkthrough.js +1 -1
- package/lib/markdoc/components/CodeWalkthrough/Input.js +4 -2
- package/lib/markdoc/tags/code-walkthrough.js +5 -0
- package/package.json +3 -3
- 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/hooks/code-walkthrough/use-code-walkthrough-controls.ts +9 -3
- 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/types/l10n.ts +3 -1
- package/src/core/utils/download-code-walkthrough.ts +14 -2
- package/src/core/utils/find-closest-common-directory.ts +51 -0
- 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 +1 -0
- package/src/markdoc/components/CodeWalkthrough/CodeFilters.tsx +19 -3
- 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 +6 -2
- package/src/markdoc/components/CodeWalkthrough/CodeToggle.tsx +1 -1
- package/src/markdoc/components/CodeWalkthrough/CodeWalkthrough.tsx +4 -1
- package/src/markdoc/components/CodeWalkthrough/Input.tsx +4 -2
- package/src/markdoc/tags/code-walkthrough.ts +5 -0
|
@@ -22,15 +22,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
26
|
exports.MOOD_STATES = void 0;
|
|
30
27
|
exports.Mood = Mood;
|
|
31
28
|
const React = __importStar(require("react"));
|
|
32
29
|
const react_1 = require("react");
|
|
33
|
-
const styled_components_1 =
|
|
30
|
+
const styled_components_1 = __importStar(require("styled-components"));
|
|
34
31
|
const Reasons_1 = require("../../components/Feedback/Reasons");
|
|
35
32
|
const hooks_1 = require("../../core/hooks");
|
|
36
33
|
const RadioCheckButtonIcon_1 = require("../../icons/RadioCheckButtonIcon/RadioCheckButtonIcon");
|
|
@@ -134,14 +131,14 @@ function Mood({ settings, onSubmit, className }) {
|
|
|
134
131
|
if (isSubmitted) {
|
|
135
132
|
return (React.createElement(MoodWrapper, { "data-component-name": "Feedback/Mood" },
|
|
136
133
|
React.createElement(StyledFormMandatoryFields, null,
|
|
137
|
-
React.createElement(Label, { "data-translation-key": "feedback.settings.submitText" }, submitText ||
|
|
134
|
+
React.createElement(Label, { standAlone: true, "data-translation-key": "feedback.settings.submitText" }, submitText ||
|
|
138
135
|
translate('feedback.settings.submitText', 'Thank you for helping improve our documentation!')),
|
|
139
136
|
React.createElement(RadioCheckButtonIcon_1.RadioCheckButtonIcon, null))));
|
|
140
137
|
}
|
|
141
138
|
return (React.createElement(MoodWrapper, { "data-component-name": "Feedback/Mood", className: className },
|
|
142
139
|
React.createElement(StyledForm, { onSubmit: onSubmitMoodForm },
|
|
143
140
|
React.createElement(StyledFormMandatoryFields, null,
|
|
144
|
-
React.createElement(Label, { "data-translation-key": "feedback.settings.label" }, label || translate('feedback.settings.label', 'Was this helpful?')),
|
|
141
|
+
React.createElement(Label, { standAlone: true, "data-translation-key": "feedback.settings.label" }, label || translate('feedback.settings.label', 'Was this helpful?')),
|
|
145
142
|
React.createElement(StyledMandatoryFieldContainer, null,
|
|
146
143
|
React.createElement(Button_1.Button, { "aria-label": MOOD_STATES.DISSATISFIED, type: "button", size: "medium", variant: score === MOOD_STATES.DISSATISFIED ? 'primary' : 'secondary', tone: score === MOOD_STATES.DISSATISFIED ? 'danger' : 'default', onClick: () => {
|
|
147
144
|
setScore(MOOD_STATES.DISSATISFIED);
|
|
@@ -189,9 +186,17 @@ const MoodWrapper = styled_components_1.default.div `
|
|
|
189
186
|
const Label = styled_components_1.default.h4 `
|
|
190
187
|
font-family: var(--feedback-font-family);
|
|
191
188
|
font-weight: var(--font-weight-regular);
|
|
192
|
-
font-size: var(--feedback-
|
|
193
|
-
line-height: var(--feedback-
|
|
194
|
-
color: var(--feedback-
|
|
189
|
+
font-size: var(--feedback-font-size);
|
|
190
|
+
line-height: var(--feedback-line-height);
|
|
191
|
+
color: var(--feedback-text-color);
|
|
192
|
+
|
|
193
|
+
${({ standAlone = false }) => standAlone &&
|
|
194
|
+
(0, styled_components_1.css) `
|
|
195
|
+
font-size: var(--feedback-header-font-size);
|
|
196
|
+
line-height: var(--feedback-header-line-height);
|
|
197
|
+
color: var(--feedback-header-text-color);
|
|
198
|
+
`}
|
|
199
|
+
|
|
195
200
|
margin: 0;
|
|
196
201
|
`;
|
|
197
202
|
const ButtonsContainer = styled_components_1.default.div `
|
|
@@ -120,7 +120,7 @@ function SearchDialog({ onClose, className }) {
|
|
|
120
120
|
setQuery('');
|
|
121
121
|
aiSearch.askQuestion(query);
|
|
122
122
|
}
|
|
123
|
-
} }, translate('search.
|
|
123
|
+
} }, translate('search.ai.button', 'Search with AI'))) : null,
|
|
124
124
|
showSearchFilterButton && (react_1.default.createElement(SearchFilterToggleButton, { icon: react_1.default.createElement(SettingsIcon_1.SettingsIcon, null), onClick: onFilterToggle }))))),
|
|
125
125
|
react_1.default.createElement(SearchDialogBody, null, mode === 'search' ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
126
126
|
react_1.default.createElement(SearchDialogBodyMainView, null,
|
|
@@ -139,7 +139,7 @@ function SearchDialog({ onClose, className }) {
|
|
|
139
139
|
react_1.default.createElement(SearchSuggestedPages_1.SearchSuggestedPages, null)))),
|
|
140
140
|
advancedSearch && mode === 'search' && isFilterOpen && (react_1.default.createElement(SearchDialogBodyFilterView, null,
|
|
141
141
|
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 }))),
|
|
142
|
-
mode === 'search'
|
|
142
|
+
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,
|
|
143
143
|
react_1.default.createElement(SearchShortcuts, null,
|
|
144
144
|
react_1.default.createElement(SearchShortcut_1.SearchShortcut, { "data-translation-key": "search.keys.navigate", combination: "Tab", text: translate('search.keys.navigate', 'to navigate') }),
|
|
145
145
|
react_1.default.createElement(SearchShortcut_1.SearchShortcut, { "data-translation-key": "search.keys.select", combination: "\u23CE", text: translate('search.keys.select', 'to select') }),
|
|
@@ -147,7 +147,7 @@ function SearchDialog({ onClose, className }) {
|
|
|
147
147
|
isSearchLoading && (react_1.default.createElement(SearchLoading, null,
|
|
148
148
|
react_1.default.createElement(SpinnerLoader_1.SpinnerLoader, { size: "16px", color: "var(--search-input-icon-color)" }),
|
|
149
149
|
translate('search.loading', 'Loading...'))),
|
|
150
|
-
react_1.default.createElement(SearchCancelButton, { "data-translation-key": "search.cancel", variant: "secondary", size: "small", onClick: onClose }, translate('search.cancel', 'Cancel')))))));
|
|
150
|
+
react_1.default.createElement(SearchCancelButton, { "data-translation-key": "search.cancel", variant: "secondary", size: "small", onClick: onClose }, translate('search.cancel', 'Cancel'))))))));
|
|
151
151
|
}
|
|
152
152
|
const SearchOverlay = styled_components_1.default.div `
|
|
153
153
|
position: fixed;
|
|
@@ -296,4 +296,10 @@ const SearchHeaderButtons = styled_components_1.default.div `
|
|
|
296
296
|
padding-left: var(--search-header-buttons-padding-left);
|
|
297
297
|
border-left: var(--search-header-buttons-border-left);
|
|
298
298
|
`;
|
|
299
|
+
const AiDisclaimer = styled_components_1.default.div `
|
|
300
|
+
font-size: var(--search-ai-disclaimer-font-size);
|
|
301
|
+
line-height: var(--search-ai-disclaimer-line-height);
|
|
302
|
+
color: var(--search-ai-disclaimer-text-color);
|
|
303
|
+
margin: 0 auto;
|
|
304
|
+
`;
|
|
299
305
|
//# sourceMappingURL=SearchDialog.js.map
|
|
@@ -178,6 +178,10 @@ exports.search = (0, styled_components_1.css) `
|
|
|
178
178
|
--search-ai-resource-tag-text-color: var(--text-color-secondary);
|
|
179
179
|
--search-ai-resource-tag-icon-color: var(--text-color-secondary);
|
|
180
180
|
|
|
181
|
+
--search-ai-disclaimer-font-size: var(--font-size-sm);
|
|
182
|
+
--search-ai-disclaimer-line-height: var(--line-height-sm);
|
|
183
|
+
--search-ai-disclaimer-text-color: var(--text-color-secondary);
|
|
184
|
+
|
|
181
185
|
// @tokens End
|
|
182
186
|
`;
|
|
183
187
|
//# sourceMappingURL=variables.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ReactElement } from 'react';
|
|
1
|
+
import type { ForwardedRef, ReactElement } from 'react';
|
|
2
2
|
import type { SelectOption } from '../../core/types/select';
|
|
3
3
|
export type SegmentedProps<T> = {
|
|
4
4
|
options: SelectOption<T>[];
|
|
@@ -7,6 +7,6 @@ export type SegmentedProps<T> = {
|
|
|
7
7
|
className?: string;
|
|
8
8
|
size?: 'regular' | 'small';
|
|
9
9
|
};
|
|
10
|
-
declare
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
export declare const Segmented: <T>(props: SegmentedProps<T> & {
|
|
11
|
+
ref?: ForwardedRef<HTMLDivElement>;
|
|
12
|
+
}) => ReactElement;
|
|
@@ -22,18 +22,15 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
26
|
exports.Segmented = void 0;
|
|
30
|
-
const react_1 =
|
|
27
|
+
const react_1 = __importStar(require("react"));
|
|
31
28
|
const styled_components_1 = __importStar(require("styled-components"));
|
|
32
29
|
const typedMemo_1 = require("../../core/hoc/typedMemo");
|
|
33
|
-
function SegmentedComponent({ options, onChange, value, className = '', size = 'regular',
|
|
34
|
-
return (react_1.default.createElement(SegmentedGroup, { "data-component-name": "Segmented/Segmented", className: `tag-grey ${size} ${className}`, role: "tablist" }, options.map((opt) => (react_1.default.createElement(SegmentedItem, { key: opt.label, role: "tab", title: opt.label, onClick: () => onChange(opt), "$isActive": value == opt.value, "$size": size }, opt.label)))));
|
|
30
|
+
function SegmentedComponent({ options, onChange, value, className = '', size = 'regular' }, ref) {
|
|
31
|
+
return (react_1.default.createElement(SegmentedGroup, { ref: ref, "data-component-name": "Segmented/Segmented", className: `tag-grey ${size} ${className}`, role: "tablist" }, options.map((opt) => (react_1.default.createElement(SegmentedItem, { key: opt.label, role: "tab", title: opt.label, onClick: () => onChange(opt), "$isActive": value == opt.value, "$size": size }, opt.label)))));
|
|
35
32
|
}
|
|
36
|
-
exports.Segmented = (0, typedMemo_1.typedMemo)(SegmentedComponent);
|
|
33
|
+
exports.Segmented = (0, typedMemo_1.typedMemo)((0, react_1.forwardRef)(SegmentedComponent));
|
|
37
34
|
const SegmentedGroup = styled_components_1.default.div `
|
|
38
35
|
display: flex;
|
|
39
36
|
background: var(--segmented-buttons-bg-color-main);
|
|
@@ -21,4 +21,5 @@ export type TagProps = {
|
|
|
21
21
|
onClose?: (event: React.MouseEvent) => void;
|
|
22
22
|
};
|
|
23
23
|
export declare function Tag({ children, color, icon, active, closable, onClick, onClose, size, borderless, withStatusDot, statusDotColor, ...otherProps }: TagProps): JSX.Element;
|
|
24
|
+
export declare const ContentWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
24
25
|
export {};
|
|
@@ -14,6 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
14
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.ContentWrapper = void 0;
|
|
17
18
|
exports.Tag = Tag;
|
|
18
19
|
const react_1 = __importDefault(require("react"));
|
|
19
20
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
@@ -23,14 +24,14 @@ function Tag(_a) {
|
|
|
23
24
|
var { children, color, icon, active, closable, onClick, onClose, size, borderless, withStatusDot, statusDotColor = 'var(--tag-status-dot-color-default)' } = _a, otherProps = __rest(_a, ["children", "color", "icon", "active", "closable", "onClick", "onClose", "size", "borderless", "withStatusDot", "statusDotColor"]);
|
|
24
25
|
return (react_1.default.createElement(TagWrapper, Object.assign({ "data-component-name": "Tag/Tag", borderless: borderless, color: color, size: size, onClick: onClick, hasCloseButton: closable }, otherProps),
|
|
25
26
|
withStatusDot ? react_1.default.createElement(StatusDot, { color: statusDotColor }) : icon ? icon : null,
|
|
26
|
-
react_1.default.createElement(ContentWrapper, null, children),
|
|
27
|
+
react_1.default.createElement(exports.ContentWrapper, null, children),
|
|
27
28
|
closable && (react_1.default.createElement(CloseButton, { onClick: (event) => {
|
|
28
29
|
onClose === null || onClose === void 0 ? void 0 : onClose(event);
|
|
29
30
|
} },
|
|
30
31
|
react_1.default.createElement(CloseIcon_1.CloseIcon, null))),
|
|
31
32
|
active && react_1.default.createElement(ActiveIcon, null)));
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
+
exports.ContentWrapper = styled_components_1.default.div `
|
|
34
35
|
display: inline-flex;
|
|
35
36
|
align-items: center;
|
|
36
37
|
justify-content: center;
|
|
@@ -19,4 +19,4 @@ export type WalkthroughControlsState = {
|
|
|
19
19
|
getFileText: (file: CodeWalkthroughFile) => string;
|
|
20
20
|
populateInputsWithValue: (node: string) => string;
|
|
21
21
|
};
|
|
22
|
-
export declare function useCodeWalkthroughControls(filters: Record<string, CodeWalkthroughFilter>, inputs: InputsMarkdocAttr, toggles: TogglesMarkdocAttr): WalkthroughControlsState;
|
|
22
|
+
export declare function useCodeWalkthroughControls(filters: Record<string, CodeWalkthroughFilter>, inputs: InputsMarkdocAttr, toggles: TogglesMarkdocAttr, enableDeepLink: boolean): WalkthroughControlsState;
|
|
@@ -9,14 +9,14 @@ const defaultControlsValues = {
|
|
|
9
9
|
toggle: false,
|
|
10
10
|
filter: '',
|
|
11
11
|
};
|
|
12
|
-
function useCodeWalkthroughControls(filters, inputs, toggles) {
|
|
12
|
+
function useCodeWalkthroughControls(filters, inputs, toggles, enableDeepLink) {
|
|
13
13
|
const location = (0, react_router_dom_1.useLocation)();
|
|
14
14
|
const navigate = (0, react_router_dom_1.useNavigate)();
|
|
15
15
|
const searchParams = (0, react_1.useMemo)(() => new URLSearchParams(location.search), [location.search]);
|
|
16
16
|
const [togglesState, setTogglesState] = (0, react_1.useState)(() => {
|
|
17
17
|
const initialState = {};
|
|
18
18
|
for (const [id, toggle] of Object.entries(toggles)) {
|
|
19
|
-
initialState[id] = Object.assign(Object.assign({}, toggle), { render: true, type: 'toggle', value: searchParams.get(id) === 'true' });
|
|
19
|
+
initialState[id] = Object.assign(Object.assign({}, toggle), { render: true, type: 'toggle', value: enableDeepLink ? searchParams.get(id) === 'true' : false });
|
|
20
20
|
}
|
|
21
21
|
return initialState;
|
|
22
22
|
});
|
|
@@ -44,9 +44,10 @@ function useCodeWalkthroughControls(filters, inputs, toggles) {
|
|
|
44
44
|
}
|
|
45
45
|
};
|
|
46
46
|
const [inputsState, setInputsState] = (0, react_1.useState)(() => {
|
|
47
|
+
var _a;
|
|
47
48
|
const initialState = {};
|
|
48
49
|
for (const [id, input] of Object.entries(inputs)) {
|
|
49
|
-
initialState[id] = Object.assign(Object.assign({}, input), { render: true, type: 'input', value: searchParams.get(id)
|
|
50
|
+
initialState[id] = Object.assign(Object.assign({}, input), { render: true, type: 'input', value: enableDeepLink ? ((_a = searchParams.get(id)) !== null && _a !== void 0 ? _a : input.value) : input.value });
|
|
50
51
|
}
|
|
51
52
|
return initialState;
|
|
52
53
|
});
|
|
@@ -74,10 +75,11 @@ function useCodeWalkthroughControls(filters, inputs, toggles) {
|
|
|
74
75
|
}
|
|
75
76
|
};
|
|
76
77
|
const [filtersState, setFiltersState] = (0, react_1.useState)(() => {
|
|
77
|
-
var _a, _b;
|
|
78
|
+
var _a, _b, _c;
|
|
78
79
|
const initialState = {};
|
|
79
80
|
for (const [id, filter] of Object.entries(filters)) {
|
|
80
|
-
|
|
81
|
+
const defaultValue = ((_b = (_a = filter === null || filter === void 0 ? void 0 : filter.items) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.value) || '';
|
|
82
|
+
initialState[id] = Object.assign(Object.assign({}, filter), { render: true, type: 'filter', value: enableDeepLink ? ((_c = searchParams.get(id)) !== null && _c !== void 0 ? _c : defaultValue) : defaultValue });
|
|
81
83
|
}
|
|
82
84
|
return initialState;
|
|
83
85
|
});
|
|
@@ -157,6 +159,9 @@ function useCodeWalkthroughControls(filters, inputs, toggles) {
|
|
|
157
159
|
* Update the URL search params with the current state of the filters and inputs
|
|
158
160
|
*/
|
|
159
161
|
(0, react_1.useEffect)(() => {
|
|
162
|
+
if (!enableDeepLink) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
160
165
|
const newSearchParams = new URLSearchParams(Array.from(searchParams.entries()));
|
|
161
166
|
for (const [id, { value }] of Object.entries(state)) {
|
|
162
167
|
if (value) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { CodeWalkthroughStepAttr } from '@redocly/config';
|
|
2
2
|
type ActiveStep = string | null;
|
|
3
3
|
type CodeWalkthroughStep = CodeWalkthroughStepAttr & {
|
|
4
|
-
active?: boolean;
|
|
5
4
|
compRef?: HTMLElement;
|
|
6
5
|
};
|
|
7
6
|
export type WalkthroughStepsState = {
|
|
@@ -12,5 +11,5 @@ export type WalkthroughStepsState = {
|
|
|
12
11
|
lockObserver?: React.MutableRefObject<boolean>;
|
|
13
12
|
filtersElementRef?: React.RefObject<HTMLDivElement>;
|
|
14
13
|
};
|
|
15
|
-
export declare function useCodeWalkthroughSteps(steps: CodeWalkthroughStep[]): WalkthroughStepsState;
|
|
14
|
+
export declare function useCodeWalkthroughSteps(steps: CodeWalkthroughStep[], enableDeepLink: boolean): WalkthroughStepsState;
|
|
16
15
|
export {};
|
|
@@ -5,7 +5,7 @@ const react_1 = require("react");
|
|
|
5
5
|
const react_router_dom_1 = require("react-router-dom");
|
|
6
6
|
const utils_1 = require("../../../core/utils");
|
|
7
7
|
const constants_1 = require("../../../core/constants");
|
|
8
|
-
function useCodeWalkthroughSteps(steps) {
|
|
8
|
+
function useCodeWalkthroughSteps(steps, enableDeepLink) {
|
|
9
9
|
const location = (0, react_router_dom_1.useLocation)();
|
|
10
10
|
const navigate = (0, react_router_dom_1.useNavigate)();
|
|
11
11
|
const searchParams = (0, react_1.useMemo)(() => new URLSearchParams(location.search), [location.search]);
|
|
@@ -14,7 +14,7 @@ function useCodeWalkthroughSteps(steps) {
|
|
|
14
14
|
const lockObserver = (0, react_1.useRef)(false);
|
|
15
15
|
// Track observed elements in case new observer needs to be created
|
|
16
16
|
const observedElementsRef = (0, react_1.useRef)(new Set());
|
|
17
|
-
const [activeStep, setActiveStep] = (0, react_1.useState)(searchParams.get(constants_1.ACTIVE_STEP_QUERY_PARAM));
|
|
17
|
+
const [activeStep, setActiveStep] = (0, react_1.useState)(enableDeepLink ? searchParams.get(constants_1.ACTIVE_STEP_QUERY_PARAM) : null);
|
|
18
18
|
const register = (0, react_1.useCallback)((element) => {
|
|
19
19
|
// for some reason, the observer is not ready immediately
|
|
20
20
|
setTimeout(() => {
|
|
@@ -43,27 +43,29 @@ function useCodeWalkthroughSteps(steps) {
|
|
|
43
43
|
if (lockObserver.current) {
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
|
-
const
|
|
46
|
+
const renderedSteps = steps.filter((step) => Boolean(step.compRef));
|
|
47
|
+
if (renderedSteps.length < 2) {
|
|
48
|
+
setActiveStep(((_a = renderedSteps[0]) === null || _a === void 0 ? void 0 : _a.id) || null);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
47
51
|
for (const entry of entries) {
|
|
48
|
-
const
|
|
49
|
-
const stepKey = Number((_a = target === null || target === void 0 ? void 0 : target.dataset) === null || _a === void 0 ? void 0 : _a.stepKey);
|
|
50
|
-
const stepActive = ((_b = target === null || target === void 0 ? void 0 : target.dataset) === null || _b === void 0 ? void 0 : _b.stepActive) === 'true';
|
|
52
|
+
const stepKey = Number((_c = (_b = entry.target) === null || _b === void 0 ? void 0 : _b.dataset) === null || _c === void 0 ? void 0 : _c.stepKey);
|
|
51
53
|
if (!Number.isInteger(stepKey) || stepKey < 0) {
|
|
52
54
|
continue;
|
|
53
55
|
}
|
|
56
|
+
const { intersectionRatio, boundingClientRect, rootBounds, isIntersecting } = entry;
|
|
54
57
|
const step = steps[stepKey];
|
|
55
|
-
step.active = stepActive;
|
|
56
|
-
stepsEntries.push(entry);
|
|
57
|
-
}
|
|
58
|
-
for (const stepEntry of stepsEntries) {
|
|
59
|
-
const { target, intersectionRatio, boundingClientRect, rootBounds, isIntersecting } = stepEntry;
|
|
60
|
-
const stepKey = Number((_c = target === null || target === void 0 ? void 0 : target.dataset) === null || _c === void 0 ? void 0 : _c.stepKey);
|
|
61
|
-
const step = steps[stepKey];
|
|
62
|
-
const renderedSteps = steps.filter((step) => Boolean(step.compRef));
|
|
63
58
|
const stepIndex = renderedSteps.findIndex((renderedStep) => renderedStep.stepKey === step.stepKey);
|
|
64
59
|
const { next } = (0, utils_1.getAdjacentValues)(renderedSteps, stepIndex);
|
|
65
60
|
const intersectionAtTop = (rootBounds === null || rootBounds === void 0 ? void 0 : rootBounds.bottom) !== undefined && boundingClientRect.top < rootBounds.top;
|
|
66
61
|
const stepGoesIn = isIntersecting;
|
|
62
|
+
if (intersectionRatio > 0.8 &&
|
|
63
|
+
intersectionRatio < 1 &&
|
|
64
|
+
intersectionAtTop &&
|
|
65
|
+
activeStep === null) {
|
|
66
|
+
setActiveStep(step.id);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
67
69
|
if (intersectionRatio < 1 && intersectionRatio !== 0 && intersectionAtTop) {
|
|
68
70
|
let newStep = null;
|
|
69
71
|
if (stepGoesIn) {
|
|
@@ -84,7 +86,7 @@ function useCodeWalkthroughSteps(steps) {
|
|
|
84
86
|
const filtersElementHeight = ((_a = filtersElementRef.current) === null || _a === void 0 ? void 0 : _a.clientHeight) || 0;
|
|
85
87
|
const navbarHeight = ((_b = document.querySelector('nav')) === null || _b === void 0 ? void 0 : _b.clientHeight) || 0;
|
|
86
88
|
const newObserver = new IntersectionObserver(observerCallback, {
|
|
87
|
-
threshold: [0.8],
|
|
89
|
+
threshold: [0.8, 0.85, 0.9, 0.95],
|
|
88
90
|
rootMargin: `-${filtersElementHeight + navbarHeight}px 0px 0px 0px`,
|
|
89
91
|
});
|
|
90
92
|
for (const observedElement of observedElementsRef.current) {
|
|
@@ -98,6 +100,9 @@ function useCodeWalkthroughSteps(steps) {
|
|
|
98
100
|
* Update the URL search params with the current state of the filters and inputs
|
|
99
101
|
*/
|
|
100
102
|
(0, react_1.useEffect)(() => {
|
|
103
|
+
if (!enableDeepLink) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
101
106
|
const newSearchParams = new URLSearchParams(Array.from(searchParams.entries()));
|
|
102
107
|
if (activeStep) {
|
|
103
108
|
newSearchParams.set(constants_1.ACTIVE_STEP_QUERY_PARAM, activeStep);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CodeWalkthroughFile, CodeWalkthroughStepAttr, CodeWalkthroughAttr } from '@redocly/config';
|
|
2
2
|
import { type WalkthroughControlsState, type WalkthroughStepsState } from '../../../core/hooks';
|
|
3
3
|
export type WalkthroughState = {
|
|
4
4
|
stepsState: WalkthroughStepsState;
|
|
@@ -6,9 +6,4 @@ export type WalkthroughState = {
|
|
|
6
6
|
downloadAssociatedFiles: CodeWalkthroughFile[];
|
|
7
7
|
files: CodeWalkthroughFile[];
|
|
8
8
|
};
|
|
9
|
-
export declare function useCodeWalkthrough(steps: CodeWalkthroughStepAttr[], attributes:
|
|
10
|
-
filters: Record<string, CodeWalkthroughFilter>;
|
|
11
|
-
filesets: CodeWalkthroughFileset[];
|
|
12
|
-
inputs: InputsMarkdocAttr;
|
|
13
|
-
toggles: TogglesMarkdocAttr;
|
|
14
|
-
}): WalkthroughState;
|
|
9
|
+
export declare function useCodeWalkthrough(steps: CodeWalkthroughStepAttr[], attributes: Omit<CodeWalkthroughAttr, 'steps' | 'preview'>): WalkthroughState;
|
|
@@ -3,9 +3,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.useCodeWalkthrough = useCodeWalkthrough;
|
|
4
4
|
const hooks_1 = require("../../../core/hooks");
|
|
5
5
|
function useCodeWalkthrough(steps, attributes) {
|
|
6
|
-
const { filters, filesets, inputs, toggles } = attributes;
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
const { filters, filesets, inputs, toggles, __idx } = attributes;
|
|
7
|
+
/*
|
|
8
|
+
We only enable deep linking for the first CodeWalkthrough,
|
|
9
|
+
because we don't expect more than one on the same page.
|
|
10
|
+
Any subsequent walkthroughs have it disabled to avoid
|
|
11
|
+
collisions/conflicts in the URL.
|
|
12
|
+
*/
|
|
13
|
+
const enableDeepLink = __idx === 1;
|
|
14
|
+
const stepsState = (0, hooks_1.useCodeWalkthroughSteps)(steps, enableDeepLink);
|
|
15
|
+
const controlsState = (0, hooks_1.useCodeWalkthroughControls)(filters, inputs, toggles, enableDeepLink);
|
|
9
16
|
const files = filesets
|
|
10
17
|
.filter((fileset) => controlsState.areConditionsMet(fileset))
|
|
11
18
|
.flatMap((fileset) => fileset.files || []);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { CodeWalkthroughFile } from '@redocly/config';
|
|
2
|
+
import type { IconProps } from '../../../icons/types';
|
|
3
|
+
export type RenderableFile = CodeWalkthroughFile & {
|
|
4
|
+
FileIcon: React.FunctionComponent<IconProps>;
|
|
5
|
+
parentFolder: string;
|
|
6
|
+
isNameDuplicate: boolean;
|
|
7
|
+
inRootDir: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare function useRenderableFiles(files: CodeWalkthroughFile[]): RenderableFile[];
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useRenderableFiles = useRenderableFiles;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const utils_1 = require("../../../core/utils");
|
|
6
|
+
function useRenderableFiles(files) {
|
|
7
|
+
return (0, react_1.useMemo)(function () {
|
|
8
|
+
const filePaths = files.map(({ path }) => path);
|
|
9
|
+
const rootDir = (0, utils_1.findClosestCommonDirectory)(filePaths);
|
|
10
|
+
const renderableFiles = files.map((file) => {
|
|
11
|
+
const FileIcon = getFileTypeIcon(file.basename);
|
|
12
|
+
const parentFolder = file.path.split('/').slice(-2, -1)[0];
|
|
13
|
+
const isNameDuplicate = files.some((_file) => file.basename === _file.basename && file.path !== _file.path);
|
|
14
|
+
const inRootDir = file.path === `${(0, utils_1.removeLeadingSlash)(rootDir)}/${file.basename}`;
|
|
15
|
+
return Object.assign(Object.assign({}, file), { FileIcon,
|
|
16
|
+
inRootDir,
|
|
17
|
+
parentFolder,
|
|
18
|
+
isNameDuplicate });
|
|
19
|
+
});
|
|
20
|
+
return renderableFiles;
|
|
21
|
+
}, [files]);
|
|
22
|
+
}
|
|
23
|
+
function getFileTypeIcon(basename) {
|
|
24
|
+
var _a;
|
|
25
|
+
const extension = ((_a = basename.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
|
|
26
|
+
return (0, utils_1.getFileIconByExt)(extension);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=use-renderable-files.js.map
|
|
@@ -32,3 +32,4 @@ export * from '../../core/hooks/code-walkthrough/use-code-walkthrough';
|
|
|
32
32
|
export * from '../../core/hooks/code-walkthrough/use-code-walkthrough-steps';
|
|
33
33
|
export * from '../../core/hooks/code-walkthrough/use-code-walkthrough-controls';
|
|
34
34
|
export * from '../../core/hooks/code-walkthrough/use-code-panel';
|
|
35
|
+
export * from '../../core/hooks/code-walkthrough/use-renderable-files';
|
package/lib/core/hooks/index.js
CHANGED
|
@@ -48,4 +48,5 @@ __exportStar(require("../../core/hooks/code-walkthrough/use-code-walkthrough"),
|
|
|
48
48
|
__exportStar(require("../../core/hooks/code-walkthrough/use-code-walkthrough-steps"), exports);
|
|
49
49
|
__exportStar(require("../../core/hooks/code-walkthrough/use-code-walkthrough-controls"), exports);
|
|
50
50
|
__exportStar(require("../../core/hooks/code-walkthrough/use-code-panel"), exports);
|
|
51
|
+
__exportStar(require("../../core/hooks/code-walkthrough/use-renderable-files"), exports);
|
|
51
52
|
//# 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.
|
|
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';
|
|
3
3
|
export type Locale = {
|
|
4
4
|
code: string;
|
|
5
5
|
name: string;
|
|
@@ -21,9 +21,17 @@ jszip_1.default.support.nodebuffer = false;
|
|
|
21
21
|
function downloadCodeWalkthrough(files, state, inputsState) {
|
|
22
22
|
return __awaiter(this, void 0, void 0, function* () {
|
|
23
23
|
const zip = new jszip_1.default();
|
|
24
|
+
const filePaths = files.map(({ path }) => path);
|
|
25
|
+
const commonClosestDirectory = (0, utils_1.findClosestCommonDirectory)(filePaths);
|
|
24
26
|
for (const file of files) {
|
|
25
27
|
const fileContent = (0, utils_1.getCodeWalkthroughFileText)(file, state, inputsState);
|
|
26
|
-
|
|
28
|
+
if (commonClosestDirectory === '/') {
|
|
29
|
+
zip.file(file.path, fileContent);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
const filePath = file.path.replace((0, utils_1.removeLeadingSlash)(`${commonClosestDirectory}/`), '');
|
|
33
|
+
zip.file(filePath, fileContent);
|
|
34
|
+
}
|
|
27
35
|
}
|
|
28
36
|
const zipContent = yield zip.generateAsync({ type: 'blob' });
|
|
29
37
|
(0, file_saver_1.saveAs)(zipContent, 'sample-code.zip');
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findClosestCommonDirectory = findClosestCommonDirectory;
|
|
4
|
+
/**
|
|
5
|
+
* Splits a file path into its directory components, removing the file name.
|
|
6
|
+
* @param path - The full file path.
|
|
7
|
+
* @returns An array of directories.
|
|
8
|
+
*/
|
|
9
|
+
function splitPath(path) {
|
|
10
|
+
const parts = path.split('/').filter(Boolean);
|
|
11
|
+
parts.pop();
|
|
12
|
+
return parts;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Finds the longest common prefix between two paths.
|
|
16
|
+
* @param path1 - The first path as an array of directories.
|
|
17
|
+
* @param path2 - The second path as an array of directories.
|
|
18
|
+
* @returns An array representing the common prefix.
|
|
19
|
+
*/
|
|
20
|
+
function findCommonPrefix(path1, path2) {
|
|
21
|
+
const common = [];
|
|
22
|
+
for (let i = 0; i < Math.min(path1.length, path2.length); i++) {
|
|
23
|
+
if (path1[i] === path2[i]) {
|
|
24
|
+
common.push(path1[i]);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return common;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Finds the closest common directory for a set of file paths.
|
|
34
|
+
* @param paths - An array of absolute file paths.
|
|
35
|
+
* @returns The closest common directory as a string.
|
|
36
|
+
*/
|
|
37
|
+
function findClosestCommonDirectory(paths) {
|
|
38
|
+
if (paths.length === 0) {
|
|
39
|
+
return '/';
|
|
40
|
+
}
|
|
41
|
+
const splitPaths = paths.map(splitPath);
|
|
42
|
+
let commonPrefix = splitPaths[0];
|
|
43
|
+
for (let i = 1; i < splitPaths.length; i++) {
|
|
44
|
+
commonPrefix = findCommonPrefix(commonPrefix, splitPaths[i]);
|
|
45
|
+
if (commonPrefix.length === 0) {
|
|
46
|
+
return '/';
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return '/' + commonPrefix.join('/');
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=find-closest-common-directory.js.map
|
|
@@ -11,6 +11,9 @@ const DocumentHtmlIcon_1 = require("../../icons/DocumentHtmlIcon/DocumentHtmlIco
|
|
|
11
11
|
const DocumentReactIcon_1 = require("../../icons/DocumentReactIcon/DocumentReactIcon");
|
|
12
12
|
const DocumentMarkdownIcon_1 = require("../../icons/DocumentMarkdownIcon/DocumentMarkdownIcon");
|
|
13
13
|
const DocumentGraphqlIcon_1 = require("../../icons/DocumentGraphqlIcon/DocumentGraphqlIcon");
|
|
14
|
+
const DocumentPythonIcon_1 = require("../../icons/DocumentPythonIcon/DocumentPythonIcon");
|
|
15
|
+
const DocumentShellIcon_1 = require("../../icons/DocumentShellIcon/DocumentShellIcon");
|
|
16
|
+
const DocumentJavaIcon_1 = require("../../icons/DocumentJavaIcon/DocumentJavaIcon");
|
|
14
17
|
const fileIconMap = {
|
|
15
18
|
yaml: DocumentYamlIcon_1.DocumentYamlIcon,
|
|
16
19
|
yml: DocumentYamlIcon_1.DocumentYamlIcon,
|
|
@@ -24,6 +27,9 @@ const fileIconMap = {
|
|
|
24
27
|
md: DocumentMarkdownIcon_1.DocumentMarkdownIcon,
|
|
25
28
|
graphql: DocumentGraphqlIcon_1.DocumentGraphqlIcon,
|
|
26
29
|
gql: DocumentGraphqlIcon_1.DocumentGraphqlIcon,
|
|
30
|
+
py: DocumentPythonIcon_1.DocumentPythonIcon,
|
|
31
|
+
sh: DocumentShellIcon_1.DocumentShellIcon,
|
|
32
|
+
java: DocumentJavaIcon_1.DocumentJavaIcon,
|
|
27
33
|
};
|
|
28
34
|
function getFileIconByExt(ext) {
|
|
29
35
|
return fileIconMap[ext] || DocumentBlankIcon_1.DocumentBlankIcon;
|
|
@@ -30,3 +30,4 @@ export * from '../../core/utils/download-code-walkthrough';
|
|
|
30
30
|
export * from '../../core/utils/get-file-icon';
|
|
31
31
|
export * from '../../core/utils/match-code-walkthrough-conditions';
|
|
32
32
|
export * from '../../core/utils/replace-inputs-with-value';
|
|
33
|
+
export * from '../../core/utils/find-closest-common-directory';
|
package/lib/core/utils/index.js
CHANGED
|
@@ -46,4 +46,5 @@ __exportStar(require("../../core/utils/download-code-walkthrough"), exports);
|
|
|
46
46
|
__exportStar(require("../../core/utils/get-file-icon"), exports);
|
|
47
47
|
__exportStar(require("../../core/utils/match-code-walkthrough-conditions"), exports);
|
|
48
48
|
__exportStar(require("../../core/utils/replace-inputs-with-value"), exports);
|
|
49
|
+
__exportStar(require("../../core/utils/find-closest-common-directory"), exports);
|
|
49
50
|
//# sourceMappingURL=index.js.map
|