@rescui/dropdown-menu 0.12.1 → 0.13.0

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.
@@ -1,4 +1,6 @@
1
1
  "use client";
2
+ import _extends from '@babel/runtime-corejs3/helpers/esm/extends';
3
+ import { c } from 'react-compiler-runtime';
2
4
  import React, { useState } from 'react';
3
5
  import { useThemeWithUndefined } from '@rescui/ui-contexts';
4
6
  import { Dropdown } from '@rescui/dropdown';
@@ -6,6 +8,7 @@ import { Menu } from '@rescui/menu';
6
8
  import cn from 'classnames';
7
9
  import { MenuWrapper } from './menu-wrapper.js';
8
10
  import styles from './dropdown-menu.p.module.css.js';
11
+ import { useExtractCssValues } from './use-extract-css-values.js';
9
12
  const ITEM_HEIGHT_BY_SIZE = {
10
13
  s: 32,
11
14
  m: 40,
@@ -17,80 +20,195 @@ const SIZE_TO_CLASS = {
17
20
  l: styles.sizeL
18
21
  };
19
22
 
20
- const DropdownMenu = _ref => {
21
- let {
22
- maxVisibleItems = 5,
23
- size = 'm',
24
- children,
25
- iconPlacement,
26
- itemTag,
27
- tag,
28
- theme: themeFromProps,
29
- mode = 'classic',
30
- activateFirstItemOnOpen = false,
31
- resizeIcons = true,
32
- wrapItemsWithLi,
33
- className,
34
- ...restProps
35
- } = _ref;
23
+ const DropdownMenu = t0 => {
24
+ const $ = c(43);
25
+ let children;
26
+ let className;
27
+ let iconPlacement;
28
+ let itemTag;
29
+ let restProps;
30
+ let t1;
31
+ let t2;
32
+ let t3;
33
+ let t4;
34
+ let t5;
35
+ let tag;
36
+ let themeFromProps;
37
+ let wrapItemsWithLi;
38
+
39
+ if ($[0] !== t0) {
40
+ ({
41
+ maxVisibleItems: t1,
42
+ size: t2,
43
+ children,
44
+ iconPlacement,
45
+ itemTag,
46
+ tag,
47
+ theme: themeFromProps,
48
+ mode: t3,
49
+ activateFirstItemOnOpen: t4,
50
+ resizeIcons: t5,
51
+ wrapItemsWithLi,
52
+ className,
53
+ ...restProps
54
+ } = t0);
55
+ $[0] = t0;
56
+ $[1] = children;
57
+ $[2] = className;
58
+ $[3] = iconPlacement;
59
+ $[4] = itemTag;
60
+ $[5] = restProps;
61
+ $[6] = t1;
62
+ $[7] = t2;
63
+ $[8] = t3;
64
+ $[9] = t4;
65
+ $[10] = t5;
66
+ $[11] = tag;
67
+ $[12] = themeFromProps;
68
+ $[13] = wrapItemsWithLi;
69
+ } else {
70
+ children = $[1];
71
+ className = $[2];
72
+ iconPlacement = $[3];
73
+ itemTag = $[4];
74
+ restProps = $[5];
75
+ t1 = $[6];
76
+ t2 = $[7];
77
+ t3 = $[8];
78
+ t4 = $[9];
79
+ t5 = $[10];
80
+ tag = $[11];
81
+ themeFromProps = $[12];
82
+ wrapItemsWithLi = $[13];
83
+ }
84
+
85
+ const maxVisibleItems = t1 === undefined ? 5 : t1;
86
+ const size = t2 === undefined ? "m" : t2;
87
+ const mode = t3 === undefined ? "classic" : t3;
88
+ const activateFirstItemOnOpen = t4 === undefined ? false : t4;
89
+ const resizeIcons = t5 === undefined ? true : t5;
36
90
  const [menuWrapperEl, setMenuWrapperEl] = useState(null);
37
91
  const [height, setHeight] = useState(0);
38
- let itemHeightFromCss = null;
39
- let contrastPrimaryFromCss = null;
40
-
41
- if (menuWrapperEl) {
42
- // In theory this part of the code might cause issues with SSR.
43
- // But in this specific context, because of checking state ref "menuWrapperEl",
44
- // we are sure that the value will still be "null" on the first render.
45
- // Therefore, the first render on the client will be the same as on the server.
46
- // Also, there will be no layout shifts on the following renders because
47
- // it's a dropdown-content and in most cases it opens only on-demand
48
- const menuWrapperStyles = getComputedStyle(menuWrapperEl);
49
- itemHeightFromCss = parseInt(menuWrapperStyles.getPropertyValue('--_rs-dropdown-menu-item-height'), 10) || null;
50
- contrastPrimaryFromCss = parseInt(menuWrapperStyles.getPropertyValue('--rs-dropdown-menu-contrast-primary'), 10) || null;
92
+ const {
93
+ itemHeightFromCss,
94
+ contrastPrimaryFromCss
95
+ } = useExtractCssValues(menuWrapperEl);
96
+ const itemHeight = itemHeightFromCss || ITEM_HEIGHT_BY_SIZE[size];
97
+ const isMoreThanPlusOne = height > (Math.ceil(maxVisibleItems) + 1.1) * itemHeight;
98
+ const maxHeight = (Math.ceil(maxVisibleItems) + (isMoreThanPlusOne ? 0.5 : 1.5)) * itemHeight;
99
+ let cleanedRestProps;
100
+
101
+ if ($[14] !== restProps) {
102
+ const {
103
+ maxHeight: cleanMaxHeight,
104
+ leastMaxHeight,
105
+ ...t6
106
+ } = restProps;
107
+ cleanedRestProps = t6;
108
+ $[14] = restProps;
109
+ $[15] = cleanedRestProps;
110
+ } else {
111
+ cleanedRestProps = $[15];
51
112
  }
52
113
 
53
- const itemHeight = itemHeightFromCss || ITEM_HEIGHT_BY_SIZE[size]; // a little buffer of 10% here
114
+ const theme = useThemeWithUndefined(themeFromProps);
115
+ const t6 = SIZE_TO_CLASS[size];
116
+ let t7;
54
117
 
55
- const isMoreThanPlusOne = height > (Math.ceil(maxVisibleItems) + 1.1) * itemHeight; // half of item added to show that there is more items even if scroll bar hidden
56
- // in case there are only 1 more item than maxVisibleItems, show it without truncating
118
+ if ($[16] !== className || $[17] !== t6) {
119
+ t7 = cn(t6, styles.dropdownMenu, className);
120
+ $[16] = className;
121
+ $[17] = t6;
122
+ $[18] = t7;
123
+ } else {
124
+ t7 = $[18];
125
+ }
57
126
 
58
- const maxHeight = (Math.ceil(maxVisibleItems) + (isMoreThanPlusOne ? 0.5 : 1.5)) * itemHeight;
59
- const {
60
- maxHeight: cleanMaxHeight,
61
- leastMaxHeight,
62
- ...cleanedRestProps
63
- } = restProps; // cast to make runtime omit
127
+ const t8 = mode === "rock" ? "rock" : "classic";
128
+ let t9;
64
129
 
65
- const theme = useThemeWithUndefined(themeFromProps);
66
- return /*#__PURE__*/React.createElement(Dropdown, { ...cleanedRestProps,
67
- closeOnTab: true,
68
- mode: mode,
69
- theme: theme,
70
- leastMaxHeight: itemHeight,
71
- maxHeight: maxHeight,
72
- className: cn(SIZE_TO_CLASS[size], styles.dropdownMenu, className)
73
- }, /*#__PURE__*/React.createElement(MenuWrapper, {
74
- el: menuWrapperEl,
75
- setEl: setMenuWrapperEl,
76
- onHeightUpdate: setHeight
77
- }, /*#__PURE__*/React.createElement(Menu, {
78
- size: size,
79
- iconPlacement: iconPlacement,
80
- itemTag: itemTag,
81
- tag: tag,
82
- mode: mode === 'rock' ? 'rock' : 'classic',
83
- "data-test": "dropdown-menu",
84
- "data-rs-internal": 'dropdown-menu__menu',
85
- className: styles.menu,
86
- style: {
87
- '--rs-menu-contrast-primary': contrastPrimaryFromCss
88
- },
89
- enableKeyboardNavigation: true,
90
- activateFirstItem: activateFirstItemOnOpen,
91
- wrapItemsWithLi: wrapItemsWithLi,
92
- resizeIcons: resizeIcons
93
- }, children)));
130
+ if ($[19] !== contrastPrimaryFromCss) {
131
+ t9 = {
132
+ "--rs-menu-contrast-primary": contrastPrimaryFromCss
133
+ };
134
+ $[19] = contrastPrimaryFromCss;
135
+ $[20] = t9;
136
+ } else {
137
+ t9 = $[20];
138
+ }
139
+
140
+ let t10;
141
+
142
+ if ($[21] !== activateFirstItemOnOpen || $[22] !== children || $[23] !== iconPlacement || $[24] !== itemTag || $[25] !== resizeIcons || $[26] !== size || $[27] !== t8 || $[28] !== t9 || $[29] !== tag || $[30] !== wrapItemsWithLi) {
143
+ t10 = /*#__PURE__*/React.createElement(Menu, {
144
+ size: size,
145
+ iconPlacement: iconPlacement,
146
+ itemTag: itemTag,
147
+ tag: tag,
148
+ mode: t8,
149
+ "data-test": "dropdown-menu",
150
+ "data-rs-internal": "dropdown-menu__menu",
151
+ className: styles.menu,
152
+ style: t9,
153
+ enableKeyboardNavigation: true,
154
+ activateFirstItem: activateFirstItemOnOpen,
155
+ wrapItemsWithLi: wrapItemsWithLi,
156
+ resizeIcons: resizeIcons
157
+ }, children);
158
+ $[21] = activateFirstItemOnOpen;
159
+ $[22] = children;
160
+ $[23] = iconPlacement;
161
+ $[24] = itemTag;
162
+ $[25] = resizeIcons;
163
+ $[26] = size;
164
+ $[27] = t8;
165
+ $[28] = t9;
166
+ $[29] = tag;
167
+ $[30] = wrapItemsWithLi;
168
+ $[31] = t10;
169
+ } else {
170
+ t10 = $[31];
171
+ }
172
+
173
+ let t11;
174
+
175
+ if ($[32] !== menuWrapperEl || $[33] !== t10) {
176
+ t11 = /*#__PURE__*/React.createElement(MenuWrapper, {
177
+ el: menuWrapperEl,
178
+ setEl: setMenuWrapperEl,
179
+ onHeightUpdate: setHeight
180
+ }, t10);
181
+ $[32] = menuWrapperEl;
182
+ $[33] = t10;
183
+ $[34] = t11;
184
+ } else {
185
+ t11 = $[34];
186
+ }
187
+
188
+ let t12;
189
+
190
+ if ($[35] !== cleanedRestProps || $[36] !== itemHeight || $[37] !== maxHeight || $[38] !== mode || $[39] !== t11 || $[40] !== t7 || $[41] !== theme) {
191
+ t12 = /*#__PURE__*/React.createElement(Dropdown, _extends({}, cleanedRestProps, {
192
+ closeOnTab: true,
193
+ mode: mode,
194
+ theme: theme,
195
+ leastMaxHeight: itemHeight,
196
+ maxHeight: maxHeight,
197
+ className: t7
198
+ }), t11);
199
+ $[35] = cleanedRestProps;
200
+ $[36] = itemHeight;
201
+ $[37] = maxHeight;
202
+ $[38] = mode;
203
+ $[39] = t11;
204
+ $[40] = t7;
205
+ $[41] = theme;
206
+ $[42] = t12;
207
+ } else {
208
+ t12 = $[42];
209
+ }
210
+
211
+ return t12;
94
212
  };
95
213
 
96
214
  export { DropdownMenu, DropdownMenu as default };
@@ -1,8 +1,8 @@
1
1
  var styles = {
2
- "sizeS": "_sizeS_17ghxyl_8",
3
- "sizeM": "_sizeM_17ghxyl_11",
4
- "sizeL": "_sizeL_17ghxyl_14",
5
- "dropdownMenu": "_dropdownMenu_17ghxyl_18",
6
- "menu": "_menu_17ghxyl_23"
2
+ "sizeS": "_sizeS_n0urep_8",
3
+ "sizeM": "_sizeM_n0urep_11",
4
+ "sizeL": "_sizeL_n0urep_14",
5
+ "dropdownMenu": "_dropdownMenu_n0urep_18",
6
+ "menu": "_menu_n0urep_23"
7
7
  };
8
8
  export { styles as default };
package/lib/index.css CHANGED
@@ -1,29 +1,29 @@
1
- ._sizeS_17ghxyl_8{
1
+ ._sizeS_n0urep_8{
2
2
  --_rs-dropdown-menu-min-width:316px;
3
3
  --_rs-dropdown-menu-max-width:389px;
4
4
  }
5
- ._sizeS_17ghxyl_8 [data-rs-internal='dropdown-menu__menu-wrapper']{
5
+ ._sizeS_n0urep_8 [data-rs-internal='dropdown-menu__menu-wrapper']{
6
6
  --_rs-dropdown-menu-item-height:32px;
7
7
  }
8
- ._sizeM_17ghxyl_11{
8
+ ._sizeM_n0urep_11{
9
9
  --_rs-dropdown-menu-min-width:316px;
10
10
  --_rs-dropdown-menu-max-width:494px;
11
11
  }
12
- ._sizeM_17ghxyl_11 [data-rs-internal='dropdown-menu__menu-wrapper']{
12
+ ._sizeM_n0urep_11 [data-rs-internal='dropdown-menu__menu-wrapper']{
13
13
  --_rs-dropdown-menu-item-height:40px;
14
14
  }
15
- ._sizeL_17ghxyl_14{
15
+ ._sizeL_n0urep_14{
16
16
  --_rs-dropdown-menu-min-width:316px;
17
17
  --_rs-dropdown-menu-max-width:494px;
18
18
  }
19
- ._sizeL_17ghxyl_14 [data-rs-internal='dropdown-menu__menu-wrapper']{
19
+ ._sizeL_n0urep_14 [data-rs-internal='dropdown-menu__menu-wrapper']{
20
20
  --_rs-dropdown-menu-item-height:52px;
21
21
  }
22
- ._dropdownMenu_17ghxyl_18{
22
+ ._dropdownMenu_n0urep_18{
23
23
  min-width:var(--_rs-dropdown-menu-min-width);
24
24
  max-width:var(--_rs-dropdown-menu-max-width);
25
25
  }
26
- ._menu_17ghxyl_23{
26
+ ._menu_n0urep_23{
27
27
  margin:0;
28
28
  padding:0;
29
29
 
@@ -1,18 +1,42 @@
1
+ import { c } from 'react-compiler-runtime';
1
2
  import React from 'react';
2
3
  import { useResizeObserver } from '@rescui/use-resize-observer';
3
4
 
4
- const MenuWrapper = _ref => {
5
- let {
5
+ const MenuWrapper = t0 => {
6
+ const $ = c(5);
7
+ const {
6
8
  children,
7
9
  onHeightUpdate,
8
10
  setEl,
9
11
  el
10
- } = _ref;
11
- useResizeObserver(el, entry => onHeightUpdate(entry.target.offsetHeight));
12
- return /*#__PURE__*/React.createElement("div", {
13
- ref: setEl,
14
- "data-rs-internal": 'dropdown-menu__menu-wrapper'
15
- }, children);
12
+ } = t0;
13
+ let t1;
14
+
15
+ if ($[0] !== onHeightUpdate) {
16
+ t1 = entry => onHeightUpdate(entry.target.offsetHeight);
17
+
18
+ $[0] = onHeightUpdate;
19
+ $[1] = t1;
20
+ } else {
21
+ t1 = $[1];
22
+ }
23
+
24
+ useResizeObserver(el, t1);
25
+ let t2;
26
+
27
+ if ($[2] !== children || $[3] !== setEl) {
28
+ t2 = /*#__PURE__*/React.createElement("div", {
29
+ ref: setEl,
30
+ "data-rs-internal": "dropdown-menu__menu-wrapper"
31
+ }, children);
32
+ $[2] = children;
33
+ $[3] = setEl;
34
+ $[4] = t2;
35
+ } else {
36
+ t2 = $[4];
37
+ }
38
+
39
+ return t2;
16
40
  };
17
41
 
18
42
  MenuWrapper.displayName = 'MenuWrapper';
@@ -0,0 +1,6 @@
1
+ type CssValues = {
2
+ itemHeightFromCss: number | null;
3
+ contrastPrimaryFromCss: number | null;
4
+ };
5
+ export declare const useExtractCssValues: (menuWrapperEl: HTMLDivElement | null) => CssValues;
6
+ export {};
@@ -0,0 +1,51 @@
1
+ import { c } from 'react-compiler-runtime';
2
+ import { useState, useEffect, useLayoutEffect } from 'react';
3
+ const useIsomorphicLayoutEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect;
4
+
5
+ const useExtractCssValues = menuWrapperEl => {
6
+ const $ = c(4);
7
+ let t0;
8
+
9
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
10
+ t0 = {
11
+ itemHeightFromCss: null,
12
+ contrastPrimaryFromCss: null
13
+ };
14
+ $[0] = t0;
15
+ } else {
16
+ t0 = $[0];
17
+ }
18
+
19
+ const [cssValues, setCssValues] = useState(t0);
20
+ let t1;
21
+ let t2;
22
+
23
+ if ($[1] !== menuWrapperEl) {
24
+ t1 = () => {
25
+ const menuWrapperStyles = menuWrapperEl?.ownerDocument?.defaultView?.getComputedStyle(menuWrapperEl);
26
+
27
+ if (!menuWrapperStyles) {
28
+ return;
29
+ }
30
+
31
+ const nextCssValues = {
32
+ itemHeightFromCss: parseInt(menuWrapperStyles.getPropertyValue("--_rs-dropdown-menu-item-height"), 10) || null,
33
+ contrastPrimaryFromCss: parseInt(menuWrapperStyles.getPropertyValue("--rs-dropdown-menu-contrast-primary"), 10) || null
34
+ };
35
+ setCssValues(previousCssValues => previousCssValues.itemHeightFromCss === nextCssValues.itemHeightFromCss && previousCssValues.contrastPrimaryFromCss === nextCssValues.contrastPrimaryFromCss ? previousCssValues : nextCssValues);
36
+ };
37
+
38
+ t2 = [menuWrapperEl];
39
+ $[1] = menuWrapperEl;
40
+ $[2] = t1;
41
+ $[3] = t2;
42
+ } else {
43
+ t1 = $[2];
44
+ t2 = $[3];
45
+ }
46
+
47
+ useIsomorphicLayoutEffect(t1, t2);
48
+ return cssValues;
49
+ };
50
+
51
+ export { useExtractCssValues };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rescui/dropdown-menu",
3
- "version": "0.12.1",
3
+ "version": "0.13.0",
4
4
  "description": "",
5
5
  "license": "Apache-2.0",
6
6
  "author": "JetBrains",
@@ -17,21 +17,22 @@
17
17
  },
18
18
  "dependencies": {
19
19
  "@babel/runtime-corejs3": "^7.26.0",
20
- "@rescui/dropdown": "^0.11.2",
21
- "@rescui/menu": "^0.14.1",
22
- "@rescui/use-resize-observer": "^0.3.4",
23
- "classnames": "^2.2.6"
20
+ "@rescui/dropdown": "^0.12.0",
21
+ "@rescui/menu": "^0.15.0",
22
+ "@rescui/use-resize-observer": "^0.4.0",
23
+ "classnames": "^2.2.6",
24
+ "react-compiler-runtime": "^1.0.0"
24
25
  },
25
26
  "peerDependencies": {
26
27
  "@rescui/ui-contexts": "^0.6.0",
27
28
  "prop-types": "^15",
28
- "react": ">=16.8.0 <20"
29
+ "react": ">=17.0.0 <20"
29
30
  },
30
31
  "devDependencies": {
31
- "@rescui/colors": "^0.3.3",
32
- "@rescui/icons": "^1.8.4",
33
- "@rescui/scripts": "^0.5.2",
34
- "@rescui/typography": "^0.27.4",
32
+ "@rescui/colors": "^0.3.4",
33
+ "@rescui/icons": "^1.9.0",
34
+ "@rescui/scripts": "^0.5.3",
35
+ "@rescui/typography": "^0.28.0",
35
36
  "@rescui/visual-regression": "^0.1.4"
36
37
  },
37
38
  "scripts": {
@@ -39,5 +40,5 @@
39
40
  "build-pcss-api": "rescui-scripts build-pcss-api --file public-api.p.css"
40
41
  },
41
42
  "nx": {},
42
- "gitHead": "3711cbfc0c797014395421b008aa5331d6d47c6e"
43
+ "gitHead": "8ffbbe20b8bcbb9ea15204113ab603675d4c03cd"
43
44
  }