@jetbrains/kotlin-web-site-ui 4.2.0-alpha.3 → 4.2.0-alpha.4

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.
@@ -96,23 +96,7 @@
96
96
  --rs-font-family-ui: var(--ktl-font-family-inter);
97
97
  }
98
98
 
99
- .ktl-dropdown-menu-module_overlay_segRo {
100
- display: none;
101
- position: fixed;
102
- top: 0;
103
- right: 0;
104
- bottom: 0;
105
- left: 0;
106
- width: 100%;
107
- height: 100%;
108
- opacity: 0;
109
- background-color: var(--ktl-color-dark-40);
110
- z-index: var(--ktl-overlay-z-index);
111
- -webkit-animation: ktl-dropdown-menu-module_fadein_MySnq ease-out var(--ktl-transition-fast) forwards;
112
- animation: ktl-dropdown-menu-module_fadein_MySnq ease-out var(--ktl-transition-fast) forwards;
113
- }
114
-
115
- .ktl-dropdown-menu-module_dropdown-menu_tq2uU {
99
+ .ktl-vertical-menu-module_vertical-menu_aLIbw {
116
100
  display: block;
117
101
  height: 100%;
118
102
  justify-self: flex-start;
@@ -122,7 +106,7 @@
122
106
  max-width: 100%;
123
107
  }
124
108
 
125
- .ktl-dropdown-menu-module_button_OYsuv {
109
+ .ktl-vertical-menu-module_button_zqr20 {
126
110
  border: none;
127
111
  background: none;
128
112
  height: 100%;
@@ -135,13 +119,13 @@
135
119
  cursor: pointer;
136
120
  }
137
121
 
138
- .ktl-dropdown-menu-module_button-text_SJmh- {
122
+ .ktl-vertical-menu-module_button-text_aXith {
139
123
  overflow: hidden;
140
124
  text-overflow: ellipsis;
141
125
  flex: 0 1 auto;
142
126
  }
143
127
 
144
- .ktl-dropdown-menu-module_icon_GGhMI {
128
+ .ktl-vertical-menu-module_icon_-Ieat {
145
129
  width: 12px;
146
130
  height: 6px;
147
131
  margin-left: 6px;
@@ -149,7 +133,9 @@
149
133
  flex: 0 0 auto;
150
134
  }
151
135
 
152
- .ktl-dropdown-menu-module_dropdown-header_fa92T {
136
+ .ktl-vertical-menu-module_dropdown-header_77lTy {
137
+ /* workaround */
138
+ margin-top: calc(var(--ktl-header-height-mobile) * -1);
153
139
  display: flex;
154
140
  color: #ffffff;
155
141
  align-items: center;
@@ -157,82 +143,58 @@
157
143
  padding: 0 0 0 16px;
158
144
  border-bottom: 1px solid rgba(255, 255, 255, 0.3);
159
145
  justify-content: space-between;
146
+ background: #ffffff;
160
147
  }
161
148
 
162
- .ktl-dropdown-menu-module_dropdown-list_Ylkvt {
163
- display: none;
149
+ .ktl-vertical-menu-module_dropdown-list_N3KWV {
150
+ display: flex;
151
+ flex-direction: column;
152
+ opacity: 1;
164
153
  position: fixed;
165
154
  top: 0;
166
155
  left: 0;
167
156
  right: 0;
168
157
  bottom: 0;
169
158
  background: #ffffff;
170
- opacity: 0;
171
- -webkit-animation: ktl-dropdown-menu-module_fadein_MySnq ease-out var(--ktl-transition-fast) forwards;
172
- animation: ktl-dropdown-menu-module_fadein_MySnq ease-out var(--ktl-transition-fast) forwards;
173
159
  z-index: var(--ktl-mobile-dropdown-list-z-index);
174
160
  }
175
161
 
176
- .ktl-dropdown-menu-module_dropdown-item_X3tZ- {
162
+ .ktl-vertical-menu-module_dropdown-item_XLfp4 {
177
163
  padding: 12px 16px;
178
164
  text-decoration: none;
179
165
  transition: color var(--ktl-transition-xfast),
180
166
  background-color var(--ktl-transition-xfast);
181
167
  }
182
168
 
183
- .ktl-dropdown-menu-module_dropdown-item_X3tZ-:hover {
169
+ .ktl-vertical-menu-module_dropdown-item_XLfp4:hover {
184
170
  background: rgba(39, 40, 44, 0.1);
185
171
  color: #27282c;
186
172
  }
187
173
 
188
- .ktl-dropdown-menu-module_dropdown-item_X3tZ-.ktl-dropdown-menu-module_dropdown-item-active_99q9X {
174
+ .ktl-vertical-menu-module_dropdown-item_XLfp4.ktl-vertical-menu-module_dropdown-item-active_iBUbj {
189
175
  background: var(--ktl-dark-100);
190
176
  color: #ffffff;
191
177
  }
192
178
 
193
- .ktl-dropdown-menu-module_overlay-visible_MjwEF {
194
- display: block;
195
- opacity: 1;
196
- }
197
-
198
- .ktl-dropdown-menu-module_dropdown-menu-expanded_EQefy .ktl-dropdown-menu-module_icon_GGhMI {
179
+ .ktl-vertical-menu-module_vertical-menu-expanded_kFaaI .ktl-vertical-menu-module_icon_-Ieat {
199
180
  transform: scale(1, -1);
200
181
  }
201
182
 
202
- .ktl-dropdown-menu-module_dropdown-menu-expanded_EQefy .ktl-dropdown-menu-module_dropdown-list_Ylkvt {
203
- display: flex;
204
- flex-direction: column;
205
- opacity: 1;
206
- }
207
-
208
- .ktl-dropdown-menu-module_dropdown-list-dark-theme_P60ol {
183
+ .ktl-vertical-menu-module_dropdown-list-dark-theme_A1-Bw {
209
184
  background: rgba(39, 40, 44, 1);
210
185
  }
211
186
 
212
- .ktl-dropdown-menu-module_dropdown-list-dark-theme_P60ol .ktl-dropdown-menu-module_dropdown-item_X3tZ-:hover {
187
+ .ktl-vertical-menu-module_dropdown-list-dark-theme_A1-Bw .ktl-vertical-menu-module_dropdown-header_77lTy {
188
+ background: rgba(39, 40, 44, 1);
189
+ }
190
+
191
+ .ktl-vertical-menu-module_dropdown-list-dark-theme_A1-Bw .ktl-vertical-menu-module_dropdown-item_XLfp4:hover {
213
192
  background: rgba(255, 255, 255, 0.1);
214
193
  color: #ffffff;
215
194
  }
216
195
 
217
- .ktl-dropdown-menu-module_dropdown-list-dark-theme_P60ol .ktl-dropdown-menu-module_dropdown-item_X3tZ-.ktl-dropdown-menu-module_dropdown-item-active_99q9X {
196
+ .ktl-vertical-menu-module_dropdown-list-dark-theme_A1-Bw .ktl-vertical-menu-module_dropdown-item_XLfp4.ktl-vertical-menu-module_dropdown-item-active_iBUbj {
218
197
  color: var(--ktl-light-text-hard);
219
198
  background: #ffffff;
220
199
  }
221
200
 
222
- @-webkit-keyframes ktl-dropdown-menu-module_fadein_MySnq {
223
- 0% {
224
- opacity: 0;
225
- }
226
- 100% {
227
- opacity: 1;
228
- }
229
- }
230
-
231
- @keyframes ktl-dropdown-menu-module_fadein_MySnq {
232
- 0% {
233
- opacity: 0;
234
- }
235
- 100% {
236
- opacity: 1;
237
- }
238
- }
@@ -4,7 +4,7 @@ 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
- import { DropdownMenu } from './dropdown-menu/dropdown-menu.js';
7
+ import { VerticalMenu } from './vertical-menu/vertical-menu.js';
8
8
  import useResizeObserver from '@react-hook/resize-observer';
9
9
  const BREAKPOINT_XS = 640;
10
10
  const TopMenu = forwardRef(({
@@ -36,14 +36,15 @@ const TopMenu = forwardRef(({
36
36
  href: homeUrl,
37
37
  className: classNames(styles.logo, textCn('rs-h3')),
38
38
  onClick: event => linkHandler(event, homeUrl)
39
- }, title), isMobileMenuVisible ? React__default.createElement(DropdownMenu, {
39
+ }, title), isMobileMenuVisible ? React__default.createElement(VerticalMenu, {
40
40
  items: items,
41
41
  activeIndex: activeIndex,
42
42
  linkHandler: linkHandler,
43
43
  title: title,
44
44
  mobileTitle: mobileTitle,
45
45
  homeUrl: homeUrl,
46
- mobileOverview: mobileOverview
46
+ mobileOverview: mobileOverview,
47
+ topMenuRef: menuRef
47
48
  }) : React__default.createElement(HorizontalMenu, {
48
49
  items: items,
49
50
  activeIndex: activeIndex,
@@ -1,34 +1,25 @@
1
- import React__default, { useState, useRef, useEffect, useCallback } from 'react';
2
- import ReactDOM from 'react-dom';
1
+ import React__default, { useState, useCallback, useEffect, useRef, useLayoutEffect } from 'react';
3
2
  import classNames from 'classnames';
4
- import styles from './dropdown-menu.module.pcss.js';
3
+ import styles from './vertical-menu.module.pcss.js';
5
4
  import { useTextStyles } from '@rescui/typography';
6
5
  import SvgArrowDropdownIcon from './arrow-dropdown-icon.svg.js';
7
6
  import { useTheme } from '@rescui/ui-contexts';
8
7
  import Button from '@rescui/button';
9
8
  import { CloseIcon } from '@rescui/icons';
10
- import { clearAllBodyScrollLocks, enableBodyScroll, disableBodyScroll } from 'body-scroll-lock';
9
+ import { disableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock';
10
+ import { createPortal } from 'react-dom';
11
11
 
12
- const DropdownMenu = ({
12
+ const VerticalMenu = ({
13
13
  homeUrl,
14
14
  title,
15
15
  mobileTitle = 'Overview',
16
16
  items,
17
17
  activeIndex,
18
18
  linkHandler,
19
- mobileOverview = true
19
+ mobileOverview = true,
20
+ topMenuRef
20
21
  }) => {
21
- const theme = useTheme();
22
22
  const textCn = useTextStyles();
23
- const [portalRoot, setPortalRoot] = useState(null);
24
- const navRef = useRef(null);
25
- useEffect(() => {
26
- if (typeof document !== `undefined`) {
27
- setPortalRoot(document.body);
28
- }
29
-
30
- return clearAllBodyScrollLocks;
31
- }, []);
32
23
 
33
24
  let _items = (mobileOverview ? [{
34
25
  title: mobileTitle,
@@ -39,13 +30,18 @@ const DropdownMenu = ({
39
30
 
40
31
  const activeItem = _items[_activeIndex];
41
32
  const [isExpanded, setIsExpanded] = useState(false);
42
- const handleClick = useCallback(() => {
43
- if (navRef.current) {
44
- isExpanded ? enableBodyScroll(navRef.current) : disableBodyScroll(navRef.current);
33
+ const [portalRoot, setPortalRoot] = useState(null);
34
+ const handleOpen = useCallback(() => {
35
+ setIsExpanded(true);
36
+ }, []);
37
+ const handleClose = useCallback(() => {
38
+ setIsExpanded(false);
39
+ }, []);
40
+ useEffect(() => {
41
+ if (typeof document !== `undefined`) {
42
+ setPortalRoot(document.body);
45
43
  }
46
-
47
- setIsExpanded(!isExpanded);
48
- }, [isExpanded, navRef]);
44
+ }, []);
49
45
  return React__default.createElement(React__default.Fragment, null, React__default.createElement("div", {
50
46
  className: classNames(styles.dropdownMenu, {
51
47
  [styles.dropdownMenuExpanded]: isExpanded
@@ -53,13 +49,50 @@ const DropdownMenu = ({
53
49
  }, React__default.createElement("button", {
54
50
  className: classNames(styles.button, textCn('rs-text-2')),
55
51
  "aria-haspopup": "true",
56
- onClick: handleClick
52
+ onClick: handleOpen
57
53
  }, React__default.createElement("span", {
58
54
  className: styles.buttonText
59
55
  }, activeItem.title), React__default.createElement(SvgArrowDropdownIcon, {
60
56
  className: styles.icon
61
- })), React__default.createElement("nav", {
57
+ })), !!portalRoot && isExpanded && createPortal(React__default.createElement(VerticalMenuDropDown, {
58
+ title: title,
59
+ activeIndex: _activeIndex,
60
+ items: _items,
61
+ onClose: handleClose,
62
+ linkHandler: linkHandler,
63
+ topMenuRef: topMenuRef
64
+ }), portalRoot)));
65
+ };
66
+
67
+ const VerticalMenuDropDown = ({
68
+ title,
69
+ onClose,
70
+ items,
71
+ linkHandler,
72
+ activeIndex,
73
+ topMenuRef
74
+ }) => {
75
+ const textCn = useTextStyles();
76
+ const theme = useTheme();
77
+ const navRef = useRef(null);
78
+ const [navStyle, setNavStyle] = useState({});
79
+ useEffect(() => {
80
+ if (navRef.current) {
81
+ disableBodyScroll(navRef.current);
82
+ }
83
+
84
+ return clearAllBodyScrollLocks;
85
+ }, []);
86
+ useLayoutEffect(() => {
87
+ if (topMenuRef.current) {
88
+ setNavStyle({
89
+ top: topMenuRef.current.getBoundingClientRect().top
90
+ });
91
+ }
92
+ }, [topMenuRef]);
93
+ return React__default.createElement("nav", {
62
94
  ref: navRef,
95
+ style: navStyle,
63
96
  className: classNames(styles.dropdownList, {
64
97
  [styles.dropdownListDarkTheme]: theme === 'dark'
65
98
  })
@@ -71,21 +104,16 @@ const DropdownMenu = ({
71
104
  mode: 'clear',
72
105
  size: 'l',
73
106
  icon: React__default.createElement(CloseIcon, null),
74
- onClick: handleClick
75
- })), _items.map((item, index) => React__default.createElement("a", {
107
+ onClick: onClose
108
+ })), items.map((item, index) => React__default.createElement("a", {
76
109
  key: item.url,
77
110
  href: item.url,
78
111
  className: classNames(styles.dropdownItem, textCn('rs-text-1'), {
79
- [styles.dropdownItemActive]: index === _activeIndex
112
+ [styles.dropdownItemActive]: index === activeIndex
80
113
  }),
81
114
  onClick: event => linkHandler?.(event, item.url),
82
115
  target: item.isExternal ? '_blank' : undefined
83
- }, item.title)))), !!portalRoot && ReactDOM.createPortal(React__default.createElement("div", {
84
- className: classNames(styles.overlay, {
85
- [styles.overlayVisible]: isExpanded
86
- }),
87
- onClick: handleClick
88
- }), portalRoot));
116
+ }, item.title)));
89
117
  };
90
118
 
91
- export { DropdownMenu };
119
+ export { VerticalMenu };
@@ -0,0 +1,13 @@
1
+ var styles = {
2
+ "verticalMenu": "ktl-vertical-menu-module_vertical-menu_aLIbw",
3
+ "button": "ktl-vertical-menu-module_button_zqr20",
4
+ "buttonText": "ktl-vertical-menu-module_button-text_aXith",
5
+ "icon": "ktl-vertical-menu-module_icon_-Ieat",
6
+ "dropdownHeader": "ktl-vertical-menu-module_dropdown-header_77lTy",
7
+ "dropdownList": "ktl-vertical-menu-module_dropdown-list_N3KWV",
8
+ "dropdownItem": "ktl-vertical-menu-module_dropdown-item_XLfp4",
9
+ "dropdownItemActive": "ktl-vertical-menu-module_dropdown-item-active_iBUbj",
10
+ "verticalMenuExpanded": "ktl-vertical-menu-module_vertical-menu-expanded_kFaaI",
11
+ "dropdownListDarkTheme": "ktl-vertical-menu-module_dropdown-list-dark-theme_A1-Bw"
12
+ };
13
+ export { styles as default };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jetbrains/kotlin-web-site-ui",
3
3
  "description": "UI components for Kotlin web sites development",
4
- "version": "4.2.0-alpha.3",
4
+ "version": "4.2.0-alpha.4",
5
5
  "license": "Apache-2.0",
6
6
  "author": "JetBrains",
7
7
  "files": [
@@ -1,16 +0,0 @@
1
- var styles = {
2
- "overlay": "ktl-dropdown-menu-module_overlay_segRo",
3
- "fadein": "ktl-dropdown-menu-module_fadein_MySnq",
4
- "dropdownMenu": "ktl-dropdown-menu-module_dropdown-menu_tq2uU",
5
- "button": "ktl-dropdown-menu-module_button_OYsuv",
6
- "buttonText": "ktl-dropdown-menu-module_button-text_SJmh-",
7
- "icon": "ktl-dropdown-menu-module_icon_GGhMI",
8
- "dropdownHeader": "ktl-dropdown-menu-module_dropdown-header_fa92T",
9
- "dropdownList": "ktl-dropdown-menu-module_dropdown-list_Ylkvt",
10
- "dropdownItem": "ktl-dropdown-menu-module_dropdown-item_X3tZ-",
11
- "dropdownItemActive": "ktl-dropdown-menu-module_dropdown-item-active_99q9X",
12
- "overlayVisible": "ktl-dropdown-menu-module_overlay-visible_MjwEF",
13
- "dropdownMenuExpanded": "ktl-dropdown-menu-module_dropdown-menu-expanded_EQefy",
14
- "dropdownListDarkTheme": "ktl-dropdown-menu-module_dropdown-list-dark-theme_P60ol"
15
- };
16
- export { styles as default };