@rescui/menu 0.13.8-RUI-297-Add-react-compiler-to-the-packages-build-dbbefd7b8.14 → 0.14.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.
package/lib/menu.js CHANGED
@@ -1,65 +1,149 @@
1
1
  "use client";
2
- import React from 'react';
2
+ import React, { useRef } from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import cn from 'classnames';
5
5
  import { MenuProvider } from './parts/menu-context.js';
6
6
  import styles from './menu.p.module.css.js';
7
7
  import { useMenuKeyboardNavigation } from './parts/use-menu-keyboard-navigation.js';
8
8
 
9
- const Menu = _ref => {
9
+ const MenuListbox = _ref => {
10
10
  let {
11
- tag = 'ul',
11
+ activateFirstItem,
12
+ tag: Tag,
12
13
  itemTag,
13
14
  iconPlacement,
14
15
  disabled,
15
- size = 'm',
16
+ size,
16
17
  mode,
17
- disableCursor = false,
18
18
  theme,
19
- enableKeyboardNavigation = false,
20
- activateFirstItem = false,
21
19
  className,
22
20
  wrapItemsWithLi,
23
- returnFocusOnUnmount = false,
24
- resizeIcons = false,
25
- ...restProps
21
+ resizeIcons,
22
+ role,
23
+ onKeyDown,
24
+ onMouseLeave,
25
+ tabIndex,
26
+ ...props
26
27
  } = _ref;
27
- const Tag = tag;
28
+ const menuRef = useRef(null);
28
29
  const {
29
- activeItemRef,
30
+ currentActiveItemEl,
31
+ setCurrentActiveItemEl,
30
32
  registerItem,
31
33
  unregisterItem,
32
- isKeyboardNavigating
34
+ handleItemFocus,
35
+ handleItemKeyDown,
36
+ handleItemMouseEnter
33
37
  } = useMenuKeyboardNavigation({
34
- enableKeyboardNavigation,
35
- activateFirstItem,
36
- returnFocusOnUnmount
38
+ activateFirstItem
37
39
  });
40
+
41
+ const handleMenuKeyDown = e => {
42
+ onKeyDown?.(e);
43
+
44
+ if (e.defaultPrevented || e.target !== e.currentTarget) {
45
+ return;
46
+ }
47
+
48
+ handleItemKeyDown(e, currentActiveItemEl ?? undefined);
49
+ };
50
+
51
+ const handleMenuMouseLeave = e => {
52
+ onMouseLeave?.(e);
53
+
54
+ if (e.defaultPrevented) {
55
+ return;
56
+ }
57
+
58
+ setCurrentActiveItemEl(null);
59
+ menuRef.current?.focus({
60
+ preventScroll: true
61
+ });
62
+ };
63
+
38
64
  return /*#__PURE__*/React.createElement(MenuProvider, {
39
65
  itemTag: itemTag,
40
66
  iconPlacement: iconPlacement,
41
67
  disabled: disabled,
42
68
  size: size,
43
- disableCursor: disableCursor || isKeyboardNavigating,
44
69
  mode: mode,
45
70
  theme: theme,
71
+ wrapWithLi: wrapItemsWithLi ?? Tag === 'ul',
72
+ resizeIcons: resizeIcons,
73
+ keyboardNavigationEnabled: true,
74
+ currentActiveItemEl: currentActiveItemEl,
46
75
  registerItem: registerItem,
47
76
  unregisterItem: unregisterItem,
48
- activeItemRef: activeItemRef.current,
49
- isKeyboardNavigating: isKeyboardNavigating,
50
- wrapWithLi: wrapItemsWithLi ?? tag === 'ul',
51
- resizeIcons: resizeIcons
77
+ onItemFocus: handleItemFocus,
78
+ onItemKeyDown: handleItemKeyDown,
79
+ onItemMouseEnter: handleItemMouseEnter
80
+ }, /*#__PURE__*/React.createElement(Tag, { ...props,
81
+ className: cn(styles.keyboardNavigationEnabled, styles.menu, className),
82
+ onKeyDown: handleMenuKeyDown,
83
+ onMouseLeave: handleMenuMouseLeave,
84
+ role: role ?? 'listbox',
85
+ tabIndex: currentActiveItemEl ? -1 : tabIndex ?? 0,
86
+ ref: menuRef
87
+ }));
88
+ };
89
+
90
+ const MenuRegular = _ref2 => {
91
+ let {
92
+ tag: Tag,
93
+ itemTag,
94
+ iconPlacement,
95
+ disabled,
96
+ size,
97
+ mode,
98
+ theme,
99
+ className,
100
+ wrapItemsWithLi,
101
+ resizeIcons,
102
+ ...props
103
+ } = _ref2;
104
+ return /*#__PURE__*/React.createElement(MenuProvider, {
105
+ itemTag: itemTag,
106
+ iconPlacement: iconPlacement,
107
+ disabled: disabled,
108
+ size: size,
109
+ mode: mode,
110
+ theme: theme,
111
+ wrapWithLi: wrapItemsWithLi ?? Tag === 'ul',
112
+ resizeIcons: resizeIcons,
113
+ keyboardNavigationEnabled: false,
114
+ currentActiveItemEl: null,
115
+ registerItem: null,
116
+ unregisterItem: null,
117
+ onItemFocus: null,
118
+ onItemKeyDown: null,
119
+ onItemMouseEnter: null
52
120
  }, /*#__PURE__*/React.createElement(Tag, {
53
- className: cn(!enableKeyboardNavigation && styles.keyboardNavigationDisabled, className),
54
- ...restProps
121
+ className: cn(styles.keyboardNavigationDisabled, styles.menu, className),
122
+ ...props
55
123
  }));
56
124
  };
57
125
 
126
+ const Menu = _ref3 => {
127
+ let {
128
+ enableKeyboardNavigation = false,
129
+ activateFirstItem = false,
130
+ tag = 'ul',
131
+ ...props
132
+ } = _ref3;
133
+ return enableKeyboardNavigation ? /*#__PURE__*/React.createElement(MenuListbox, {
134
+ activateFirstItem: activateFirstItem,
135
+ tag: tag,
136
+ ...props
137
+ }) : /*#__PURE__*/React.createElement(MenuRegular, {
138
+ tag: tag,
139
+ ...props
140
+ });
141
+ };
142
+
58
143
  Menu.propTypes = {
59
144
  size: PropTypes.oneOf(['l', 'm', 's']),
60
145
  mode: PropTypes.oneOf(['clear', 'classic', 'rock']),
61
146
  theme: PropTypes.oneOf(['light', 'dark']),
62
- disableCursor: PropTypes.bool,
63
147
  disabled: PropTypes.bool,
64
148
  resizeIcons: PropTypes.bool,
65
149
  iconPlacement: PropTypes.oneOf(['left', 'right']),
@@ -1,30 +1,37 @@
1
1
  var styles = {
2
- "themeLight": "_themeLight_1be69r7_8",
3
- "themeDark": "_themeDark_1be69r7_11",
4
- "sizeS": "_sizeS_1be69r7_15",
5
- "sizeM": "_sizeM_1be69r7_18",
6
- "sizeL": "_sizeL_1be69r7_21",
7
- "modeClassic": "_modeClassic_1be69r7_25",
8
- "modeRock": "_modeRock_1be69r7_28",
9
- "modeClear": "_modeClear_1be69r7_31",
10
- "iconPlacementLeft": "_iconPlacementLeft_1be69r7_35",
11
- "iconPlacementRight": "_iconPlacementRight_1be69r7_39",
12
- "wrapper": "_wrapper_1be69r7_43",
13
- "menuItem": "_menuItem_1be69r7_50",
14
- "keyboardNavigationDisabled": "_keyboardNavigationDisabled_1be69r7_85",
15
- "selected": "_selected_1be69r7_99",
16
- "highlighted": "_highlighted_1be69r7_106",
17
- "disableCursor": "_disableCursor_1be69r7_107",
18
- "disabled": "_disabled_1be69r7_120",
19
- "content": "_content_1be69r7_131",
20
- "icon": "_icon_1be69r7_35",
21
- "resizedIcon": "_resizedIcon_1be69r7_141",
22
- "divider": "_divider_1be69r7_149",
23
- "groupHeaderThemeLight": "_groupHeaderThemeLight_1be69r7_163",
24
- "groupHeaderThemeDark": "_groupHeaderThemeDark_1be69r7_166",
25
- "groupHeaderSizeL": "_groupHeaderSizeL_1be69r7_170",
26
- "groupHeaderSizeM": "_groupHeaderSizeM_1be69r7_173",
27
- "groupHeaderSizeS": "_groupHeaderSizeS_1be69r7_176",
28
- "groupHeader": "_groupHeader_1be69r7_163"
2
+ "themeLight": "_themeLight_1t76rai_8",
3
+ "themeDark": "_themeDark_1t76rai_11",
4
+ "menu": "_menu_1t76rai_15",
5
+ "sizeS": "_sizeS_1t76rai_21",
6
+ "sizeM": "_sizeM_1t76rai_24",
7
+ "sizeL": "_sizeL_1t76rai_27",
8
+ "modeClassic": "_modeClassic_1t76rai_31",
9
+ "modeRock": "_modeRock_1t76rai_34",
10
+ "modeClear": "_modeClear_1t76rai_37",
11
+ "iconPlacementLeft": "_iconPlacementLeft_1t76rai_41",
12
+ "iconPlacementRight": "_iconPlacementRight_1t76rai_45",
13
+ "wrapper": "_wrapper_1t76rai_49",
14
+ "hoverIcon": "_hoverIcon_1t76rai_53",
15
+ "hoverIconNoReserve": "_hoverIconNoReserve_1t76rai_56",
16
+ "menuItem": "_menuItem_1t76rai_61",
17
+ "keyboardNavigationDisabled": "_keyboardNavigationDisabled_1t76rai_98",
18
+ "selected": "_selected_1t76rai_112",
19
+ "keyboardNavigationEnabled": "_keyboardNavigationEnabled_1t76rai_119",
20
+ "hideCustomIconOnHover": "_hideCustomIconOnHover_1t76rai_130",
21
+ "customIcon": "_customIcon_1t76rai_132",
22
+ "hideSelectedIconOnHover": "_hideSelectedIconOnHover_1t76rai_137",
23
+ "selectedIcon": "_selectedIcon_1t76rai_139",
24
+ "disabled": "_disabled_1t76rai_144",
25
+ "contentWrapper": "_contentWrapper_1t76rai_151",
26
+ "content": "_content_1t76rai_151",
27
+ "icon": "_icon_1t76rai_41",
28
+ "resizedIcon": "_resizedIcon_1t76rai_169",
29
+ "divider": "_divider_1t76rai_177",
30
+ "groupHeaderThemeLight": "_groupHeaderThemeLight_1t76rai_191",
31
+ "groupHeaderThemeDark": "_groupHeaderThemeDark_1t76rai_194",
32
+ "groupHeaderSizeL": "_groupHeaderSizeL_1t76rai_198",
33
+ "groupHeaderSizeM": "_groupHeaderSizeM_1t76rai_201",
34
+ "groupHeaderSizeS": "_groupHeaderSizeS_1t76rai_204",
35
+ "groupHeader": "_groupHeader_1t76rai_191"
29
36
  };
30
37
  export { styles as default };
@@ -1,10 +1,7 @@
1
- import React, { HTMLAttributes } from 'react';
1
+ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { Theme } from '@rescui/ui-contexts';
4
- export interface DividerProps extends HTMLAttributes<HTMLHRElement> {
5
- theme?: Theme;
6
- className?: string;
7
- }
3
+ import type { DividerProps } from '../types';
4
+ export type { DividerProps } from '../types';
8
5
  declare const Divider: {
9
6
  ({ className, theme, ...restProps }: DividerProps): React.JSX.Element;
10
7
  propTypes: {
@@ -20,6 +20,7 @@ const Divider = _ref => {
20
20
  const actualTheme = useThemeWithUndefined(menuContext.theme ?? theme);
21
21
  return /*#__PURE__*/React.createElement("hr", {
22
22
  className: cn(styles.divider, THEME_CLASS[actualTheme], className),
23
+ role: menuContext.keyboardNavigationEnabled ? 'presentation' : undefined,
23
24
  ...restProps
24
25
  });
25
26
  };
@@ -1,13 +1,7 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { Theme } from '@rescui/ui-contexts';
4
- import { MenuItemSize } from './menu-context';
5
- export interface GroupHeaderProps {
6
- theme?: Theme;
7
- size?: MenuItemSize;
8
- text?: React.ReactNode;
9
- className?: string;
10
- }
3
+ import type { GroupHeaderProps } from '../types';
4
+ export type { GroupHeaderProps } from '../types';
11
5
  declare function GroupHeader({ className, text, size: propsSize, theme: propsTheme }: GroupHeaderProps): React.JSX.Element;
12
6
  declare namespace GroupHeader {
13
7
  var propTypes: {
@@ -27,7 +27,8 @@ function GroupHeader(_ref) {
27
27
  const actualTheme = useThemeWithUndefined(menuContext.theme ?? propsTheme);
28
28
  return /*#__PURE__*/React.createElement(Tag, {
29
29
  className: cn(styles.groupHeader, SIZE_CLASS[menuContext.size ?? propsSize], THEME_CLASS[actualTheme], className),
30
- "data-rs-internal": 'menu__group-header'
30
+ "data-rs-internal": 'menu__group-header',
31
+ role: menuContext.keyboardNavigationEnabled ? 'presentation' : undefined
31
32
  }, text);
32
33
  }
33
34
 
@@ -1,23 +1,6 @@
1
1
  import React, { PropsWithChildren } from 'react';
2
- import { Theme } from '@rescui/ui-contexts';
3
- export type MenuItemSize = 's' | 'm' | 'l';
4
- export type MenuItemIconPlacement = 'left' | 'right';
5
- export type MenuItemMode = 'clear' | 'classic' | 'rock';
6
- export interface MenuContextValue {
7
- iconPlacement?: MenuItemIconPlacement;
8
- disabled?: boolean;
9
- disableCursor?: boolean;
10
- size?: MenuItemSize;
11
- mode?: MenuItemMode;
12
- theme?: Theme;
13
- itemTag?: React.ElementType;
14
- wrapWithLi: boolean;
15
- registerItem?: (ref: HTMLElement) => void;
16
- unregisterItem?: (ref: HTMLElement) => void;
17
- activeItemRef?: HTMLElement;
18
- isKeyboardNavigating: boolean;
19
- resizeIcons?: boolean;
20
- }
2
+ import type { MenuContextValue } from '../types';
3
+ export type { MenuContextValue, MenuItemMode, MenuItemIconPlacement, MenuItemSize } from '../types';
21
4
  export declare const DEFAULT_MENU_CONTEXT: MenuContextValue;
22
5
  export declare const MenuContext: React.Context<MenuContextValue>;
23
6
  export declare const useMenuContext: () => MenuContextValue;
@@ -3,12 +3,14 @@ import React, { useContext } from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  const DEFAULT_MENU_CONTEXT = {
5
5
  disabled: false,
6
- isKeyboardNavigating: false,
6
+ keyboardNavigationEnabled: false,
7
7
  wrapWithLi: false,
8
- // eslint-disable-next-line @typescript-eslint/no-empty-function
9
- registerItem: () => {},
10
- // eslint-disable-next-line @typescript-eslint/no-empty-function
11
- unregisterItem: () => {}
8
+ registerItem: null,
9
+ unregisterItem: null,
10
+ currentActiveItemEl: null,
11
+ onItemFocus: null,
12
+ onItemKeyDown: null,
13
+ onItemMouseEnter: null
12
14
  };
13
15
  const MenuContext = /*#__PURE__*/React.createContext(DEFAULT_MENU_CONTEXT);
14
16
 
@@ -18,7 +20,6 @@ const MenuProvider = _ref => {
18
20
  let {
19
21
  children,
20
22
  disabled = DEFAULT_MENU_CONTEXT.disabled,
21
- isKeyboardNavigating = DEFAULT_MENU_CONTEXT.isKeyboardNavigating,
22
23
  wrapWithLi = DEFAULT_MENU_CONTEXT.wrapWithLi,
23
24
  registerItem = DEFAULT_MENU_CONTEXT.registerItem,
24
25
  unregisterItem = DEFAULT_MENU_CONTEXT.unregisterItem,
@@ -27,7 +28,6 @@ const MenuProvider = _ref => {
27
28
  return /*#__PURE__*/React.createElement(MenuContext.Provider, {
28
29
  value: {
29
30
  disabled,
30
- isKeyboardNavigating,
31
31
  wrapWithLi,
32
32
  registerItem,
33
33
  unregisterItem,
@@ -40,7 +40,6 @@ MenuProvider.propTypes = {
40
40
  size: PropTypes.oneOf(['l', 'm', 's']),
41
41
  mode: PropTypes.oneOf(['clear', 'classic', 'rock']),
42
42
  theme: PropTypes.oneOf(['light', 'dark']),
43
- disableCursor: PropTypes.bool,
44
43
  disabled: PropTypes.bool,
45
44
  iconPlacement: PropTypes.oneOf(['left', 'right']),
46
45
  itemTag: PropTypes.elementType
@@ -1,21 +1,33 @@
1
1
  import React from 'react';
2
- import type { JSX, AllHTMLAttributes, ReactNode } from 'react';
3
- import { Theme } from '@rescui/ui-contexts';
4
- import { MenuItemSize, MenuItemMode, MenuItemIconPlacement } from './menu-context';
5
- export interface MenuItemProps extends Omit<AllHTMLAttributes<Element>, 'size'> {
2
+ import type { JSX } from 'react';
3
+ export type { MenuItemProps } from '../types';
4
+ export declare const MenuItem: React.ForwardRefExoticComponent<{
6
5
  className?: string;
7
6
  tag?: React.ElementType;
8
7
  icon?: JSX.Element;
9
- size?: MenuItemSize;
10
- mode?: MenuItemMode;
11
- theme?: Theme;
8
+ size?: import("./menu-context").MenuItemSize;
9
+ mode?: import("./menu-context").MenuItemMode;
10
+ theme?: import("@rescui/ui-contexts").Theme;
12
11
  disabled?: boolean;
13
- disableCursor?: boolean;
14
12
  selected?: boolean;
15
- highlighted?: boolean;
16
- iconPlacement?: MenuItemIconPlacement;
17
- children?: ReactNode;
13
+ iconPlacement?: import("./menu-context").MenuItemIconPlacement;
14
+ children?: React.ReactNode;
18
15
  key?: string;
19
- }
20
- export declare const MenuItem: React.ForwardRefExoticComponent<MenuItemProps & React.RefAttributes<HTMLElement>>;
16
+ 'data-test'?: string;
17
+ hoverIcon?: JSX.Element;
18
+ } & Omit<React.AllHTMLAttributes<Element>, keyof {
19
+ className?: string;
20
+ tag?: React.ElementType;
21
+ icon?: JSX.Element;
22
+ size?: import("./menu-context").MenuItemSize;
23
+ mode?: import("./menu-context").MenuItemMode;
24
+ theme?: import("@rescui/ui-contexts").Theme;
25
+ disabled?: boolean;
26
+ selected?: boolean;
27
+ iconPlacement?: import("./menu-context").MenuItemIconPlacement;
28
+ children?: React.ReactNode;
29
+ key?: string;
30
+ 'data-test'?: string;
31
+ hoverIcon?: JSX.Element;
32
+ }> & React.RefAttributes<HTMLElement>>;
21
33
  export default MenuItem;
@@ -1,8 +1,9 @@
1
1
  "use client";
2
- import React, { useState, useEffect, cloneElement } from 'react';
2
+ import React, { useState, cloneElement, useEffect } from 'react';
3
3
  import cn from 'classnames';
4
4
  import PropTypes from 'prop-types';
5
5
  import { useThemeWithUndefined } from '@rescui/ui-contexts';
6
+ import CheckOutlineIcon from '../_virtual/check-outline.js';
6
7
  import styles from '../menu.p.module.css.js';
7
8
  import { useMenuContext } from './menu-context.js';
8
9
  const ICON_PLACEMENT_STYLES = {
@@ -22,6 +23,11 @@ const SIZE_STYLES = {
22
23
  const THEME_STYLES = {
23
24
  light: styles.themeLight,
24
25
  dark: styles.themeDark
26
+ };
27
+ const HOVER_ICON_WILL_REPLACE_STYLES = {
28
+ custom: styles.hideCustomIconOnHover,
29
+ selected: styles.hideSelectedIconOnHover,
30
+ none: ''
25
31
  }; // eslint-disable-next-line complexity
26
32
 
27
33
  const MenuItemInner = (_ref, ref) => {
@@ -34,27 +40,29 @@ const MenuItemInner = (_ref, ref) => {
34
40
  mode = 'classic',
35
41
  theme,
36
42
  disabled,
37
- disableCursor,
38
43
  selected,
39
-
40
- /* @private */
41
- highlighted,
42
44
  iconPlacement = 'left',
45
+ onFocus,
46
+ onKeyDown,
47
+ onMouseEnter,
48
+ role,
49
+ tabIndex,
50
+ hoverIcon,
43
51
  ...restProps
44
52
  } = _ref;
45
53
  const {
46
54
  unregisterItem,
47
55
  registerItem,
48
- activeItemRef,
49
- isKeyboardNavigating,
56
+ currentActiveItemEl,
57
+ keyboardNavigationEnabled,
58
+ onItemFocus,
59
+ onItemKeyDown,
60
+ onItemMouseEnter,
50
61
  wrapWithLi,
51
62
  ...menuContext
52
63
  } = useMenuContext();
53
64
  const actualTheme = useThemeWithUndefined(menuContext.theme ?? theme);
54
65
  const [thisRef, setThisRef] = useState(null);
55
- useEffect(() => {
56
- return () => unregisterItem(thisRef);
57
- }, [unregisterItem, thisRef]);
58
66
  let autoTag = 'span';
59
67
 
60
68
  if (restProps.href) {
@@ -67,17 +75,37 @@ const MenuItemInner = (_ref, ref) => {
67
75
  const actualIconPlacement = menuContext.iconPlacement ?? iconPlacement ?? 'left';
68
76
  const actualMode = menuContext.mode ?? mode;
69
77
  const actualSize = menuContext.size ?? size;
70
- const actualDisableCursor = menuContext.disableCursor ?? disableCursor;
71
78
  const resizeIcons = menuContext.resizeIcons ?? false;
72
- const iconElement = icon ? /*#__PURE__*/cloneElement(icon, {
73
- className: cn(icon.props.className, styles.icon, resizeIcons && styles.resizedIcon),
79
+ const actualDisabled = menuContext.disabled || disabled;
80
+ const iconElement = /*#__PURE__*/React.isValidElement(icon) ? /*#__PURE__*/cloneElement(icon, {
81
+ className: cn(icon.props.className, styles.icon, styles.customIcon, resizeIcons && styles.resizedIcon),
74
82
  'data-render-all-sizes': true
75
83
  }) : null;
76
- const actualHighlighted = highlighted || activeItemRef === thisRef && isKeyboardNavigating;
84
+ const hasHoverIcon = /*#__PURE__*/React.isValidElement(hoverIcon);
85
+ const rovingTabIndex = currentActiveItemEl === thisRef ? 0 : -1;
86
+ let resolvedTabIndex = tabIndex ?? 0;
87
+
88
+ if (keyboardNavigationEnabled) {
89
+ resolvedTabIndex = rovingTabIndex;
90
+ }
91
+
92
+ if (actualDisabled) {
93
+ resolvedTabIndex = -1;
94
+ }
95
+
96
+ useEffect(() => {
97
+ if (!thisRef || actualDisabled || !registerItem) {
98
+ return undefined;
99
+ }
100
+
101
+ registerItem(thisRef);
102
+ return () => unregisterItem?.(thisRef);
103
+ }, [actualDisabled, registerItem, thisRef, unregisterItem]);
77
104
 
78
105
  const handleRef = r => {
79
- registerItem(r);
80
- setThisRef(r);
106
+ if (r) {
107
+ setThisRef(r);
108
+ }
81
109
 
82
110
  if (typeof ref === 'function') {
83
111
  ref(r);
@@ -87,31 +115,71 @@ const MenuItemInner = (_ref, ref) => {
87
115
  };
88
116
 
89
117
  const handleKeyDown = e => {
90
- if (isKeyboardNavigating && (e.key === ' ' || e.key === 'Enter')) {
91
- e.preventDefault();
118
+ onKeyDown?.(e);
119
+
120
+ if (e.defaultPrevented || !onItemKeyDown) {
121
+ return;
122
+ }
92
123
 
93
- if (e.target && e.target.click) {
94
- e.target.click();
95
- }
124
+ if (thisRef) {
125
+ onItemKeyDown(e, thisRef);
96
126
  }
97
127
  };
98
128
 
129
+ const handleFocus = e => {
130
+ onFocus?.(e);
131
+
132
+ if (onItemFocus && thisRef) {
133
+ onItemFocus(thisRef);
134
+ }
135
+ };
136
+
137
+ const handleMouseEnter = e => {
138
+ onMouseEnter?.(e);
139
+
140
+ if (onItemMouseEnter && thisRef) {
141
+ onItemMouseEnter(thisRef);
142
+ }
143
+ };
144
+
145
+ let hoverIconWillReplace = 'none';
146
+
147
+ if (hasHoverIcon && iconElement && actualIconPlacement === 'right') {
148
+ hoverIconWillReplace = 'custom';
149
+ } else if (hasHoverIcon && selected) {
150
+ hoverIconWillReplace = 'selected';
151
+ }
152
+
99
153
  const Wrapper = wrapWithLi ? 'li' : 'div';
100
154
  return /*#__PURE__*/React.createElement(Wrapper, {
101
155
  className: cn(styles.wrapper, className, ICON_PLACEMENT_STYLES[actualIconPlacement], MODE_STYLES[actualMode], SIZE_STYLES[actualSize], THEME_STYLES[actualTheme]),
102
156
  "data-test": 'menu-item__wrapper',
103
- "data-rs-internal": 'menu__menu-item'
104
- }, /*#__PURE__*/React.createElement(Tag, {
157
+ "data-rs-internal": 'menu__menu-item',
158
+ role: keyboardNavigationEnabled ? 'presentation' : undefined
159
+ }, /*#__PURE__*/React.createElement(Tag, { ...restProps,
160
+ onFocus: handleFocus,
105
161
  onKeyDown: handleKeyDown,
162
+ onMouseEnter: handleMouseEnter,
106
163
  ref: handleRef,
107
- className: cn(styles.menuItem, (menuContext.disabled || disabled) && styles.disabled, selected && styles.selected, actualHighlighted && styles.highlighted, actualDisableCursor && styles.disableCursor),
108
- "data-test": 'menu-item',
164
+ className: cn(styles.menuItem, actualDisabled && styles.disabled, selected && styles.selected, HOVER_ICON_WILL_REPLACE_STYLES[hoverIconWillReplace]),
165
+ "data-test": restProps['data-test'] ?? 'menu-item',
109
166
  "data-rs-internal": 'menu__menu-item__inner',
110
- tabIndex: 0,
111
- ...restProps
167
+ role: role ?? (keyboardNavigationEnabled ? 'option' : undefined),
168
+ "aria-selected": keyboardNavigationEnabled && selected !== undefined ? selected : restProps['aria-selected'],
169
+ "aria-disabled": keyboardNavigationEnabled && actualDisabled ? true : restProps['aria-disabled'],
170
+ tabIndex: resolvedTabIndex
112
171
  }, iconElement, /*#__PURE__*/React.createElement("span", {
172
+ className: styles.contentWrapper
173
+ }, /*#__PURE__*/React.createElement("span", {
113
174
  className: styles.content
114
- }, children)));
175
+ }, children), selected && /*#__PURE__*/React.createElement(CheckOutlineIcon, {
176
+ className: cn(styles.icon, styles.selectedIcon, resizeIcons && styles.resizedIcon),
177
+ "data-test": 'menu-item__selected-icon',
178
+ "data-render-all-sizes": true
179
+ }), hasHoverIcon && /*#__PURE__*/React.cloneElement(hoverIcon, {
180
+ className: cn(hoverIcon.props.className, styles.icon, styles.hoverIcon, resizeIcons && styles.resizedIcon, hoverIconWillReplace !== 'none' && styles.hoverIconNoReserve),
181
+ 'data-render-all-sizes': true
182
+ }))));
115
183
  };
116
184
 
117
185
  const MenuItem = /*#__PURE__*/React.forwardRef(MenuItemInner);
@@ -119,15 +187,11 @@ MenuItem.propTypes = {
119
187
  size: PropTypes.oneOf(['l', 'm', 's']),
120
188
  mode: PropTypes.oneOf(['clear', 'classic', 'rock']),
121
189
  theme: PropTypes.oneOf(['light', 'dark']),
122
- onClick: PropTypes.func,
123
190
  disabled: PropTypes.bool,
124
- disableCursor: PropTypes.bool,
125
191
  selected: PropTypes.bool,
126
-
127
- /** @ignore */
128
- highlighted: PropTypes.bool,
129
192
  icon: PropTypes.element,
130
193
  iconPlacement: PropTypes.oneOf(['left', 'right']),
131
- tag: PropTypes.elementType
194
+ tag: PropTypes.elementType,
195
+ hoverIcon: PropTypes.element
132
196
  };
133
197
  export { MenuItem, MenuItem as default };
@@ -1,5 +1,5 @@
1
1
  export declare function getFirstItem(sortedItems: HTMLElement[]): HTMLElement;
2
2
  export declare function getLastItem(sortedItems: HTMLElement[]): HTMLElement;
3
- export declare function getNextItem(sortedItems: HTMLElement[], activeItem: HTMLElement): HTMLElement;
4
- export declare function getPrevItem(sortedItems: HTMLElement[], activeItem: HTMLElement): HTMLElement;
3
+ export declare function getNextItem(sortedItems: HTMLElement[], activeItem?: HTMLElement): HTMLElement;
4
+ export declare function getPrevItem(sortedItems: HTMLElement[], activeItem?: HTMLElement): HTMLElement;
5
5
  export declare function htmlElementsComparator(a: HTMLElement, b: HTMLElement): 0 | 1 | -1;
@@ -1,12 +1,14 @@
1
+ import React from 'react';
1
2
  interface UseMenuKeyboardNavigationParams {
2
- enableKeyboardNavigation: boolean;
3
3
  activateFirstItem: boolean;
4
- returnFocusOnUnmount: boolean;
5
4
  }
6
- export declare function useMenuKeyboardNavigation({ enableKeyboardNavigation, activateFirstItem, returnFocusOnUnmount }: UseMenuKeyboardNavigationParams): {
7
- activeItemRef: import("react").RefObject<any>;
5
+ export declare function useMenuKeyboardNavigation({ activateFirstItem }: UseMenuKeyboardNavigationParams): {
6
+ currentActiveItemEl: HTMLElement;
7
+ setCurrentActiveItemEl: React.Dispatch<React.SetStateAction<HTMLElement>>;
8
8
  registerItem: (ref: HTMLElement) => void;
9
9
  unregisterItem: (ref: HTMLElement) => void;
10
- isKeyboardNavigating: boolean;
10
+ handleItemFocus: (ref: HTMLElement) => void;
11
+ handleItemKeyDown: (e: React.KeyboardEvent<HTMLElement>, ref?: HTMLElement) => void;
12
+ handleItemMouseEnter: (ref: HTMLElement) => void;
11
13
  };
12
14
  export {};