@redocly/theme 0.68.0-next.4 → 0.68.0-next.6
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/ShowMoreToggleButton.d.ts +11 -0
- package/lib/components/Button/ShowMoreToggleButton.js +21 -0
- package/lib/components/CodeBlock/CodeBlock.d.ts +7 -1
- package/lib/components/CodeBlock/CodeBlock.js +30 -7
- package/lib/components/Dropdown/Dropdown.d.ts +2 -0
- package/lib/components/Dropdown/Dropdown.js +59 -14
- package/lib/components/Dropdown/variables.js +3 -1
- package/lib/components/Feedback/Feedback.js +1 -3
- package/lib/components/Feedback/Stars.js +1 -1
- package/lib/components/Footer/FooterItem.js +1 -1
- package/lib/components/JsonViewer/Helpers.d.ts +1 -0
- package/lib/components/JsonViewer/Helpers.js +20 -7
- package/lib/components/JsonViewer/JsonViewer.d.ts +2 -0
- package/lib/components/JsonViewer/JsonViewer.js +2 -2
- package/lib/components/LanguagePicker/LanguagePicker.js +3 -2
- package/lib/components/Markdown/Markdown.js +13 -6
- package/lib/components/Markdown/styles/links.d.ts +1 -0
- package/lib/components/Markdown/styles/links.js +19 -16
- package/lib/components/Menu/MenuItem.d.ts +7 -1
- package/lib/components/Menu/MenuItem.js +43 -2
- package/lib/components/Navbar/NavbarItem.js +8 -3
- package/lib/components/PageActions/PageActions.js +1 -4
- package/lib/components/Panel/variables.js +1 -0
- package/lib/components/ReplayGate/ReplayGate.d.ts +12 -0
- package/lib/components/ReplayGate/ReplayGate.js +11 -0
- package/lib/components/ReplayTopBarActions/ReplayTopBarActions.d.ts +13 -0
- package/lib/components/ReplayTopBarActions/ReplayTopBarActions.js +7 -0
- package/lib/components/Search/SearchDialog.js +4 -4
- package/lib/core/hooks/use-active-section-id.d.ts +2 -0
- package/lib/core/hooks/use-active-section-id.js +11 -1
- package/lib/core/hooks/use-page-actions.js +10 -9
- package/lib/core/hooks/use-theme-hooks.js +1 -0
- package/lib/core/openapi/index.d.ts +1 -1
- package/lib/core/openapi/index.js +2 -1
- package/lib/core/styles/global.js +8 -0
- package/lib/core/types/hooks.d.ts +1 -0
- package/lib/core/types/l10n.d.ts +1 -1
- package/lib/layouts/ThreePanelLayout.d.ts +5 -2
- package/package.json +3 -3
- package/src/components/Button/ShowMoreToggleButton.tsx +33 -0
- package/src/components/CodeBlock/CodeBlock.tsx +56 -12
- package/src/components/Dropdown/Dropdown.tsx +93 -21
- package/src/components/Dropdown/variables.ts +3 -1
- package/src/components/Feedback/Feedback.tsx +1 -3
- package/src/components/Feedback/Stars.tsx +1 -0
- package/src/components/Footer/FooterItem.tsx +3 -0
- package/src/components/JsonViewer/Helpers.tsx +41 -3
- package/src/components/JsonViewer/JsonViewer.tsx +4 -0
- package/src/components/LanguagePicker/LanguagePicker.tsx +3 -1
- package/src/components/Markdown/Markdown.tsx +13 -6
- package/src/components/Markdown/styles/links.ts +19 -15
- package/src/components/Menu/MenuItem.tsx +47 -2
- package/src/components/Navbar/NavbarItem.tsx +10 -4
- package/src/components/PageActions/PageActions.tsx +3 -6
- package/src/components/Panel/variables.ts +1 -0
- package/src/components/ReplayGate/ReplayGate.tsx +18 -0
- package/src/components/ReplayTopBarActions/ReplayTopBarActions.tsx +14 -0
- package/src/components/Search/SearchDialog.tsx +4 -4
- package/src/core/hooks/use-active-section-id.ts +13 -1
- package/src/core/hooks/use-page-actions.ts +13 -11
- package/src/core/hooks/use-theme-hooks.ts +1 -0
- package/src/core/openapi/index.ts +1 -1
- package/src/core/styles/global.ts +8 -0
- package/src/core/types/hooks.ts +1 -0
- package/src/core/types/l10n.ts +39 -1
- package/src/layouts/ThreePanelLayout.tsx +1 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { JSX } from 'react';
|
|
2
|
+
export type ShowMoreToggleButtonProps = {
|
|
3
|
+
isExpanded: boolean;
|
|
4
|
+
onToggle: () => void;
|
|
5
|
+
className?: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* "Show more" / "Show less" toggle used by truncated-value renderers
|
|
9
|
+
* (JsonViewer oversized strings, CodeBlock `maxDisplayLength`).
|
|
10
|
+
*/
|
|
11
|
+
export declare function ShowMoreToggleButton({ isExpanded, onToggle, className, }: ShowMoreToggleButtonProps): JSX.Element;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ShowMoreToggleButton = ShowMoreToggleButton;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const hooks_1 = require("../../core/hooks");
|
|
9
|
+
const Button_1 = require("../../components/Button/Button");
|
|
10
|
+
/**
|
|
11
|
+
* "Show more" / "Show less" toggle used by truncated-value renderers
|
|
12
|
+
* (JsonViewer oversized strings, CodeBlock `maxDisplayLength`).
|
|
13
|
+
*/
|
|
14
|
+
function ShowMoreToggleButton({ isExpanded, onToggle, className, }) {
|
|
15
|
+
const { useTranslate } = (0, hooks_1.useThemeHooks)();
|
|
16
|
+
const { translate } = useTranslate();
|
|
17
|
+
return (react_1.default.createElement(Button_1.Button, { className: className, size: "small", variant: "link", onClick: onToggle }, isExpanded
|
|
18
|
+
? translate('jsonViewer.showLess', 'Show less')
|
|
19
|
+
: translate('jsonViewer.showMore', 'Show more')));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=ShowMoreToggleButton.js.map
|
|
@@ -13,6 +13,12 @@ export type CodeBlockProps = {
|
|
|
13
13
|
withLineNumbers?: boolean;
|
|
14
14
|
startLineNumber?: number;
|
|
15
15
|
highlightedHtml?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Display at most this many characters of `source`, with a "Show more" toggle for the rest.
|
|
18
|
+
* Copy and report controls always receive the full source. Ignored when `highlightedHtml`
|
|
19
|
+
* or `children` are provided.
|
|
20
|
+
*/
|
|
21
|
+
maxDisplayLength?: number;
|
|
16
22
|
skipHighlight?: boolean;
|
|
17
23
|
codeBlockRef?: (instance: HTMLPreElement | null) => void;
|
|
18
24
|
codeBlockMaxHeight?: string;
|
|
@@ -41,5 +47,5 @@ type ExternalSource = {
|
|
|
41
47
|
properties?: any;
|
|
42
48
|
operation?: any;
|
|
43
49
|
};
|
|
44
|
-
export declare function CodeBlock({ lang, source, externalSource, header, dataTestId, codeBlockRef, highlightedHtml, withLineNumbers, startLineNumber, className, codeBlockMaxHeight, tabs, dropdown, hideCodeColors, wrapContents, children, ...rest }: React.PropsWithChildren<CodeBlockProps>): JSX.Element;
|
|
50
|
+
export declare function CodeBlock({ lang, source, externalSource, header, dataTestId, codeBlockRef, highlightedHtml, maxDisplayLength, withLineNumbers, startLineNumber, className, codeBlockMaxHeight, tabs, dropdown, hideCodeColors, wrapContents, children, ...rest }: React.PropsWithChildren<CodeBlockProps>): JSX.Element;
|
|
45
51
|
export {};
|
|
@@ -55,24 +55,42 @@ const hooks_1 = require("../../core/hooks");
|
|
|
55
55
|
const ReportDialog_1 = require("../../components/Feedback/ReportDialog");
|
|
56
56
|
const CodeBlockContainer_1 = require("../../components/CodeBlock/CodeBlockContainer");
|
|
57
57
|
const CodeBlockControls_1 = require("../../components/CodeBlock/CodeBlockControls");
|
|
58
|
+
const ShowMoreToggleButton_1 = require("../../components/Button/ShowMoreToggleButton");
|
|
58
59
|
function CodeBlock(_a) {
|
|
59
60
|
var _b, _c, _d, _e, _f;
|
|
60
61
|
var _g;
|
|
61
|
-
var { lang, source, externalSource, header, dataTestId = 'source-code', codeBlockRef, highlightedHtml, withLineNumbers, startLineNumber, className, codeBlockMaxHeight, tabs, dropdown, hideCodeColors, wrapContents = false, children } = _a, rest = __rest(_a, ["lang", "source", "externalSource", "header", "dataTestId", "codeBlockRef", "highlightedHtml", "withLineNumbers", "startLineNumber", "className", "codeBlockMaxHeight", "tabs", "dropdown", "hideCodeColors", "wrapContents", "children"]);
|
|
62
|
+
var { lang, source, externalSource, header, dataTestId = 'source-code', codeBlockRef, highlightedHtml, maxDisplayLength, withLineNumbers, startLineNumber, className, codeBlockMaxHeight, tabs, dropdown, hideCodeColors, wrapContents = false, children } = _a, rest = __rest(_a, ["lang", "source", "externalSource", "header", "dataTestId", "codeBlockRef", "highlightedHtml", "maxDisplayLength", "withLineNumbers", "startLineNumber", "className", "codeBlockMaxHeight", "tabs", "dropdown", "hideCodeColors", "wrapContents", "children"]);
|
|
62
63
|
const [sourceCode, setSourceCode] = (0, react_1.useState)((_g = (source || ((_c = (_b = externalSource === null || externalSource === void 0 ? void 0 : externalSource.sample) === null || _b === void 0 ? void 0 : _b.get) === null || _c === void 0 ? void 0 : _c.call(_b, externalSource)))) !== null && _g !== void 0 ? _g : '');
|
|
63
64
|
const { useCodeHighlight } = (0, hooks_1.useThemeHooks)();
|
|
64
65
|
const { highlight } = useCodeHighlight() || {};
|
|
65
|
-
const
|
|
66
|
+
const dataHighlight = rest['data-highlight'];
|
|
67
|
+
const hasChildren = Boolean(children);
|
|
68
|
+
const [isSourceExpanded, setIsSourceExpanded] = (0, react_1.useState)(false);
|
|
69
|
+
const isTruncatable = maxDisplayLength !== undefined &&
|
|
70
|
+
sourceCode.length > maxDisplayLength &&
|
|
71
|
+
!highlightedHtml &&
|
|
72
|
+
!hasChildren;
|
|
73
|
+
const displayedSource = isTruncatable && !isSourceExpanded ? `${sourceCode.slice(0, maxDisplayLength)}…` : sourceCode;
|
|
74
|
+
const highlightedCode = (0, react_1.useMemo)(() => highlightedHtml
|
|
66
75
|
? withLineNumbers
|
|
67
76
|
? (0, utils_1.addLineNumbers)(highlightedHtml, startLineNumber)
|
|
68
77
|
: highlightedHtml
|
|
69
|
-
:
|
|
78
|
+
: hasChildren
|
|
70
79
|
? null
|
|
71
|
-
: highlight === null || highlight === void 0 ? void 0 : highlight(
|
|
80
|
+
: highlight === null || highlight === void 0 ? void 0 : highlight(displayedSource, lang, {
|
|
72
81
|
withLineNumbers,
|
|
73
82
|
startLineNumber,
|
|
74
|
-
highlight:
|
|
75
|
-
})
|
|
83
|
+
highlight: dataHighlight,
|
|
84
|
+
}), [
|
|
85
|
+
highlightedHtml,
|
|
86
|
+
withLineNumbers,
|
|
87
|
+
startLineNumber,
|
|
88
|
+
hasChildren,
|
|
89
|
+
highlight,
|
|
90
|
+
displayedSource,
|
|
91
|
+
lang,
|
|
92
|
+
dataHighlight,
|
|
93
|
+
]);
|
|
76
94
|
// The same initial value should be returned for ssr and frontend to avoid issues
|
|
77
95
|
// Because we don't have session storage in ssr and can't get the security details there
|
|
78
96
|
// Issue for more details https://github.com/Redocly/reference-docs/issues/888
|
|
@@ -97,8 +115,13 @@ function CodeBlock(_a) {
|
|
|
97
115
|
/* eslint-disable-next-line no-warning-comments */
|
|
98
116
|
suppressHydrationWarning // TODO: investigate issue
|
|
99
117
|
: true, "data-testid": dataTestId, hideCodeColors: hideCodeColors, maxHeight: codeBlockMaxHeight, wrapContents: wrapContents, tabIndex: 0 }, children),
|
|
100
|
-
reportDialog.visible && (react_1.default.createElement(ReportDialog_1.ReportDialog, Object.assign({}, reportDialog.props, { location: sourceCode, lang: lang }))))
|
|
118
|
+
reportDialog.visible && (react_1.default.createElement(ReportDialog_1.ReportDialog, Object.assign({}, reportDialog.props, { location: sourceCode, lang: lang })))),
|
|
119
|
+
isTruncatable ? (react_1.default.createElement(TruncationToggleButton, { isExpanded: isSourceExpanded, onToggle: () => setIsSourceExpanded((expanded) => !expanded) })) : null));
|
|
101
120
|
}
|
|
121
|
+
const TruncationToggleButton = (0, styled_components_1.default)(ShowMoreToggleButton_1.ShowMoreToggleButton) `
|
|
122
|
+
margin: 0 var(--spacing-sm) var(--spacing-xs);
|
|
123
|
+
user-select: none;
|
|
124
|
+
`;
|
|
102
125
|
const ContainerWrapper = styled_components_1.default.div `
|
|
103
126
|
display: grid; // prevents content to overstretch
|
|
104
127
|
position: relative;
|
|
@@ -10,6 +10,7 @@ export type DropdownProps = PropsWithChildren<{
|
|
|
10
10
|
dataAttributes?: Record<string, string>;
|
|
11
11
|
className?: string;
|
|
12
12
|
withArrow?: boolean;
|
|
13
|
+
portalled?: boolean;
|
|
13
14
|
onClick?: (event: React.UIEvent) => void;
|
|
14
15
|
onClose?: () => void;
|
|
15
16
|
onOpen?: () => void;
|
|
@@ -24,6 +25,7 @@ export declare const Dropdown: React.ForwardRefExoticComponent<{
|
|
|
24
25
|
dataAttributes?: Record<string, string>;
|
|
25
26
|
className?: string;
|
|
26
27
|
withArrow?: boolean;
|
|
28
|
+
portalled?: boolean;
|
|
27
29
|
onClick?: (event: React.UIEvent) => void;
|
|
28
30
|
onClose?: () => void;
|
|
29
31
|
onOpen?: () => void;
|
|
@@ -32,19 +32,21 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
36
|
exports.Dropdown = void 0;
|
|
40
37
|
const react_1 = __importStar(require("react"));
|
|
41
|
-
const
|
|
38
|
+
const react_dom_1 = require("react-dom");
|
|
39
|
+
const styled_components_1 = __importStar(require("styled-components"));
|
|
42
40
|
const hooks_1 = require("../../core/hooks");
|
|
43
41
|
const ChevronDownIcon_1 = require("../../icons/ChevronDownIcon/ChevronDownIcon");
|
|
44
42
|
const ChevronUpIcon_1 = require("../../icons/ChevronUpIcon/ChevronUpIcon");
|
|
45
|
-
|
|
43
|
+
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? react_1.useLayoutEffect : react_1.useEffect;
|
|
44
|
+
exports.Dropdown = (0, react_1.forwardRef)(({ children, className, active, trigger, triggerEvent = 'click', closeOnClick = true, withArrow, dataAttributes, placement, alignment, portalled = false, onClick, onClose, onOpen, }, ref) => {
|
|
46
45
|
const dropdownRef = (0, react_1.useRef)(null);
|
|
46
|
+
const menuRef = (0, react_1.useRef)(null);
|
|
47
47
|
const [isOpen, setIsOpen] = (0, hooks_1.useControlledState)(false, active);
|
|
48
|
+
const [menuStyle, setMenuStyle] = (0, react_1.useState)({});
|
|
49
|
+
const wrapperRef = ref || dropdownRef;
|
|
48
50
|
const handleOpen = () => {
|
|
49
51
|
setIsOpen(true);
|
|
50
52
|
onOpen === null || onOpen === void 0 ? void 0 : onOpen();
|
|
@@ -71,12 +73,49 @@ exports.Dropdown = (0, react_1.forwardRef)(({ children, className, active, trigg
|
|
|
71
73
|
handleToggle(event);
|
|
72
74
|
}
|
|
73
75
|
};
|
|
74
|
-
(0,
|
|
76
|
+
const updateMenuPosition = (0, react_1.useCallback)(() => {
|
|
77
|
+
const wrapper = wrapperRef.current;
|
|
78
|
+
if (!wrapper)
|
|
79
|
+
return;
|
|
80
|
+
const rect = wrapper.getBoundingClientRect();
|
|
81
|
+
const style = { minWidth: rect.width };
|
|
82
|
+
if (placement === 'top') {
|
|
83
|
+
style.bottom = window.innerHeight - rect.top;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
style.top = rect.bottom;
|
|
87
|
+
}
|
|
88
|
+
if (alignment === 'end') {
|
|
89
|
+
style.right = window.innerWidth - rect.right;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
style.left = rect.left;
|
|
93
|
+
}
|
|
94
|
+
const zIndex = getComputedStyle(wrapper).getPropertyValue('--dropdown-menu-z-index').trim();
|
|
95
|
+
if (zIndex) {
|
|
96
|
+
style.zIndex = zIndex;
|
|
97
|
+
}
|
|
98
|
+
setMenuStyle(style);
|
|
99
|
+
}, [placement, alignment, wrapperRef]);
|
|
100
|
+
useIsomorphicLayoutEffect(() => {
|
|
101
|
+
if (!portalled || !isOpen)
|
|
102
|
+
return;
|
|
103
|
+
updateMenuPosition();
|
|
104
|
+
window.addEventListener('scroll', updateMenuPosition, true);
|
|
105
|
+
window.addEventListener('resize', updateMenuPosition);
|
|
106
|
+
return () => {
|
|
107
|
+
window.removeEventListener('scroll', updateMenuPosition, true);
|
|
108
|
+
window.removeEventListener('resize', updateMenuPosition);
|
|
109
|
+
};
|
|
110
|
+
}, [portalled, isOpen, updateMenuPosition]);
|
|
111
|
+
(0, hooks_1.useOutsideClick)(portalled ? [wrapperRef, menuRef] : wrapperRef, handleClose);
|
|
75
112
|
const triggerChild = react_1.default.Children.only(trigger);
|
|
76
113
|
const dropdownTrigger = (0, react_1.cloneElement)(triggerChild, Object.assign(Object.assign(Object.assign({ onClick: triggerEvent === 'click' ? handleToggle : undefined, icon: withArrow ? isOpen ? react_1.default.createElement(ChevronUpIcon_1.ChevronUpIcon, null) : react_1.default.createElement(ChevronDownIcon_1.ChevronDownIcon, null) : undefined }, (withArrow ? { iconPosition: 'right' } : {})), triggerChild.props), { onKeyDown: triggerEvent === 'click' ? handleKeyDown : undefined }));
|
|
77
|
-
|
|
114
|
+
const menu = (react_1.default.createElement(ChildrenWrapper, { ref: menuRef, $placement: placement, $alignment: alignment, $isOpen: isOpen, $portalled: portalled, style: portalled ? menuStyle : undefined, onClick: closeOnClick ? handleChildClick : undefined }, children));
|
|
115
|
+
const portalledMenu = isOpen && typeof document !== 'undefined' ? (0, react_dom_1.createPortal)(menu, document.body) : null;
|
|
116
|
+
return (react_1.default.createElement(DropdownWrapper, Object.assign({ "data-component-name": "Dropdown/Dropdown", "data-testid": "dropdown" }, dataAttributes, { className: className, ref: wrapperRef, onPointerEnter: triggerEvent === 'hover' ? handleOpen : undefined, onPointerLeave: triggerEvent === 'hover' ? handleClose : undefined, onClick: onClick }),
|
|
78
117
|
dropdownTrigger,
|
|
79
|
-
|
|
118
|
+
portalled ? portalledMenu : menu));
|
|
80
119
|
});
|
|
81
120
|
const DropdownWrapper = styled_components_1.default.div `
|
|
82
121
|
--button-gap: var(--spacing-xxs);
|
|
@@ -96,13 +135,19 @@ const DropdownWrapper = styled_components_1.default.div `
|
|
|
96
135
|
`;
|
|
97
136
|
const ChildrenWrapper = styled_components_1.default.div `
|
|
98
137
|
padding-top: var(--dropdown-menu-padding-top);
|
|
99
|
-
position: absolute;
|
|
100
|
-
top: ${({ $placement }) => ($placement === 'top' ? 'auto' : '100%')};
|
|
101
|
-
bottom: ${({ $placement }) => ($placement === 'top' ? '100%' : 'auto')};
|
|
102
|
-
left: ${({ $alignment }) => ($alignment === 'start' ? '0' : 'auto')};
|
|
103
|
-
right: ${({ $alignment }) => ($alignment === 'end' ? '0' : 'auto')};
|
|
104
138
|
display: ${({ $isOpen }) => ($isOpen ? 'block' : 'none')};
|
|
105
|
-
|
|
106
139
|
z-index: var(--dropdown-menu-z-index);
|
|
140
|
+
|
|
141
|
+
${({ $portalled, $placement, $alignment }) => $portalled
|
|
142
|
+
? (0, styled_components_1.css) `
|
|
143
|
+
position: fixed;
|
|
144
|
+
`
|
|
145
|
+
: (0, styled_components_1.css) `
|
|
146
|
+
position: absolute;
|
|
147
|
+
top: ${$placement === 'top' ? 'auto' : '100%'};
|
|
148
|
+
bottom: ${$placement === 'top' ? '100%' : 'auto'};
|
|
149
|
+
left: ${$alignment === 'start' ? '0' : 'auto'};
|
|
150
|
+
right: ${$alignment === 'end' ? '0' : 'auto'};
|
|
151
|
+
`}
|
|
107
152
|
`;
|
|
108
153
|
//# sourceMappingURL=Dropdown.js.map
|
|
@@ -10,7 +10,9 @@ exports.dropdown = (0, styled_components_1.css) `
|
|
|
10
10
|
--dropdown-menu-font-weight: var(--font-weight-regular); // @presenter FontWeight
|
|
11
11
|
--dropdown-menu-line-height: var(--line-height-base); // @presenter LineHeight
|
|
12
12
|
--dropdown-menu-text-color: var(--text-color-secondary); // @presenter Color
|
|
13
|
-
|
|
13
|
+
/* One below --z-index-raised (the sticky Navbar) so a portaled menu, which is
|
|
14
|
+
appended to <body> after the navbar, never paints over it on a z-index tie. */
|
|
15
|
+
--dropdown-menu-z-index: calc(var(--z-index-raised) - 1); // @presenter ZIndex
|
|
14
16
|
|
|
15
17
|
--dropdown-menu-padding-top: var(--spacing-xxs);
|
|
16
18
|
--dropdown-menu-min-width: 100px;
|
|
@@ -38,7 +38,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.Feedback = Feedback;
|
|
40
40
|
const React = __importStar(require("react"));
|
|
41
|
-
const react_router_dom_1 = require("react-router-dom");
|
|
42
41
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
43
42
|
const hooks_1 = require("../../core/hooks");
|
|
44
43
|
const Rating_1 = require("../../components/Feedback/Rating");
|
|
@@ -60,7 +59,6 @@ function Feedback(props) {
|
|
|
60
59
|
const { useSubmitFeedback, useTelemetry } = (0, hooks_1.useThemeHooks)();
|
|
61
60
|
const { submitFeedback } = useSubmitFeedback();
|
|
62
61
|
const telemetry = useTelemetry();
|
|
63
|
-
const { pathname } = (0, react_router_dom_1.useLocation)();
|
|
64
62
|
const { feedback: themeFeedbackConf } = (0, hooks_1.useThemeConfig)();
|
|
65
63
|
const feedbackConf = Object.assign(Object.assign({}, themeFeedbackConf), { path: props === null || props === void 0 ? void 0 : props.path, type: (props === null || props === void 0 ? void 0 : props.type) || (themeFeedbackConf === null || themeFeedbackConf === void 0 ? void 0 : themeFeedbackConf.type) || constants_1.DEFAULT_FEEDBACK_TYPE, settings: (props === null || props === void 0 ? void 0 : props.settings) || (themeFeedbackConf === null || themeFeedbackConf === void 0 ? void 0 : themeFeedbackConf.settings) || {}, hide: (_a = props.hide) !== null && _a !== void 0 ? _a : themeFeedbackConf === null || themeFeedbackConf === void 0 ? void 0 : themeFeedbackConf.hide });
|
|
66
64
|
if (feedbackConf.hide) {
|
|
@@ -80,7 +78,7 @@ function Feedback(props) {
|
|
|
80
78
|
]);
|
|
81
79
|
} })));
|
|
82
80
|
};
|
|
83
|
-
return React.createElement(React.Fragment, { key:
|
|
81
|
+
return React.createElement(React.Fragment, { key: feedbackConf.path }, renderFeedbackComponent());
|
|
84
82
|
}
|
|
85
83
|
const FeedbackWrapper = styled_components_1.default.div `
|
|
86
84
|
padding: var(--feedback-padding);
|
|
@@ -45,7 +45,7 @@ function Stars({ max = 5, onChange, value }) {
|
|
|
45
45
|
const [hovered, setHovered] = React.useState(value || 0);
|
|
46
46
|
const stars = [];
|
|
47
47
|
for (let index = 1; index <= max; index++) {
|
|
48
|
-
stars.push(React.createElement(Star, { "data-testid": `star-${index}`, key: index, onClick: () => onChange(index), onMouseOver: () => setHovered(index), onMouseLeave: () => !value && setHovered(0) }, hovered < index ? (React.createElement(StarIcon_1.StarIcon, { color: "var(--feedback-star-color)" })) : (React.createElement(StarFilledIcon_1.StarFilledIcon, { color: "var(--feedback-star-color)" }))));
|
|
48
|
+
stars.push(React.createElement(Star, { "data-testid": `star-${index}`, key: index, "aria-label": `${index} ${index === 1 ? 'star' : 'stars'}`, onClick: () => onChange(index), onMouseOver: () => setHovered(index), onMouseLeave: () => !value && setHovered(0) }, hovered < index ? (React.createElement(StarIcon_1.StarIcon, { color: "var(--feedback-star-color)" })) : (React.createElement(StarFilledIcon_1.StarFilledIcon, { color: "var(--feedback-star-color)" }))));
|
|
49
49
|
}
|
|
50
50
|
return React.createElement(StarsWrapper, { "data-component-name": "Feedback/Stars" }, stars);
|
|
51
51
|
}
|
|
@@ -20,7 +20,7 @@ function FooterItem({ item, iconsOnly, className }) {
|
|
|
20
20
|
}
|
|
21
21
|
const hasIcon = Boolean(item.icon || item.srcSet);
|
|
22
22
|
const iconWithoutLabel = Boolean(item.label === item.link && hasIcon);
|
|
23
|
-
return (react_1.default.createElement(FooterItemWrapper, { className: className, "data-component-name": "Footer/FooterItem", $iconsOnly: iconsOnly, $item: item }, item.type === 'separator' ? (react_1.default.createElement(FooterSeparator, { "data-translation-key": item.labelTranslationKey }, translate(item.labelTranslationKey, item.label))) : (react_1.default.createElement(FooterLink, { to: item.link, external: item.external, target: item.target, "data-testid": item.label, onClick: () => telemetry.sendFooterItemClickedMessage([(0, utils_1.getBaseDataAttributes)('footerItem', 'footer')]), "data-translation-key": item.labelTranslationKey },
|
|
23
|
+
return (react_1.default.createElement(FooterItemWrapper, { className: className, "data-component-name": "Footer/FooterItem", $iconsOnly: iconsOnly, $item: item }, item.type === 'separator' ? (react_1.default.createElement(FooterSeparator, { "data-translation-key": item.labelTranslationKey }, translate(item.labelTranslationKey, item.label))) : (react_1.default.createElement(FooterLink, { to: item.link, external: item.external, target: item.target, "data-testid": item.label, onClick: () => telemetry.sendFooterItemClickedMessage([(0, utils_1.getBaseDataAttributes)('footerItem', 'footer')]), "data-translation-key": item.labelTranslationKey, "aria-label": iconWithoutLabel ? translate(item.labelTranslationKey, item.label) : undefined },
|
|
24
24
|
hasIcon ? (react_1.default.createElement(FooterLinkIcon, { $iconsOnly: iconsOnly },
|
|
25
25
|
react_1.default.createElement(GenericIcon_1.GenericIcon, { icon: item.icon, srcSet: item.srcSet }))) : null,
|
|
26
26
|
!iconWithoutLabel ? translate(item.labelTranslationKey, item.label) : null,
|
|
@@ -40,9 +40,10 @@ exports.JsonValue = JsonValue;
|
|
|
40
40
|
const react_1 = __importStar(require("react"));
|
|
41
41
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
42
42
|
const Button_1 = require("../../components/Button/Button");
|
|
43
|
+
const ShowMoreToggleButton_1 = require("../../components/Button/ShowMoreToggleButton");
|
|
43
44
|
const ChevronDownIcon_1 = require("../../icons/ChevronDownIcon/ChevronDownIcon");
|
|
44
45
|
function JsonValue(props) {
|
|
45
|
-
const { standalone, defaultExpandLevel, level, value, expandAllSignal } = props;
|
|
46
|
+
const { standalone, defaultExpandLevel, level, value, expandAllSignal, maxStringLength } = props;
|
|
46
47
|
const indent = ' '.repeat(level * 2);
|
|
47
48
|
const [isExpandedState, setExpanded] = react_1.default.useState(expandAllSignal !== null && expandAllSignal !== void 0 ? expandAllSignal : level < defaultExpandLevel);
|
|
48
49
|
const isExpanded = expandAllSignal !== undefined && level > 0 ? expandAllSignal : isExpandedState;
|
|
@@ -58,18 +59,19 @@ function JsonValue(props) {
|
|
|
58
59
|
const valueType = typeof value;
|
|
59
60
|
const isPrimitive = (valueType !== 'object' && value !== null) || keys.length === 0;
|
|
60
61
|
if (isPrimitive) {
|
|
62
|
+
const isOversizedString = typeof value === 'string' && maxStringLength !== undefined && value.length > maxStringLength;
|
|
61
63
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
62
64
|
standalone ? indent : null,
|
|
63
|
-
react_1.default.createElement("span", { className: 'token ' + valueType }, JSON.stringify(value))));
|
|
65
|
+
isOversizedString ? (react_1.default.createElement(TruncatedStringValue, { value: value, maxStringLength: maxStringLength })) : (react_1.default.createElement("span", { className: 'token ' + valueType }, JSON.stringify(value)))));
|
|
64
66
|
}
|
|
65
67
|
const openingPunctuation = Array.isArray(value) ? '[' : '{';
|
|
66
68
|
const closingPunctuation = Array.isArray(value) ? ']' : '}';
|
|
67
69
|
const valueElement = Array.isArray(value)
|
|
68
70
|
? value.map((item, index) => (react_1.default.createElement(react_1.default.Fragment, { key: index },
|
|
69
|
-
react_1.default.createElement(JsonValue, { value: item, level: level + 1, standalone: true, defaultExpandLevel: defaultExpandLevel, expandAllSignal: expandAllSignal }),
|
|
71
|
+
react_1.default.createElement(JsonValue, { value: item, level: level + 1, standalone: true, defaultExpandLevel: defaultExpandLevel, expandAllSignal: expandAllSignal, maxStringLength: maxStringLength }),
|
|
70
72
|
index < value.length - 1 ? ',\n' : null)))
|
|
71
73
|
: keys.map((key, index) => (react_1.default.createElement(react_1.default.Fragment, { key: key },
|
|
72
|
-
react_1.default.createElement(JsonKeyValue, { name: key, value: value[key], level: level + 1, defaultExpandLevel: defaultExpandLevel, expandAllSignal: expandAllSignal }),
|
|
74
|
+
react_1.default.createElement(JsonKeyValue, { name: key, value: value[key], level: level + 1, defaultExpandLevel: defaultExpandLevel, expandAllSignal: expandAllSignal, maxStringLength: maxStringLength }),
|
|
73
75
|
index < keys.length - 1 ? ',\n' : null)));
|
|
74
76
|
const openingPunctuationElement = standalone ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
75
77
|
indent,
|
|
@@ -86,7 +88,7 @@ function JsonValue(props) {
|
|
|
86
88
|
closingPunctuationElement));
|
|
87
89
|
}
|
|
88
90
|
function JsonKeyValue(props) {
|
|
89
|
-
const { defaultExpandLevel, level, name, value, expandAllSignal } = props;
|
|
91
|
+
const { defaultExpandLevel, level, name, value, expandAllSignal, maxStringLength } = props;
|
|
90
92
|
const indent = ' '.repeat(level * 2);
|
|
91
93
|
const keys = (value && Object.keys(value).filter((key) => value[key] !== undefined)) || []; // filter out undefined properties
|
|
92
94
|
const isCollapsible = typeof value === 'object' && value !== null && keys.length > 0;
|
|
@@ -103,10 +105,10 @@ function JsonKeyValue(props) {
|
|
|
103
105
|
openingPunctuation,
|
|
104
106
|
isExpanded ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
105
107
|
'\n',
|
|
106
|
-
react_1.default.createElement(JsonValue, { value: value, level: level, defaultExpandLevel: defaultExpandLevel, expandAllSignal: expandAllSignal }),
|
|
108
|
+
react_1.default.createElement(JsonValue, { value: value, level: level, defaultExpandLevel: defaultExpandLevel, expandAllSignal: expandAllSignal, maxStringLength: maxStringLength }),
|
|
107
109
|
'\n')) : (' … '),
|
|
108
110
|
isExpanded ? indent : null,
|
|
109
|
-
closingPunctuation)) : (react_1.default.createElement(JsonValue, { value: value, level: level, defaultExpandLevel: defaultExpandLevel, expandAllSignal: expandAllSignal }));
|
|
111
|
+
closingPunctuation)) : (react_1.default.createElement(JsonValue, { value: value, level: level, defaultExpandLevel: defaultExpandLevel, expandAllSignal: expandAllSignal, maxStringLength: maxStringLength }));
|
|
110
112
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
111
113
|
indent,
|
|
112
114
|
isCollapsible ? (react_1.default.createElement(ExpandIcon, { onClick: () => setExpanded((v) => !v), isExpanded: isExpanded })) : null,
|
|
@@ -114,9 +116,20 @@ function JsonKeyValue(props) {
|
|
|
114
116
|
": ",
|
|
115
117
|
valueElement));
|
|
116
118
|
}
|
|
119
|
+
function TruncatedStringValue({ value, maxStringLength, }) {
|
|
120
|
+
const [isExpanded, setExpanded] = react_1.default.useState(false);
|
|
121
|
+
const shownValue = react_1.default.useMemo(() => JSON.stringify(isExpanded ? value : `${value.slice(0, maxStringLength)}…`), [isExpanded, value, maxStringLength]);
|
|
122
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
123
|
+
react_1.default.createElement("span", { className: "token string" }, shownValue),
|
|
124
|
+
' ',
|
|
125
|
+
react_1.default.createElement(ShowMoreButton, { isExpanded: isExpanded, onToggle: () => setExpanded((v) => !v) })));
|
|
126
|
+
}
|
|
117
127
|
function ExpandIcon({ isExpanded, onClick, }) {
|
|
118
128
|
return (react_1.default.createElement(ExpandButton, { "aria-label": "collapse", className: isExpanded ? 'expanded' : '', size: "small", variant: "text", onClick: onClick, icon: react_1.default.createElement(ChevronDownIcon_1.ChevronDownIcon, { color: "var(--text-color-helper)" }) }));
|
|
119
129
|
}
|
|
130
|
+
const ShowMoreButton = (0, styled_components_1.default)(ShowMoreToggleButton_1.ShowMoreToggleButton) `
|
|
131
|
+
user-select: none;
|
|
132
|
+
`;
|
|
120
133
|
const ExpandButton = (0, styled_components_1.default)(Button_1.Button) `
|
|
121
134
|
position: absolute;
|
|
122
135
|
left: -10px;
|
|
@@ -8,6 +8,8 @@ export type JsonProps = {
|
|
|
8
8
|
className?: string;
|
|
9
9
|
expandLevel: number;
|
|
10
10
|
startLineNumber?: number;
|
|
11
|
+
/** Truncate string values longer than this at render time (full value stays available for copy). */
|
|
12
|
+
maxStringLength?: number;
|
|
11
13
|
onCopyClick?: () => void;
|
|
12
14
|
onPanelToggle?: (isExpanded: boolean, panelType?: PanelType) => void;
|
|
13
15
|
};
|
|
@@ -41,7 +41,7 @@ const react_1 = __importStar(require("react"));
|
|
|
41
41
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
42
42
|
const CodeBlock_1 = require("../../components/CodeBlock/CodeBlock");
|
|
43
43
|
const Helpers_1 = require("../../components/JsonViewer/Helpers");
|
|
44
|
-
function JsonComponent({ data, expandLevel = 1, className, onCopyClick, onPanelToggle, title, controls = {}, }) {
|
|
44
|
+
function JsonComponent({ data, expandLevel = 1, className, onCopyClick, onPanelToggle, title, controls = {}, maxStringLength, }) {
|
|
45
45
|
const showFoldingButtons = data && Object.values(data).some((value) => typeof value === 'object' && value !== null);
|
|
46
46
|
const [expandAllSignal, setExpandAllSignal] = react_1.default.useState(undefined);
|
|
47
47
|
const expandAll = () => {
|
|
@@ -71,7 +71,7 @@ function JsonComponent({ data, expandLevel = 1, className, onCopyClick, onPanelT
|
|
|
71
71
|
}
|
|
72
72
|
: undefined, source: source },
|
|
73
73
|
react_1.default.createElement(FoldingWrap, null,
|
|
74
|
-
react_1.default.createElement(Helpers_1.JsonValue, { value: data, level: 0, standalone: true, expandAllSignal: expandAllSignal, defaultExpandLevel: Math.max(1, expandLevel) })))));
|
|
74
|
+
react_1.default.createElement(Helpers_1.JsonValue, { value: data, level: 0, standalone: true, expandAllSignal: expandAllSignal, defaultExpandLevel: Math.max(1, expandLevel), maxStringLength: maxStringLength })))));
|
|
75
75
|
}
|
|
76
76
|
exports.JsonViewer = (0, react_1.memo)(JsonComponent);
|
|
77
77
|
const FoldingWrap = styled_components_1.default.div `
|
|
@@ -15,12 +15,13 @@ const Dropdown_1 = require("../../components/Dropdown/Dropdown");
|
|
|
15
15
|
const CheckmarkIcon_1 = require("../../icons/CheckmarkIcon/CheckmarkIcon");
|
|
16
16
|
function LanguagePicker(props) {
|
|
17
17
|
const { currentLocale, locales, getLocaleUrl } = (0, hooks_1.useLanguagePicker)();
|
|
18
|
-
const { useTelemetry } = (0, hooks_1.useThemeHooks)();
|
|
18
|
+
const { useTelemetry, useTranslate } = (0, hooks_1.useThemeHooks)();
|
|
19
19
|
const telemetry = useTelemetry();
|
|
20
|
+
const { translate } = useTranslate();
|
|
20
21
|
if (locales.length < 2 || !currentLocale) {
|
|
21
22
|
return null;
|
|
22
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
|
+
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", "aria-label": translate('languagePicker.label', 'Select language') }));
|
|
24
25
|
const languageItems = locales.map((locale) => ({
|
|
25
26
|
content: locale.name || locale.code || '',
|
|
26
27
|
to: getLocaleUrl(locale.code),
|
|
@@ -53,6 +53,7 @@ exports.Markdown = styled_components_1.default.main
|
|
|
53
53
|
line-height: var(--md-content-line-height);
|
|
54
54
|
color: var(--md-content-text-color);
|
|
55
55
|
padding: 0;
|
|
56
|
+
overflow-wrap: break-word;
|
|
56
57
|
|
|
57
58
|
${({ compact }) => compact &&
|
|
58
59
|
(0, styled_components_1.css) `
|
|
@@ -97,7 +98,12 @@ exports.Markdown = styled_components_1.default.main
|
|
|
97
98
|
scroll-margin-top: calc(var(--navbar-height) + var(--banner-height));
|
|
98
99
|
${(0, heading_anchor_1.headingAnchorCss)(constants_1.ANCHOR_CLASS)};
|
|
99
100
|
|
|
100
|
-
h1,
|
|
101
|
+
h1,
|
|
102
|
+
h2,
|
|
103
|
+
h3,
|
|
104
|
+
h4,
|
|
105
|
+
h5,
|
|
106
|
+
h6 {
|
|
101
107
|
display: flex;
|
|
102
108
|
align-items: flex-start;
|
|
103
109
|
gap: var(--spacing-sm);
|
|
@@ -306,8 +312,10 @@ exports.Markdown = styled_components_1.default.main
|
|
|
306
312
|
}
|
|
307
313
|
|
|
308
314
|
blockquote {
|
|
309
|
-
margin: var(--md-blockquote-margin-vertical)
|
|
310
|
-
|
|
315
|
+
margin: var(--md-blockquote-margin-vertical)
|
|
316
|
+
var(--md-blockquote-margin-horizontal);
|
|
317
|
+
padding: var(--md-blockquote-padding-vertical)
|
|
318
|
+
var(--md-blockquote-padding-horizontal);
|
|
311
319
|
border-left: var(--md-blockquote-border-left);
|
|
312
320
|
background-color: var(--md-blockquote-bg-color);
|
|
313
321
|
color: var(--md-blockquote-text-color);
|
|
@@ -335,8 +343,7 @@ exports.Markdown = styled_components_1.default.main
|
|
|
335
343
|
}
|
|
336
344
|
}
|
|
337
345
|
|
|
338
|
-
ul.${constants_1.MARKDOWN_CLASS_NAME},
|
|
339
|
-
ol.${constants_1.MARKDOWN_CLASS_NAME} {
|
|
346
|
+
ul.${constants_1.MARKDOWN_CLASS_NAME}, ol.${constants_1.MARKDOWN_CLASS_NAME} {
|
|
340
347
|
padding-left: var(--md-list-left-padding);
|
|
341
348
|
margin: var(--md-list-margin);
|
|
342
349
|
|
|
@@ -359,7 +366,7 @@ exports.Markdown = styled_components_1.default.main
|
|
|
359
366
|
}
|
|
360
367
|
}
|
|
361
368
|
|
|
362
|
-
ul > li:has(input[type=
|
|
369
|
+
ul > li:has(input[type="checkbox"]) {
|
|
363
370
|
list-style: var(--md-checkbox-list-item-style);
|
|
364
371
|
}
|
|
365
372
|
|
|
@@ -1,24 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.markdownLinksCss = void 0;
|
|
3
|
+
exports.markdownLinksCss = exports.linkCss = void 0;
|
|
4
4
|
const styled_components_1 = require("styled-components");
|
|
5
|
-
exports.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
font-weight: var(--link-font-weight);
|
|
5
|
+
exports.linkCss = (0, styled_components_1.css) `
|
|
6
|
+
text-decoration: var(--link-decoration);
|
|
7
|
+
text-underline-offset: var(--link-underline-offset);
|
|
8
|
+
color: var(--link-color-primary);
|
|
9
|
+
font-weight: var(--link-font-weight);
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
&:visited {
|
|
12
|
+
color: var(--link-color-visited);
|
|
13
|
+
text-decoration: var(--link-decoration-visited);
|
|
14
|
+
}
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
&:hover,
|
|
17
|
+
&:focus {
|
|
18
|
+
text-decoration: var(--link-decoration-hover);
|
|
19
|
+
color: var(--link-color-primary-hover);
|
|
20
|
+
}
|
|
21
|
+
`;
|
|
22
|
+
exports.markdownLinksCss = (0, styled_components_1.css) `
|
|
23
|
+
a:not([role='button']) {
|
|
24
|
+
${exports.linkCss}
|
|
22
25
|
}
|
|
23
26
|
`;
|
|
24
27
|
//# sourceMappingURL=links.js.map
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { MenuItemProps } from '../../core/types';
|
|
3
3
|
import type { JSX } from 'react';
|
|
4
|
-
|
|
4
|
+
declare function MenuItemImpl(props: React.PropsWithChildren<MenuItemProps>): JSX.Element;
|
|
5
|
+
/** Compares only the props that actually affect this row. `item` is expected
|
|
6
|
+
* to be reference-stable from the producer (e.g. `useMenuItems`) when the
|
|
7
|
+
* row's state hasn't changed; `onClick` and `children` are fresh JSX from
|
|
8
|
+
* the parent's `.map()` every render and would defeat the memo. */
|
|
9
|
+
export declare const MenuItem: React.MemoExoticComponent<typeof MenuItemImpl>;
|
|
10
|
+
export {};
|
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.MenuItem =
|
|
36
|
+
exports.MenuItem = void 0;
|
|
37
37
|
const react_1 = __importStar(require("react"));
|
|
38
38
|
const styled_components_1 = __importStar(require("styled-components"));
|
|
39
39
|
const hooks_1 = require("../../core/hooks");
|
|
@@ -47,7 +47,19 @@ const utils_1 = require("../../core/utils");
|
|
|
47
47
|
const ArrowRightIcon_1 = require("../../icons/ArrowRightIcon/ArrowRightIcon");
|
|
48
48
|
const GenericIcon_1 = require("../../icons/GenericIcon/GenericIcon");
|
|
49
49
|
const Tag_1 = require("../../components/Tag/Tag");
|
|
50
|
-
|
|
50
|
+
/** Nearest scrollable ancestor, stopping before <body> so only the sidebar scrolls — never the page. */
|
|
51
|
+
function getScrollParent(el) {
|
|
52
|
+
let node = el.parentElement;
|
|
53
|
+
while (node && node !== document.body) {
|
|
54
|
+
const { overflowY } = getComputedStyle(node);
|
|
55
|
+
if ((overflowY === 'auto' || overflowY === 'scroll') && node.scrollHeight > node.clientHeight) {
|
|
56
|
+
return node;
|
|
57
|
+
}
|
|
58
|
+
node = node.parentElement;
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
function MenuItemImpl(props) {
|
|
51
63
|
var _a, _b;
|
|
52
64
|
var _c;
|
|
53
65
|
const { item, depth, className, onClick } = props;
|
|
@@ -65,6 +77,25 @@ function MenuItem(props) {
|
|
|
65
77
|
const isNested = type === constants_1.MenuItemType.Group;
|
|
66
78
|
const hasChevron = isNested && !isDrilldown;
|
|
67
79
|
const hasHttpTag = !!item.httpVerb || type === constants_1.MenuItemType.Operation;
|
|
80
|
+
// When this item becomes the active one (via navigation or scroll-spy), keep
|
|
81
|
+
// it visible by scrolling only the sidebar's own scroll container.
|
|
82
|
+
(0, react_1.useEffect)(() => {
|
|
83
|
+
const el = labelRef.current;
|
|
84
|
+
if (!item.active || !el)
|
|
85
|
+
return;
|
|
86
|
+
const scroller = getScrollParent(el);
|
|
87
|
+
if (!scroller)
|
|
88
|
+
return;
|
|
89
|
+
const scrollerRect = scroller.getBoundingClientRect();
|
|
90
|
+
const elRect = el.getBoundingClientRect();
|
|
91
|
+
const margin = elRect.height;
|
|
92
|
+
if (elRect.top < scrollerRect.top + margin) {
|
|
93
|
+
scroller.scrollTop -= scrollerRect.top + margin - elRect.top;
|
|
94
|
+
}
|
|
95
|
+
else if (elRect.bottom > scrollerRect.bottom - margin) {
|
|
96
|
+
scroller.scrollTop += elRect.bottom - (scrollerRect.bottom - margin);
|
|
97
|
+
}
|
|
98
|
+
}, [item.active]);
|
|
68
99
|
const handleOnClick = () => {
|
|
69
100
|
telemetry.sendSidebarItemClickedMessage([
|
|
70
101
|
Object.assign(Object.assign({}, (0, utils_1.getBaseDataAttributes)('sidebarItem', 'sidebar')), { label: item.label, type: item.type === 'link' || item.type === 'group' ? item.type : undefined }),
|
|
@@ -323,4 +354,14 @@ const BadgeIcon = (0, styled_components_1.default)(GenericIcon_1.GenericIcon) `
|
|
|
323
354
|
margin-right: var(--spacing-xxs);
|
|
324
355
|
flex-shrink: 0;
|
|
325
356
|
`;
|
|
357
|
+
/** Compares only the props that actually affect this row. `item` is expected
|
|
358
|
+
* to be reference-stable from the producer (e.g. `useMenuItems`) when the
|
|
359
|
+
* row's state hasn't changed; `onClick` and `children` are fresh JSX from
|
|
360
|
+
* the parent's `.map()` every render and would defeat the memo. */
|
|
361
|
+
exports.MenuItem = react_1.default.memo(MenuItemImpl, (prev, next) => {
|
|
362
|
+
return (prev.item === next.item &&
|
|
363
|
+
prev.depth === next.depth &&
|
|
364
|
+
prev.isMobile === next.isMobile &&
|
|
365
|
+
prev.className === next.className);
|
|
366
|
+
});
|
|
326
367
|
//# sourceMappingURL=MenuItem.js.map
|