@redocly/theme 0.65.0-next.4 → 0.65.0-next.5
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/Button/Button.d.ts +1 -0
- package/lib/components/Button/Button.js +14 -2
- package/lib/components/Dropdown/DropdownMenuItem.js +18 -6
- package/lib/components/LanguagePicker/LanguagePicker.js +3 -2
- package/lib/components/UserMenu/LoginButton.js +1 -1
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.d.ts +0 -11
- package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.js +7 -2
- package/lib/core/hooks/use-language-picker.d.ts +6 -1
- package/lib/core/hooks/use-language-picker.js +10 -2
- package/lib/markdoc/components/CodeWalkthrough/CodeStep.js +8 -7
- package/package.json +2 -2
- package/src/components/Button/Button.tsx +9 -2
- package/src/components/Dropdown/DropdownMenuItem.tsx +27 -27
- package/src/components/LanguagePicker/LanguagePicker.tsx +3 -2
- package/src/components/UserMenu/LoginButton.tsx +1 -0
- package/src/core/hooks/code-walkthrough/use-code-walkthrough-steps.ts +10 -2
- package/src/core/hooks/use-language-picker.ts +33 -8
- package/src/markdoc/components/CodeWalkthrough/CodeStep.tsx +7 -8
|
@@ -32,6 +32,17 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
36
|
+
var t = {};
|
|
37
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
38
|
+
t[p] = s[p];
|
|
39
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
40
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
41
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
42
|
+
t[p[i]] = s[p[i]];
|
|
43
|
+
}
|
|
44
|
+
return t;
|
|
45
|
+
};
|
|
35
46
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
47
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
48
|
};
|
|
@@ -166,13 +177,14 @@ const StyledButton = styled_components_1.default.button.attrs((props) => ({
|
|
|
166
177
|
`}
|
|
167
178
|
`;
|
|
168
179
|
const ButtonComponent = (props) => {
|
|
180
|
+
const { languageInsensitive } = props, buttonProps = __rest(props, ["languageInsensitive"]);
|
|
169
181
|
const tabIndex = 'tabIndex' in props ? props.tabIndex : props.to ? -1 : undefined;
|
|
170
|
-
const button = (react_1.default.createElement(StyledButton, Object.assign({ "data-component-name": "Button/Button" },
|
|
182
|
+
const button = (react_1.default.createElement(StyledButton, Object.assign({ "data-component-name": "Button/Button" }, buttonProps, { iconOnly: !props.children && props.icon !== null, tabIndex: tabIndex }),
|
|
171
183
|
props.icon && props.iconPosition !== 'right' && props.icon,
|
|
172
184
|
props.children,
|
|
173
185
|
props.icon && props.iconPosition === 'right' && props.icon));
|
|
174
186
|
if (props.to) {
|
|
175
|
-
return (react_1.default.createElement(StyledButtonLink, { to: props.to, external: props.external, onClick: props.onClick }, button));
|
|
187
|
+
return (react_1.default.createElement(StyledButtonLink, { to: props.to, external: props.external, languageInsensitive: languageInsensitive, onClick: props.onClick }, button));
|
|
176
188
|
}
|
|
177
189
|
else {
|
|
178
190
|
return button;
|
|
@@ -62,13 +62,25 @@ function DropdownMenuItem(_a) {
|
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
64
|
className = className || '' + (active ? ' active' : '');
|
|
65
|
+
const sharedProps = {
|
|
66
|
+
$active: active,
|
|
67
|
+
$dangerous: dangerous,
|
|
68
|
+
$disabled: disabled,
|
|
69
|
+
$separator: separator,
|
|
70
|
+
$separatorLine: separatorLine,
|
|
71
|
+
'data-component-name': 'Dropdown/DropdownMenuItem',
|
|
72
|
+
className,
|
|
73
|
+
onClick: handleClick,
|
|
74
|
+
role,
|
|
75
|
+
style,
|
|
76
|
+
};
|
|
65
77
|
if (to) {
|
|
66
|
-
return (react_1.default.createElement(DropdownMenuItemWrapper, Object.assign({ as: Link_1.Link,
|
|
78
|
+
return (react_1.default.createElement(DropdownMenuItemWrapper, Object.assign({ as: Link_1.Link, to: to }, sharedProps, dataAttributes, otherProps),
|
|
67
79
|
prefix,
|
|
68
80
|
children,
|
|
69
81
|
suffix));
|
|
70
82
|
}
|
|
71
|
-
return (react_1.default.createElement(DropdownMenuItemWrapper, Object.assign({
|
|
83
|
+
return (react_1.default.createElement(DropdownMenuItemWrapper, Object.assign({}, sharedProps, dataAttributes, { onKeyDown: handleKeyDown, tabIndex: onAction ? 0 : -1 }),
|
|
72
84
|
prefix,
|
|
73
85
|
children || content,
|
|
74
86
|
suffix));
|
|
@@ -109,7 +121,7 @@ const DropdownMenuItemWrapper = styled_components_1.default.li `
|
|
|
109
121
|
color: var(--dropdown-menu-item-color-hover);
|
|
110
122
|
}
|
|
111
123
|
|
|
112
|
-
${({ separator }) => separator &&
|
|
124
|
+
${({ $separator }) => $separator &&
|
|
113
125
|
(0, styled_components_1.css) `
|
|
114
126
|
cursor: default;
|
|
115
127
|
pointer-events: none;
|
|
@@ -119,7 +131,7 @@ const DropdownMenuItemWrapper = styled_components_1.default.li `
|
|
|
119
131
|
--dropdown-menu-item-bg-color-hover: var(--dropdown-menu-item-bg-color);
|
|
120
132
|
`}
|
|
121
133
|
|
|
122
|
-
${({ active }) => active &&
|
|
134
|
+
${({ $active }) => $active &&
|
|
123
135
|
(0, styled_components_1.css) `
|
|
124
136
|
background-color: var(--dropdown-menu-item-bg-color-active);
|
|
125
137
|
color: var(--dropdown-menu-item-color-active);
|
|
@@ -128,7 +140,7 @@ const DropdownMenuItemWrapper = styled_components_1.default.li `
|
|
|
128
140
|
}
|
|
129
141
|
`}
|
|
130
142
|
|
|
131
|
-
${({ disabled }) => disabled &&
|
|
143
|
+
${({ $disabled }) => $disabled &&
|
|
132
144
|
(0, styled_components_1.css) `
|
|
133
145
|
cursor: default;
|
|
134
146
|
pointer-events: none;
|
|
@@ -152,7 +164,7 @@ const DropdownMenuItemWrapper = styled_components_1.default.li `
|
|
|
152
164
|
}
|
|
153
165
|
`}
|
|
154
166
|
|
|
155
|
-
${({ dangerous }) => dangerous &&
|
|
167
|
+
${({ $dangerous }) => $dangerous &&
|
|
156
168
|
(0, styled_components_1.css) `
|
|
157
169
|
&:hover,
|
|
158
170
|
& {
|
|
@@ -14,7 +14,7 @@ const Button_1 = require("../../components/Button/Button");
|
|
|
14
14
|
const Dropdown_1 = require("../../components/Dropdown/Dropdown");
|
|
15
15
|
const CheckmarkIcon_1 = require("../../icons/CheckmarkIcon/CheckmarkIcon");
|
|
16
16
|
function LanguagePicker(props) {
|
|
17
|
-
const { currentLocale, locales,
|
|
17
|
+
const { currentLocale, locales, getLocaleUrl } = (0, hooks_1.useLanguagePicker)();
|
|
18
18
|
const { useTelemetry } = (0, hooks_1.useThemeHooks)();
|
|
19
19
|
const telemetry = useTelemetry();
|
|
20
20
|
if (locales.length < 2 || !currentLocale) {
|
|
@@ -23,8 +23,9 @@ function LanguagePicker(props) {
|
|
|
23
23
|
const languagePickerButton = (react_1.default.createElement(Button_1.Button, { icon: react_1.default.createElement(GlobalOutlinedIcon_1.GlobalOutlinedIcon, { color: "--button-content-color" }), variant: "secondary", size: "medium" }));
|
|
24
24
|
const languageItems = locales.map((locale) => ({
|
|
25
25
|
content: locale.name || locale.code || '',
|
|
26
|
+
to: getLocaleUrl(locale.code),
|
|
27
|
+
languageInsensitive: true,
|
|
26
28
|
onAction: () => {
|
|
27
|
-
setLocale(locale.code);
|
|
28
29
|
props.onChangeLanguage(locale.code);
|
|
29
30
|
telemetry.sendLanguagePickerLocaleChangedMessage([{ object: 'locale', locale: locale.code }]);
|
|
30
31
|
},
|
|
@@ -13,6 +13,6 @@ function LoginButton({ href, className, variant = 'primary', size = 'medium', la
|
|
|
13
13
|
const telemetry = useTelemetry();
|
|
14
14
|
const buttonLabel = label || translate(labelTranslationKey, 'Login');
|
|
15
15
|
return (react_1.default.createElement("span", { "data-component-name": componentName, className: className },
|
|
16
|
-
react_1.default.createElement(Button_1.Button, { "data-translation-key": label ? undefined : labelTranslationKey, to: href, onClick: () => telemetry.sendLoginButtonClickedMessage(), "data-testid": "login-btn", extraClass: className, variant: variant, size: size }, buttonLabel)));
|
|
16
|
+
react_1.default.createElement(Button_1.Button, { "data-translation-key": label ? undefined : labelTranslationKey, to: href, languageInsensitive: true, onClick: () => telemetry.sendLoginButtonClickedMessage(), "data-testid": "login-btn", extraClass: className, variant: variant, size: size }, buttonLabel)));
|
|
17
17
|
}
|
|
18
18
|
//# sourceMappingURL=LoginButton.js.map
|
|
@@ -10,15 +10,4 @@ type Params = {
|
|
|
10
10
|
root: React.RefObject<HTMLDivElement | null>;
|
|
11
11
|
};
|
|
12
12
|
export declare function useCodeWalkthroughSteps({ steps, enableDeepLink, root, }: Params): WalkthroughStepsState;
|
|
13
|
-
type StepsGroup = {
|
|
14
|
-
freeSpace: number;
|
|
15
|
-
usedSpace: number;
|
|
16
|
-
offset: number;
|
|
17
|
-
steps: {
|
|
18
|
-
offset: number;
|
|
19
|
-
height: number;
|
|
20
|
-
ref?: HTMLElement;
|
|
21
|
-
}[];
|
|
22
|
-
};
|
|
23
|
-
export declare function getGroupMarkers(group: StepsGroup): number[];
|
|
24
13
|
export {};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.useCodeWalkthroughSteps = useCodeWalkthroughSteps;
|
|
4
|
-
exports.getGroupMarkers = getGroupMarkers;
|
|
5
4
|
const react_1 = require("react");
|
|
6
5
|
const react_router_dom_1 = require("react-router-dom");
|
|
7
6
|
const js_utils_1 = require("../../utils/js-utils");
|
|
@@ -97,7 +96,7 @@ function useCodeWalkthroughSteps({ steps, enableDeepLink, root, }) {
|
|
|
97
96
|
return;
|
|
98
97
|
}
|
|
99
98
|
step.compRef = element;
|
|
100
|
-
setVisibleSteps((prevSteps) => (
|
|
99
|
+
setVisibleSteps((prevSteps) => insertVisibleStepInOrder(prevSteps, step));
|
|
101
100
|
}, [stepsMap]);
|
|
102
101
|
const removeStep = (0, react_1.useCallback)((stepId) => {
|
|
103
102
|
const step = stepsMap.get(stepId);
|
|
@@ -315,4 +314,10 @@ function getNormalizedNumber(options) {
|
|
|
315
314
|
const { min, max, value } = options;
|
|
316
315
|
return (value - min) / (max - min);
|
|
317
316
|
}
|
|
317
|
+
function insertVisibleStepInOrder(visible, step) {
|
|
318
|
+
const others = visible.filter((s) => s.id !== step.id);
|
|
319
|
+
const laterAt = others.findIndex((s) => s.index > step.index);
|
|
320
|
+
const at = laterAt === -1 ? others.length : laterAt;
|
|
321
|
+
return (0, js_utils_1.insertAt)(others, at, step);
|
|
322
|
+
}
|
|
318
323
|
//# sourceMappingURL=use-code-walkthrough-steps.js.map
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { L10nConfig } from '../types/hooks';
|
|
2
|
-
export
|
|
2
|
+
export type UseLanguagePickerResult = {
|
|
3
3
|
currentLocale: L10nConfig['locales'][number] | undefined;
|
|
4
4
|
locales: L10nConfig['locales'];
|
|
5
|
+
getLocaleUrl: (value: string) => string;
|
|
6
|
+
/**
|
|
7
|
+
* @deprecated Use `getLocaleUrl` to build the URL for the target locale, then pass it to `<Link>`.
|
|
8
|
+
*/
|
|
5
9
|
setLocale: (value: string) => void;
|
|
6
10
|
};
|
|
11
|
+
export declare function useLanguagePicker(): UseLanguagePickerResult;
|
|
@@ -9,15 +9,23 @@ function useLanguagePicker() {
|
|
|
9
9
|
const navigate = (0, react_router_dom_1.useNavigate)();
|
|
10
10
|
const loadAndNavigate = useLoadAndNavigate();
|
|
11
11
|
const { currentLocale, locales, defaultLocale } = useL10nConfig();
|
|
12
|
+
const location = (0, react_router_dom_1.useLocation)();
|
|
12
13
|
const locale = locales.find((l) => l.code === currentLocale);
|
|
14
|
+
function getLocaleUrl(value) {
|
|
15
|
+
let newLangPathname = (0, urls_1.getPathnameForLocale)((0, urls_1.withoutPathPrefix)(location.pathname), defaultLocale, value, locales);
|
|
16
|
+
if (location.search) {
|
|
17
|
+
newLangPathname += location.search;
|
|
18
|
+
}
|
|
19
|
+
return (0, urls_1.addLeadingSlash)(newLangPathname);
|
|
20
|
+
}
|
|
13
21
|
function setLocale(value) {
|
|
14
|
-
const
|
|
15
|
-
const newUrlWithLanguage = `${newLangPathname}${location.search}${location.hash}`;
|
|
22
|
+
const newUrlWithLanguage = (0, urls_1.withPathPrefix)(getLocaleUrl(value));
|
|
16
23
|
loadAndNavigate({ navigate, to: newUrlWithLanguage });
|
|
17
24
|
}
|
|
18
25
|
return {
|
|
19
26
|
currentLocale: locale,
|
|
20
27
|
locales,
|
|
28
|
+
getLocaleUrl,
|
|
21
29
|
setLocale,
|
|
22
30
|
};
|
|
23
31
|
}
|
|
@@ -40,9 +40,11 @@ exports.StepWrapper = void 0;
|
|
|
40
40
|
exports.CodeStep = CodeStep;
|
|
41
41
|
const react_1 = __importStar(require("react"));
|
|
42
42
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
43
|
+
const react_router_dom_1 = require("react-router-dom");
|
|
43
44
|
const Marker_1 = require("../../../components/Marker/Marker");
|
|
44
45
|
const contexts_1 = require("../../../core/contexts");
|
|
45
46
|
function CodeStep({ id, heading, when, unless, children, }) {
|
|
47
|
+
const location = (0, react_router_dom_1.useLocation)();
|
|
46
48
|
const compRef = (0, react_1.useRef)(null);
|
|
47
49
|
const markerRef = (0, react_1.useRef)(null);
|
|
48
50
|
const { areConditionsMet } = (0, react_1.useContext)(contexts_1.CodeWalkthroughControlsStateContext);
|
|
@@ -66,15 +68,14 @@ function CodeStep({ id, heading, when, unless, children, }) {
|
|
|
66
68
|
const handleRegisterMarker = (0, react_1.useCallback)((element) => registerMarker(id, element), [registerMarker, id]);
|
|
67
69
|
const handleRemoveMarker = (0, react_1.useCallback)((element) => removeMarker(id, element), [removeMarker, id]);
|
|
68
70
|
(0, react_1.useEffect)(() => {
|
|
69
|
-
// If the step is active during first render, scroll to it
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
71
|
+
// If the step is active during navigation or first render, scroll to it
|
|
72
|
+
if (!isActive)
|
|
73
|
+
return;
|
|
74
|
+
const timer = setTimeout(handleActivateStep, 5);
|
|
75
|
+
return () => clearTimeout(timer);
|
|
75
76
|
// Ignore dependency array because we only need to run this once
|
|
76
77
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
77
|
-
}, []);
|
|
78
|
+
}, [location.pathname]);
|
|
78
79
|
(0, react_1.useEffect)(() => {
|
|
79
80
|
var _a, _b;
|
|
80
81
|
const currentCompRef = compRef.current;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/theme",
|
|
3
|
-
"version": "0.65.0-next.
|
|
3
|
+
"version": "0.65.0-next.5",
|
|
4
4
|
"description": "Shared UI components lib",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"theme",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"vitest": "4.0.10",
|
|
64
64
|
"vitest-when": "0.6.2",
|
|
65
65
|
"webpack": "5.105.2",
|
|
66
|
-
"@redocly/realm-asyncapi-sdk": "0.11.0-next.
|
|
66
|
+
"@redocly/realm-asyncapi-sdk": "0.11.0-next.3"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
69
|
"@tanstack/react-query": "5.62.3",
|
|
@@ -28,6 +28,7 @@ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElemen
|
|
|
28
28
|
extraClass?: string;
|
|
29
29
|
to?: string;
|
|
30
30
|
external?: boolean;
|
|
31
|
+
languageInsensitive?: boolean;
|
|
31
32
|
icon?: JSX.Element;
|
|
32
33
|
iconPosition?: 'left' | 'right';
|
|
33
34
|
title?: string;
|
|
@@ -175,12 +176,13 @@ const StyledButton = styled.button.attrs((props: ButtonProps) => ({
|
|
|
175
176
|
`;
|
|
176
177
|
|
|
177
178
|
const ButtonComponent: React.FC<ButtonProps> = (props) => {
|
|
179
|
+
const { languageInsensitive, ...buttonProps } = props;
|
|
178
180
|
const tabIndex = 'tabIndex' in props ? props.tabIndex : props.to ? -1 : undefined;
|
|
179
181
|
|
|
180
182
|
const button = (
|
|
181
183
|
<StyledButton
|
|
182
184
|
data-component-name="Button/Button"
|
|
183
|
-
{...
|
|
185
|
+
{...buttonProps}
|
|
184
186
|
iconOnly={!props.children && props.icon !== null}
|
|
185
187
|
tabIndex={tabIndex}
|
|
186
188
|
>
|
|
@@ -192,7 +194,12 @@ const ButtonComponent: React.FC<ButtonProps> = (props) => {
|
|
|
192
194
|
|
|
193
195
|
if (props.to) {
|
|
194
196
|
return (
|
|
195
|
-
<StyledButtonLink
|
|
197
|
+
<StyledButtonLink
|
|
198
|
+
to={props.to}
|
|
199
|
+
external={props.external}
|
|
200
|
+
languageInsensitive={languageInsensitive}
|
|
201
|
+
onClick={props.onClick}
|
|
202
|
+
>
|
|
196
203
|
{button}
|
|
197
204
|
</StyledButtonLink>
|
|
198
205
|
);
|
|
@@ -55,16 +55,25 @@ export function DropdownMenuItem({
|
|
|
55
55
|
|
|
56
56
|
className = className || '' + (active ? ' active' : '');
|
|
57
57
|
|
|
58
|
+
const sharedProps = {
|
|
59
|
+
$active: active,
|
|
60
|
+
$dangerous: dangerous,
|
|
61
|
+
$disabled: disabled,
|
|
62
|
+
$separator: separator,
|
|
63
|
+
$separatorLine: separatorLine,
|
|
64
|
+
'data-component-name': 'Dropdown/DropdownMenuItem',
|
|
65
|
+
className,
|
|
66
|
+
onClick: handleClick,
|
|
67
|
+
role,
|
|
68
|
+
style,
|
|
69
|
+
};
|
|
70
|
+
|
|
58
71
|
if (to) {
|
|
59
72
|
return (
|
|
60
73
|
<DropdownMenuItemWrapper
|
|
61
74
|
as={Link}
|
|
62
|
-
data-component-name="Dropdown/DropdownMenuItem"
|
|
63
|
-
className={className}
|
|
64
|
-
$separatorLine={separatorLine}
|
|
65
75
|
to={to}
|
|
66
|
-
|
|
67
|
-
role={role}
|
|
76
|
+
{...sharedProps}
|
|
68
77
|
{...dataAttributes}
|
|
69
78
|
{...otherProps}
|
|
70
79
|
>
|
|
@@ -77,19 +86,10 @@ export function DropdownMenuItem({
|
|
|
77
86
|
|
|
78
87
|
return (
|
|
79
88
|
<DropdownMenuItemWrapper
|
|
80
|
-
|
|
81
|
-
className={className}
|
|
82
|
-
role={role}
|
|
83
|
-
style={style}
|
|
89
|
+
{...sharedProps}
|
|
84
90
|
{...dataAttributes}
|
|
85
|
-
onClick={handleClick}
|
|
86
91
|
onKeyDown={handleKeyDown}
|
|
87
92
|
tabIndex={onAction ? 0 : -1}
|
|
88
|
-
active={active}
|
|
89
|
-
disabled={disabled}
|
|
90
|
-
separator={separator}
|
|
91
|
-
dangerous={dangerous}
|
|
92
|
-
$separatorLine={separatorLine}
|
|
93
93
|
>
|
|
94
94
|
{prefix}
|
|
95
95
|
{children || content}
|
|
@@ -100,10 +100,10 @@ export function DropdownMenuItem({
|
|
|
100
100
|
|
|
101
101
|
const DropdownMenuItemWrapper = styled.li<{
|
|
102
102
|
$separatorLine?: boolean;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
dangerous?: boolean;
|
|
103
|
+
$separator?: boolean;
|
|
104
|
+
$active?: boolean;
|
|
105
|
+
$disabled?: boolean;
|
|
106
|
+
$dangerous?: boolean;
|
|
107
107
|
}>`
|
|
108
108
|
display: flex;
|
|
109
109
|
flex-direction: row;
|
|
@@ -140,8 +140,8 @@ const DropdownMenuItemWrapper = styled.li<{
|
|
|
140
140
|
color: var(--dropdown-menu-item-color-hover);
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
${({ separator }) =>
|
|
144
|
-
separator &&
|
|
143
|
+
${({ $separator }) =>
|
|
144
|
+
$separator &&
|
|
145
145
|
css`
|
|
146
146
|
cursor: default;
|
|
147
147
|
pointer-events: none;
|
|
@@ -151,8 +151,8 @@ const DropdownMenuItemWrapper = styled.li<{
|
|
|
151
151
|
--dropdown-menu-item-bg-color-hover: var(--dropdown-menu-item-bg-color);
|
|
152
152
|
`}
|
|
153
153
|
|
|
154
|
-
${({ active }) =>
|
|
155
|
-
active &&
|
|
154
|
+
${({ $active }) =>
|
|
155
|
+
$active &&
|
|
156
156
|
css`
|
|
157
157
|
background-color: var(--dropdown-menu-item-bg-color-active);
|
|
158
158
|
color: var(--dropdown-menu-item-color-active);
|
|
@@ -161,8 +161,8 @@ const DropdownMenuItemWrapper = styled.li<{
|
|
|
161
161
|
}
|
|
162
162
|
`}
|
|
163
163
|
|
|
164
|
-
${({ disabled }) =>
|
|
165
|
-
disabled &&
|
|
164
|
+
${({ $disabled }) =>
|
|
165
|
+
$disabled &&
|
|
166
166
|
css`
|
|
167
167
|
cursor: default;
|
|
168
168
|
pointer-events: none;
|
|
@@ -187,8 +187,8 @@ const DropdownMenuItemWrapper = styled.li<{
|
|
|
187
187
|
}
|
|
188
188
|
`}
|
|
189
189
|
|
|
190
|
-
${({ dangerous }) =>
|
|
191
|
-
dangerous &&
|
|
190
|
+
${({ $dangerous }) =>
|
|
191
|
+
$dangerous &&
|
|
192
192
|
css`
|
|
193
193
|
&:hover,
|
|
194
194
|
& {
|
|
@@ -19,7 +19,7 @@ export type LanguagePickerProps = {
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
export function LanguagePicker(props: LanguagePickerProps): JSX.Element | null {
|
|
22
|
-
const { currentLocale, locales,
|
|
22
|
+
const { currentLocale, locales, getLocaleUrl } = useLanguagePicker();
|
|
23
23
|
const { useTelemetry } = useThemeHooks();
|
|
24
24
|
const telemetry = useTelemetry();
|
|
25
25
|
|
|
@@ -37,8 +37,9 @@ export function LanguagePicker(props: LanguagePickerProps): JSX.Element | null {
|
|
|
37
37
|
|
|
38
38
|
const languageItems = locales.map((locale) => ({
|
|
39
39
|
content: locale.name || locale.code || '',
|
|
40
|
+
to: getLocaleUrl(locale.code),
|
|
41
|
+
languageInsensitive: true,
|
|
40
42
|
onAction: () => {
|
|
41
|
-
setLocale(locale.code);
|
|
42
43
|
props.onChangeLanguage(locale.code);
|
|
43
44
|
telemetry.sendLanguagePickerLocaleChangedMessage([{ object: 'locale', locale: locale.code }]);
|
|
44
45
|
},
|
|
@@ -153,7 +153,7 @@ export function useCodeWalkthroughSteps({
|
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
step.compRef = element;
|
|
156
|
-
setVisibleSteps((prevSteps) =>
|
|
156
|
+
setVisibleSteps((prevSteps) => insertVisibleStepInOrder(prevSteps, step));
|
|
157
157
|
},
|
|
158
158
|
[stepsMap],
|
|
159
159
|
);
|
|
@@ -365,7 +365,7 @@ function getGroups(steps: CodeWalkthroughStep[]): StepsGroup[] {
|
|
|
365
365
|
return groups;
|
|
366
366
|
}
|
|
367
367
|
|
|
368
|
-
|
|
368
|
+
function getGroupMarkers(group: StepsGroup) {
|
|
369
369
|
if (!group.steps.length) {
|
|
370
370
|
return [];
|
|
371
371
|
}
|
|
@@ -440,3 +440,11 @@ function getNormalizedNumber(options: { min: number; max: number; value: number
|
|
|
440
440
|
|
|
441
441
|
return (value - min) / (max - min);
|
|
442
442
|
}
|
|
443
|
+
|
|
444
|
+
function insertVisibleStepInOrder(visible: StepWithIndex[], step: StepWithIndex): StepWithIndex[] {
|
|
445
|
+
const others = visible.filter((s) => s.id !== step.id);
|
|
446
|
+
const laterAt = others.findIndex((s) => s.index > step.index);
|
|
447
|
+
const at = laterAt === -1 ? others.length : laterAt;
|
|
448
|
+
|
|
449
|
+
return insertAt(others, at, step);
|
|
450
|
+
}
|
|
@@ -1,34 +1,59 @@
|
|
|
1
|
-
import { useNavigate } from 'react-router-dom';
|
|
1
|
+
import { useLocation, useNavigate } from 'react-router-dom';
|
|
2
2
|
|
|
3
3
|
import type { L10nConfig } from '../types/hooks';
|
|
4
4
|
|
|
5
5
|
import { useThemeHooks } from './use-theme-hooks';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
addLeadingSlash,
|
|
8
|
+
getPathnameForLocale,
|
|
9
|
+
withoutPathPrefix,
|
|
10
|
+
withPathPrefix,
|
|
11
|
+
} from '../utils/urls';
|
|
7
12
|
|
|
8
|
-
export
|
|
13
|
+
export type UseLanguagePickerResult = {
|
|
9
14
|
currentLocale: L10nConfig['locales'][number] | undefined;
|
|
10
15
|
locales: L10nConfig['locales'];
|
|
16
|
+
getLocaleUrl: (value: string) => string;
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated Use `getLocaleUrl` to build the URL for the target locale, then pass it to `<Link>`.
|
|
19
|
+
*/
|
|
11
20
|
setLocale: (value: string) => void;
|
|
12
|
-
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export function useLanguagePicker(): UseLanguagePickerResult {
|
|
13
24
|
const { useL10nConfig, useLoadAndNavigate } = useThemeHooks();
|
|
14
25
|
const navigate = useNavigate();
|
|
15
26
|
const loadAndNavigate = useLoadAndNavigate();
|
|
27
|
+
|
|
16
28
|
const { currentLocale, locales, defaultLocale } = useL10nConfig();
|
|
29
|
+
const location = useLocation();
|
|
17
30
|
|
|
18
31
|
const locale = locales.find((l) => l.code === currentLocale);
|
|
19
32
|
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
|
|
33
|
+
function getLocaleUrl(value: string): string {
|
|
34
|
+
let newLangPathname = getPathnameForLocale(
|
|
35
|
+
withoutPathPrefix(location.pathname),
|
|
36
|
+
defaultLocale,
|
|
37
|
+
value,
|
|
38
|
+
locales,
|
|
23
39
|
);
|
|
24
40
|
|
|
25
|
-
|
|
41
|
+
if (location.search) {
|
|
42
|
+
newLangPathname += location.search;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return addLeadingSlash(newLangPathname);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function setLocale(value: string): void {
|
|
49
|
+
const newUrlWithLanguage = withPathPrefix(getLocaleUrl(value));
|
|
26
50
|
loadAndNavigate({ navigate, to: newUrlWithLanguage });
|
|
27
51
|
}
|
|
28
52
|
|
|
29
53
|
return {
|
|
30
54
|
currentLocale: locale,
|
|
31
55
|
locales,
|
|
56
|
+
getLocaleUrl,
|
|
32
57
|
setLocale,
|
|
33
58
|
};
|
|
34
59
|
}
|
|
@@ -8,6 +8,7 @@ import React, {
|
|
|
8
8
|
useCallback,
|
|
9
9
|
} from 'react';
|
|
10
10
|
import styled from 'styled-components';
|
|
11
|
+
import { useLocation } from 'react-router-dom';
|
|
11
12
|
|
|
12
13
|
import type { WithConditions } from '@redocly/config';
|
|
13
14
|
|
|
@@ -29,6 +30,7 @@ export function CodeStep({
|
|
|
29
30
|
unless,
|
|
30
31
|
children,
|
|
31
32
|
}: PropsWithChildren<CodeStepProps>) {
|
|
33
|
+
const location = useLocation();
|
|
32
34
|
const compRef = useRef<HTMLDivElement | null>(null);
|
|
33
35
|
const markerRef = useRef<HTMLDivElement | null>(null);
|
|
34
36
|
|
|
@@ -79,16 +81,13 @@ export function CodeStep({
|
|
|
79
81
|
);
|
|
80
82
|
|
|
81
83
|
useEffect(() => {
|
|
82
|
-
// If the step is active during first render, scroll to it
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
setTimeout(handleActivateStep, 5);
|
|
87
|
-
}
|
|
88
|
-
|
|
84
|
+
// If the step is active during navigation or first render, scroll to it
|
|
85
|
+
if (!isActive) return;
|
|
86
|
+
const timer = setTimeout(handleActivateStep, 5);
|
|
87
|
+
return () => clearTimeout(timer);
|
|
89
88
|
// Ignore dependency array because we only need to run this once
|
|
90
89
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
91
|
-
}, []);
|
|
90
|
+
}, [location.pathname]);
|
|
92
91
|
|
|
93
92
|
useEffect(() => {
|
|
94
93
|
const currentCompRef = compRef.current;
|