@jetbrains/kotlin-web-site-ui 4.2.0-alpha.2 → 4.2.0-alpha.3
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/out/components/header/full-search/full-search.js +8 -1
- package/out/components/header/header.js +6 -16
- package/out/components/top-menu/dropdown-menu/dropdown-menu.js +14 -5
- package/out/components/top-menu/index.css +1 -13
- package/out/components/top-menu/top-menu.js +17 -11
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import React__default, { useState, useContext, useRef, useCallback, useLayoutEffect } from 'react';
|
|
1
|
+
import React__default, { useState, useContext, useRef, useCallback, useLayoutEffect, useEffect } from 'react';
|
|
2
|
+
import { disableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock';
|
|
2
3
|
import useScrollbarSize from 'react-scrollbar-size';
|
|
3
4
|
import { ThemeProvider } from '@rescui/ui-contexts';
|
|
4
5
|
import Input from '@rescui/input';
|
|
@@ -53,6 +54,12 @@ const FullSearch = ({
|
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
56
|
}, [hits, inputValue]);
|
|
57
|
+
useLayoutEffect(() => {
|
|
58
|
+
if (ref.current) disableBodyScroll(ref.current);
|
|
59
|
+
}, [ref]);
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
return clearAllBodyScrollLocks;
|
|
62
|
+
}, []);
|
|
56
63
|
return React__default.createElement(ThemeProvider, {
|
|
57
64
|
theme: 'light'
|
|
58
65
|
}, React__default.createElement("div", {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React__default, { forwardRef, useState, useMemo, useRef, useImperativeHandle, useLayoutEffect, useCallback, useEffect } from 'react';
|
|
2
2
|
import { ThemeProvider } from '@rescui/ui-contexts';
|
|
3
3
|
import FocusManager from '@rescui/focus-manager';
|
|
4
|
-
import useResizeObserver from '@react-hook/resize-observer';
|
|
5
4
|
import OutsideClickHandler from 'react-outside-click-handler';
|
|
6
5
|
import { LogoLarge } from './logo-large/logo-large.js';
|
|
7
6
|
import styles from './header.module.pcss.js';
|
|
@@ -15,7 +14,8 @@ import classNames from 'classnames';
|
|
|
15
14
|
import { SearchWrapper } from './search-wrapper/search-wrapper.js';
|
|
16
15
|
import { isMacOs } from './is-macos.js';
|
|
17
16
|
import { KEY_K_CODE } from './key-codes.js';
|
|
18
|
-
|
|
17
|
+
import useResizeObserver from '@react-hook/resize-observer';
|
|
18
|
+
const BREAKPOINT_XS = 640;
|
|
19
19
|
const Header = forwardRef(({
|
|
20
20
|
productWebUrl,
|
|
21
21
|
hasSearch = false,
|
|
@@ -27,21 +27,20 @@ const Header = forwardRef(({
|
|
|
27
27
|
linkHandler,
|
|
28
28
|
isPlayground,
|
|
29
29
|
isUrlActive,
|
|
30
|
-
searchConfig
|
|
31
|
-
noScrollClassName
|
|
30
|
+
searchConfig
|
|
32
31
|
}, forwardedRef) => {
|
|
33
32
|
const [menuPopupExpanded, setMenuPopupExpanded] = useState(false);
|
|
34
|
-
const [isMenuPopupVisible, setIsMenuPopupVisible] = useState(false);
|
|
35
33
|
const [isSearchBoxVisible, setSearchBoxVisible] = useState(false);
|
|
36
34
|
const [fullSearchActive, setFullSearchActive] = useState(false);
|
|
37
35
|
const items = useMemo(() => getNavScheme(isUrlActive, currentUrl, isPlayground), [isUrlActive, currentUrl, isPlayground]);
|
|
38
36
|
const itemsWithoutHomeSection = useMemo(() => items.slice(1), [items]);
|
|
39
37
|
const headerRef = useRef(null);
|
|
40
38
|
useImperativeHandle(forwardedRef, () => headerRef.current);
|
|
39
|
+
const [isMenuPopupVisible, setMenuPopupVisible] = useState(false);
|
|
41
40
|
useLayoutEffect(() => {
|
|
42
|
-
|
|
41
|
+
setMenuPopupVisible((headerRef.current?.getBoundingClientRect?.().width ?? 0) <= BREAKPOINT_XS);
|
|
43
42
|
}, [headerRef]);
|
|
44
|
-
useResizeObserver(headerRef, entry =>
|
|
43
|
+
useResizeObserver(headerRef, entry => setMenuPopupVisible(entry.contentRect.width <= BREAKPOINT_XS));
|
|
45
44
|
const handleSearchButtonClick = useCallback(() => {
|
|
46
45
|
setSearchBoxVisible(!isSearchBoxVisible);
|
|
47
46
|
}, []);
|
|
@@ -70,15 +69,6 @@ const Header = forwardRef(({
|
|
|
70
69
|
};
|
|
71
70
|
}
|
|
72
71
|
}, [fullSearchKeyHandler]);
|
|
73
|
-
useEffect(() => {
|
|
74
|
-
if (typeof document !== `undefined` && noScrollClassName) {
|
|
75
|
-
if (fullSearchActive) {
|
|
76
|
-
document.body.classList.add(noScrollClassName);
|
|
77
|
-
} else {
|
|
78
|
-
document.body.classList.remove(noScrollClassName);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}, [fullSearchActive]);
|
|
82
72
|
return React__default.createElement(ThemeProvider, {
|
|
83
73
|
theme: 'dark'
|
|
84
74
|
}, React__default.createElement(SearchWrapper, {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React__default, { useState } from 'react';
|
|
1
|
+
import React__default, { useState, useRef, useEffect, useCallback } from 'react';
|
|
2
2
|
import ReactDOM from 'react-dom';
|
|
3
3
|
import classNames from 'classnames';
|
|
4
4
|
import styles from './dropdown-menu.module.pcss.js';
|
|
@@ -7,6 +7,7 @@ import SvgArrowDropdownIcon from './arrow-dropdown-icon.svg.js';
|
|
|
7
7
|
import { useTheme } from '@rescui/ui-contexts';
|
|
8
8
|
import Button from '@rescui/button';
|
|
9
9
|
import { CloseIcon } from '@rescui/icons';
|
|
10
|
+
import { clearAllBodyScrollLocks, enableBodyScroll, disableBodyScroll } from 'body-scroll-lock';
|
|
10
11
|
|
|
11
12
|
const DropdownMenu = ({
|
|
12
13
|
homeUrl,
|
|
@@ -19,11 +20,14 @@ const DropdownMenu = ({
|
|
|
19
20
|
}) => {
|
|
20
21
|
const theme = useTheme();
|
|
21
22
|
const textCn = useTextStyles();
|
|
22
|
-
const [portalRoot, setPortalRoot] =
|
|
23
|
-
|
|
23
|
+
const [portalRoot, setPortalRoot] = useState(null);
|
|
24
|
+
const navRef = useRef(null);
|
|
25
|
+
useEffect(() => {
|
|
24
26
|
if (typeof document !== `undefined`) {
|
|
25
27
|
setPortalRoot(document.body);
|
|
26
28
|
}
|
|
29
|
+
|
|
30
|
+
return clearAllBodyScrollLocks;
|
|
27
31
|
}, []);
|
|
28
32
|
|
|
29
33
|
let _items = (mobileOverview ? [{
|
|
@@ -35,9 +39,13 @@ const DropdownMenu = ({
|
|
|
35
39
|
|
|
36
40
|
const activeItem = _items[_activeIndex];
|
|
37
41
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
42
|
+
const handleClick = useCallback(() => {
|
|
43
|
+
if (navRef.current) {
|
|
44
|
+
isExpanded ? enableBodyScroll(navRef.current) : disableBodyScroll(navRef.current);
|
|
45
|
+
}
|
|
38
46
|
|
|
39
|
-
|
|
40
|
-
|
|
47
|
+
setIsExpanded(!isExpanded);
|
|
48
|
+
}, [isExpanded, navRef]);
|
|
41
49
|
return React__default.createElement(React__default.Fragment, null, React__default.createElement("div", {
|
|
42
50
|
className: classNames(styles.dropdownMenu, {
|
|
43
51
|
[styles.dropdownMenuExpanded]: isExpanded
|
|
@@ -51,6 +59,7 @@ const DropdownMenu = ({
|
|
|
51
59
|
}, activeItem.title), React__default.createElement(SvgArrowDropdownIcon, {
|
|
52
60
|
className: styles.icon
|
|
53
61
|
})), React__default.createElement("nav", {
|
|
62
|
+
ref: navRef,
|
|
54
63
|
className: classNames(styles.dropdownList, {
|
|
55
64
|
[styles.dropdownListDarkTheme]: theme === 'dark'
|
|
56
65
|
})
|
|
@@ -75,12 +75,6 @@
|
|
|
75
75
|
color: var(--ktl-color-primary-light-theme);
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
@media (max-width: 640px) {
|
|
79
|
-
.ktl-horizontal-menu-module_horizontal-menu_pB2-S {
|
|
80
|
-
display: none;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
78
|
:root {
|
|
85
79
|
--ktl-light-grey: #f4f4f4;
|
|
86
80
|
--ktl-dark-100: rgba(39, 40, 44, 1);
|
|
@@ -119,7 +113,7 @@
|
|
|
119
113
|
}
|
|
120
114
|
|
|
121
115
|
.ktl-dropdown-menu-module_dropdown-menu_tq2uU {
|
|
122
|
-
display:
|
|
116
|
+
display: block;
|
|
123
117
|
height: 100%;
|
|
124
118
|
justify-self: flex-start;
|
|
125
119
|
white-space: nowrap;
|
|
@@ -225,12 +219,6 @@
|
|
|
225
219
|
background: #ffffff;
|
|
226
220
|
}
|
|
227
221
|
|
|
228
|
-
@media (max-width: 640px) {
|
|
229
|
-
.ktl-dropdown-menu-module_dropdown-menu_tq2uU {
|
|
230
|
-
display: block;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
222
|
@-webkit-keyframes ktl-dropdown-menu-module_fadein_MySnq {
|
|
235
223
|
0% {
|
|
236
224
|
opacity: 0;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import React__default from 'react';
|
|
1
|
+
import React__default, { forwardRef, useRef, useImperativeHandle, useState, useLayoutEffect } from 'react';
|
|
2
2
|
import { useTheme } from '@rescui/ui-contexts';
|
|
3
3
|
import classNames from 'classnames';
|
|
4
4
|
import styles from './top-menu.module.pcss.js';
|
|
5
5
|
import { useTextStyles } from '@rescui/typography';
|
|
6
6
|
import { HorizontalMenu } from './horizontal-menu/horizontal-menu.js';
|
|
7
7
|
import { DropdownMenu } from './dropdown-menu/dropdown-menu.js';
|
|
8
|
-
|
|
9
|
-
const
|
|
8
|
+
import useResizeObserver from '@react-hook/resize-observer';
|
|
9
|
+
const BREAKPOINT_XS = 640;
|
|
10
|
+
const TopMenu = forwardRef(({
|
|
10
11
|
homeUrl,
|
|
11
12
|
title,
|
|
12
13
|
mobileTitle,
|
|
@@ -15,21 +16,27 @@ const TopMenu = ({
|
|
|
15
16
|
linkHandler = () => {},
|
|
16
17
|
className,
|
|
17
18
|
children,
|
|
18
|
-
forwardedRef,
|
|
19
19
|
mobileOverview
|
|
20
|
-
}) => {
|
|
20
|
+
}, forwardedRef) => {
|
|
21
21
|
const theme = useTheme();
|
|
22
22
|
const textCn = useTextStyles();
|
|
23
|
+
const menuRef = useRef(null);
|
|
24
|
+
useImperativeHandle(forwardedRef, () => menuRef.current);
|
|
25
|
+
const [isMobileMenuVisible, setMobileMenuVisible] = useState(false);
|
|
26
|
+
useLayoutEffect(() => {
|
|
27
|
+
setMobileMenuVisible((menuRef.current?.getBoundingClientRect?.().width ?? 0) <= BREAKPOINT_XS);
|
|
28
|
+
}, [menuRef]);
|
|
29
|
+
useResizeObserver(menuRef, entry => setMobileMenuVisible(entry.contentRect.width <= BREAKPOINT_XS));
|
|
23
30
|
return React__default.createElement("div", {
|
|
31
|
+
ref: menuRef,
|
|
24
32
|
className: classNames(styles.topMenu, className, {
|
|
25
33
|
[styles.topMenuDarkTheme]: theme === 'dark'
|
|
26
|
-
})
|
|
27
|
-
ref: forwardedRef
|
|
34
|
+
})
|
|
28
35
|
}, React__default.createElement("a", {
|
|
29
36
|
href: homeUrl,
|
|
30
37
|
className: classNames(styles.logo, textCn('rs-h3')),
|
|
31
38
|
onClick: event => linkHandler(event, homeUrl)
|
|
32
|
-
}, title), React__default.createElement(DropdownMenu, {
|
|
39
|
+
}, title), isMobileMenuVisible ? React__default.createElement(DropdownMenu, {
|
|
33
40
|
items: items,
|
|
34
41
|
activeIndex: activeIndex,
|
|
35
42
|
linkHandler: linkHandler,
|
|
@@ -37,11 +44,10 @@ const TopMenu = ({
|
|
|
37
44
|
mobileTitle: mobileTitle,
|
|
38
45
|
homeUrl: homeUrl,
|
|
39
46
|
mobileOverview: mobileOverview
|
|
40
|
-
})
|
|
47
|
+
}) : React__default.createElement(HorizontalMenu, {
|
|
41
48
|
items: items,
|
|
42
49
|
activeIndex: activeIndex,
|
|
43
50
|
linkHandler: linkHandler
|
|
44
51
|
}), children);
|
|
45
|
-
};
|
|
46
|
-
|
|
52
|
+
});
|
|
47
53
|
export { TopMenu };
|