@carbon/react 1.78.0-rc.0 → 1.78.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.
@@ -215,7 +215,7 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
215
215
  const textInput = useRef(null);
216
216
  const comboBoxInstanceId = useId();
217
217
  const [isFocused, setIsFocused] = useState(false);
218
- const savedOnInputChange = useRef(onInputChange);
218
+ const prevInputValue = useRef(inputValue);
219
219
  const prevSelectedItemProp = useRef(selectedItemProp);
220
220
 
221
221
  // fully controlled combobox: handle changes to selectedItemProp
@@ -246,12 +246,12 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
246
246
  itemToString,
247
247
  inputValue
248
248
  }) : defaultShouldFilterItem());
249
+
250
+ // call onInputChange whenever inputValue is updated
249
251
  useEffect(() => {
250
- savedOnInputChange.current = onInputChange;
251
- }, [onInputChange]);
252
- useEffect(() => {
253
- if (savedOnInputChange.current) {
254
- savedOnInputChange.current(inputValue);
252
+ if (prevInputValue.current !== inputValue) {
253
+ prevInputValue.current = inputValue;
254
+ onInputChange && onInputChange(inputValue);
255
255
  }
256
256
  }, [inputValue]);
257
257
  const handleSelectionClear = () => {
@@ -166,7 +166,6 @@ const ComboButton = /*#__PURE__*/React__default.forwardRef(function ComboButton(
166
166
  ref: refs.setFloating,
167
167
  id: id,
168
168
  label: t('carbon.combo-button.additional-actions'),
169
- mode: "basic",
170
169
  size: size$1,
171
170
  open: open,
172
171
  onClose: handleClose
@@ -10,7 +10,6 @@ export interface ContextMenuProps {
10
10
  x: number;
11
11
  y: number;
12
12
  onClose: () => void;
13
- mode: string;
14
13
  }
15
14
  /**
16
15
  * @param {TriggerType} [trigger=document] The element or ref which should trigger the Menu on right-click
@@ -41,8 +41,7 @@ function useContextMenu() {
41
41
  open,
42
42
  x: position[0],
43
43
  y: position[1],
44
- onClose,
45
- mode: 'full'
44
+ onClose
46
45
  };
47
46
  }
48
47
 
@@ -27,6 +27,7 @@ export interface MenuProps extends React.HTMLAttributes<HTMLUListElement> {
27
27
  */
28
28
  menuAlignment?: string;
29
29
  /**
30
+ * @deprecated Menus now always support both icons as well as selectable items and nesting.
30
31
  * The mode of this menu. Defaults to full.
31
32
  * `full` supports nesting and selectable menu items, but no icons.
32
33
  * `basic` supports icons but no nesting or selectable menu items.
@@ -12,7 +12,7 @@ import React__default, { forwardRef, useRef, useContext, useReducer, useMemo, us
12
12
  import { createPortal } from 'react-dom';
13
13
  import { useMergedRefs } from '../../internal/useMergedRefs.js';
14
14
  import { usePrefix } from '../../internal/usePrefix.js';
15
- import { warning } from '../../internal/warning.js';
15
+ import deprecate from '../../prop-types/deprecate.js';
16
16
  import { MenuContext, menuReducer } from './MenuContext.js';
17
17
  import { canUseDOM } from '../../internal/environment.js';
18
18
  import { useLayoutDirection } from '../LayoutDirection/useLayoutDirection.js';
@@ -28,7 +28,7 @@ const Menu = /*#__PURE__*/forwardRef(function Menu(_ref, forwardRef) {
28
28
  containerRef,
29
29
  label,
30
30
  menuAlignment,
31
- mode = 'full',
31
+ mode,
32
32
  onClose,
33
33
  onOpen,
34
34
  open,
@@ -44,14 +44,10 @@ const Menu = /*#__PURE__*/forwardRef(function Menu(_ref, forwardRef) {
44
44
  const focusReturn = useRef(null);
45
45
  const context = useContext(MenuContext);
46
46
  const isRoot = context.state.isRoot;
47
- if (context.state.mode === 'basic' && !isRoot) {
48
- process.env.NODE_ENV !== "production" ? warning(false, 'Nested menus are not supported when the menu is in "basic" mode.') : void 0;
49
- }
50
47
  const menuSize = isRoot ? size : context.state.size;
51
48
  const [childState, childDispatch] = useReducer(menuReducer, {
52
49
  ...context.state,
53
50
  isRoot: false,
54
- mode,
55
51
  size,
56
52
  requestCloseRoot: isRoot ? handleClose : context.state.requestCloseRoot
57
53
  });
@@ -283,6 +279,7 @@ const Menu = /*#__PURE__*/forwardRef(function Menu(_ref, forwardRef) {
283
279
  [`${prefix}--menu--open`]: open,
284
280
  [`${prefix}--menu--shown`]: open && !legacyAutoalign || position[0] >= 0 && position[1] >= 0,
285
281
  [`${prefix}--menu--with-icons`]: childContext.state.hasIcons,
282
+ [`${prefix}--menu--with-selectable-items`]: childContext.state.hasSelectableItems,
286
283
  [`${prefix}--autoalign`]: !legacyAutoalign
287
284
  });
288
285
  const rendered = /*#__PURE__*/React__default.createElement(MenuContext.Provider, {
@@ -320,13 +317,14 @@ Menu.propTypes = {
320
317
  */
321
318
  menuAlignment: PropTypes.string,
322
319
  /**
320
+ * **Deprecated**: Menus now always support both icons as well as selectable items and nesting.
323
321
  * The mode of this menu. Defaults to full.
324
322
  * `full` supports nesting and selectable menu items, but no icons.
325
323
  * `basic` supports icons but no nesting or selectable menu items.
326
324
  *
327
325
  * **This prop is not intended for use and will be set by the respective implementation (like useContextMenu, MenuButton, and ComboButton).**
328
326
  */
329
- mode: PropTypes.oneOf(['full', 'basic']),
327
+ mode: deprecate(PropTypes.oneOf(['full', 'basic']), 'Menus now always support both icons as well as selectable items and nesting.'),
330
328
  /**
331
329
  * Provide an optional function to be called when the Menu should be closed.
332
330
  */
@@ -6,13 +6,13 @@
6
6
  */
7
7
  import { KeyboardEvent, RefObject } from 'react';
8
8
  type ActionType = {
9
- type: 'enableIcons' | 'registerItem';
9
+ type: 'enableIcons' | 'enableSelectableItems' | 'registerItem';
10
10
  payload: any;
11
11
  };
12
12
  type StateType = {
13
13
  isRoot: boolean;
14
- mode: 'full' | 'basic';
15
14
  hasIcons: boolean;
15
+ hasSelectableItems: boolean;
16
16
  size: 'xs' | 'sm' | 'md' | 'lg' | null;
17
17
  items: any[];
18
18
  requestCloseRoot: (e: Pick<KeyboardEvent<HTMLUListElement>, 'type'>) => void;
@@ -20,13 +20,13 @@ type StateType = {
20
20
  declare function menuReducer(state: StateType, action: ActionType): {
21
21
  hasIcons: boolean;
22
22
  isRoot: boolean;
23
- mode: "full" | "basic";
23
+ hasSelectableItems: boolean;
24
24
  size: "xs" | "sm" | "md" | "lg" | null;
25
25
  items: any[];
26
26
  requestCloseRoot: (e: Pick<KeyboardEvent<HTMLUListElement>, "type">) => void;
27
27
  };
28
28
  type DispatchFuncProps = {
29
- type: 'registerItem' | 'enableIcons';
29
+ type: ActionType['type'];
30
30
  payload: {
31
31
  ref: RefObject<HTMLLIElement>;
32
32
  disabled: boolean;
@@ -9,8 +9,8 @@ import { createContext } from 'react';
9
9
 
10
10
  const menuDefaultState = {
11
11
  isRoot: true,
12
- mode: 'full',
13
12
  hasIcons: false,
13
+ hasSelectableItems: false,
14
14
  size: null,
15
15
  items: [],
16
16
  requestCloseRoot: () => {}
@@ -22,6 +22,11 @@ function menuReducer(state, action) {
22
22
  ...state,
23
23
  hasIcons: true
24
24
  };
25
+ case 'enableSelectableItems':
26
+ return {
27
+ ...state,
28
+ hasSelectableItems: true
29
+ };
25
30
  case 'registerItem':
26
31
  return {
27
32
  ...state,
@@ -31,7 +31,7 @@ export interface MenuItemProps extends LiHTMLAttributes<HTMLLIElement> {
31
31
  */
32
32
  onClick?: (event: KeyboardEvent<HTMLLIElement> | MouseEvent<HTMLLIElement>) => void;
33
33
  /**
34
- * Only applicable if the parent menu is in `basic` mode. Sets the menu item's icon.
34
+ * Sets the menu item's icon.
35
35
  */
36
36
  renderIcon?: FC;
37
37
  /**
@@ -10,11 +10,10 @@ import cx from 'classnames';
10
10
  import PropTypes from 'prop-types';
11
11
  import React__default, { forwardRef, useState, useContext, useRef, useEffect } from 'react';
12
12
  import { useFloating, autoUpdate, offset, useInteractions, useHover, safePolygon, FloatingFocusManager } from '@floating-ui/react';
13
- import { CaretLeft, CaretRight, Checkmark } from '@carbon/icons-react';
13
+ import { Checkmark, CaretLeft, CaretRight } from '@carbon/icons-react';
14
14
  import { useControllableState } from '../../internal/useControllableState.js';
15
15
  import { useMergedRefs } from '../../internal/useMergedRefs.js';
16
16
  import { usePrefix } from '../../internal/usePrefix.js';
17
- import { warning } from '../../internal/warning.js';
18
17
  import { Menu } from './Menu.js';
19
18
  import { MenuContext } from './MenuContext.js';
20
19
  import '../Text/index.js';
@@ -23,7 +22,7 @@ import { match } from '../../internal/keyboard/match.js';
23
22
  import { Text } from '../Text/Text.js';
24
23
  import { ArrowRight, Enter, Space } from '../../internal/keyboard/keys.js';
25
24
 
26
- var _CaretLeft, _CaretRight;
25
+ var _Checkmark, _CaretLeft, _CaretRight;
27
26
  const MenuItem = /*#__PURE__*/forwardRef(function MenuItem(_ref, forwardRef) {
28
27
  let {
29
28
  children,
@@ -134,15 +133,14 @@ const MenuItem = /*#__PURE__*/forwardRef(function MenuItem(_ref, forwardRef) {
134
133
  setRtl(false);
135
134
  }
136
135
  }, [direction]);
137
- const iconsAllowed = context.state.mode === 'basic' || rest.role === 'menuitemcheckbox' || rest.role === 'menuitemradio';
138
136
  useEffect(() => {
139
- if (iconsAllowed && IconElement && !context.state.hasIcons) {
137
+ if (IconElement && !context.state.hasIcons) {
140
138
  // @ts-ignore - TODO: Should we be passing payload?
141
139
  context.dispatch({
142
140
  type: 'enableIcons'
143
141
  });
144
142
  }
145
- }, [iconsAllowed, IconElement, context.state.hasIcons, context]);
143
+ }, [IconElement, context.state.hasIcons, context]);
146
144
  useEffect(() => {
147
145
  Object.keys(floatingStyles).forEach(style => {
148
146
  if (refs.floating.current && style !== 'position') {
@@ -166,8 +164,10 @@ const MenuItem = /*#__PURE__*/forwardRef(function MenuItem(_ref, forwardRef) {
166
164
  onClick: handleClick,
167
165
  onKeyDown: handleKeyDown
168
166
  }, getReferenceProps()), /*#__PURE__*/React__default.createElement("div", {
167
+ className: `${prefix}--menu-item__selection-icon`
168
+ }, rest['aria-checked'] && (_Checkmark || (_Checkmark = /*#__PURE__*/React__default.createElement(Checkmark, null)))), /*#__PURE__*/React__default.createElement("div", {
169
169
  className: `${prefix}--menu-item__icon`
170
- }, iconsAllowed && IconElement && /*#__PURE__*/React__default.createElement(IconElement, null)), /*#__PURE__*/React__default.createElement(Text, {
170
+ }, IconElement && /*#__PURE__*/React__default.createElement(IconElement, null)), /*#__PURE__*/React__default.createElement(Text, {
171
171
  as: "div",
172
172
  className: `${prefix}--menu-item__label`,
173
173
  title: label
@@ -212,7 +212,7 @@ MenuItem.propTypes = {
212
212
  // @ts-ignore-next-line -- avoid spurious (?) TS2322 error
213
213
  onClick: PropTypes.func,
214
214
  /**
215
- * Only applicable if the parent menu is in `basic` mode. Sets the menu item's icon.
215
+ * Sets the menu item's icon.
216
216
  */
217
217
  // @ts-ignore-next-line -- avoid spurious (?) TS2322 error
218
218
  renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
@@ -233,9 +233,6 @@ const MenuItemSelectable = /*#__PURE__*/forwardRef(function MenuItemSelectable(_
233
233
  } = _ref2;
234
234
  const prefix = usePrefix();
235
235
  const context = useContext(MenuContext);
236
- if (context.state.mode === 'basic') {
237
- process.env.NODE_ENV !== "production" ? warning(false, 'MenuItemSelectable is not supported when the menu is in "basic" mode.') : void 0;
238
- }
239
236
  const [checked, setChecked] = useControllableState({
240
237
  value: selected,
241
238
  onChange,
@@ -245,13 +242,13 @@ const MenuItemSelectable = /*#__PURE__*/forwardRef(function MenuItemSelectable(_
245
242
  setChecked(!checked);
246
243
  }
247
244
  useEffect(() => {
248
- if (!context.state.hasIcons) {
245
+ if (!context.state.hasSelectableItems) {
249
246
  // @ts-ignore - TODO: Should we be passing payload?
250
247
  context.dispatch({
251
- type: 'enableIcons'
248
+ type: 'enableSelectableItems'
252
249
  });
253
250
  }
254
- }, [context.state.hasIcons, context]);
251
+ }, [context.state.hasSelectableItems, context]);
255
252
  const classNames = cx(className, `${prefix}--menu-item-selectable--selected`);
256
253
  return /*#__PURE__*/React__default.createElement(MenuItem, _extends({}, rest, {
257
254
  ref: forwardRef,
@@ -259,7 +256,6 @@ const MenuItemSelectable = /*#__PURE__*/forwardRef(function MenuItemSelectable(_
259
256
  className: classNames,
260
257
  role: "menuitemcheckbox",
261
258
  "aria-checked": checked,
262
- renderIcon: checked ? Checkmark : undefined,
263
259
  onClick: handleClick
264
260
  }));
265
261
  });
@@ -334,9 +330,6 @@ const MenuItemRadioGroup = /*#__PURE__*/forwardRef(function MenuItemRadioGroup(_
334
330
  } = _ref4;
335
331
  const prefix = usePrefix();
336
332
  const context = useContext(MenuContext);
337
- if (context.state.mode === 'basic') {
338
- process.env.NODE_ENV !== "production" ? warning(false, 'MenuItemRadioGroup is not supported when the menu is in "basic" mode.') : void 0;
339
- }
340
333
  const [selection, setSelection] = useControllableState({
341
334
  value: selectedItem,
342
335
  onChange,
@@ -346,13 +339,13 @@ const MenuItemRadioGroup = /*#__PURE__*/forwardRef(function MenuItemRadioGroup(_
346
339
  setSelection(item);
347
340
  }
348
341
  useEffect(() => {
349
- if (!context.state.hasIcons) {
342
+ if (!context.state.hasSelectableItems) {
350
343
  // @ts-ignore - TODO: Should we be passing payload?
351
344
  context.dispatch({
352
- type: 'enableIcons'
345
+ type: 'enableSelectableItems'
353
346
  });
354
347
  }
355
- }, [context.state.hasIcons, context]);
348
+ }, [context.state.hasSelectableItems, context]);
356
349
  const classNames = cx(className, `${prefix}--menu-item-radio-group`);
357
350
  return /*#__PURE__*/React__default.createElement("li", {
358
351
  className: classNames,
@@ -366,7 +359,6 @@ const MenuItemRadioGroup = /*#__PURE__*/forwardRef(function MenuItemRadioGroup(_
366
359
  label: itemToString(item),
367
360
  role: "menuitemradio",
368
361
  "aria-checked": item === selection,
369
- renderIcon: item === selection ? Checkmark : undefined,
370
362
  onClick: e => {
371
363
  handleClick(item);
372
364
  }
@@ -73,6 +73,15 @@ const MenuButton = /*#__PURE__*/forwardRef(function MenuButton(_ref, forwardRef)
73
73
  // “break” the floating element out of a clipping ancestor.
74
74
  // https://floating-ui.com/docs/misc#clipping
75
75
  strategy: 'fixed',
76
+ // Submenus are using a fixed position to break out of the parent menu's
77
+ // box avoiding clipping while allowing for vertical scroll. When an
78
+ // element is using transform it establishes a new containing block
79
+ // block for all of its descendants. Therefore, its padding box will be
80
+ // used for fixed-positioned descendants. This would cause the submenu
81
+ // to be clipped by its parent menu.
82
+ // Reference: https://www.w3.org/TR/2019/CR-css-transforms-1-20190214/#current-transformation-matrix-computation
83
+ // Reference: https://github.com/carbon-design-system/carbon/pull/18153#issuecomment-2498548835
84
+ transform: false,
76
85
  // Middleware order matters, arrow should be last
77
86
  middleware: middlewares,
78
87
  whileElementsMounted: autoUpdate
@@ -87,7 +96,11 @@ const MenuButton = /*#__PURE__*/forwardRef(function MenuButton(_ref, forwardRef)
87
96
  useLayoutEffect(() => {
88
97
  Object.keys(floatingStyles).forEach(style => {
89
98
  if (refs.floating.current) {
90
- refs.floating.current.style[style] = floatingStyles[style];
99
+ let value = floatingStyles[style];
100
+ if (['top', 'right', 'bottom', 'left'].includes(style) && Number(value)) {
101
+ value += 'px';
102
+ }
103
+ refs.floating.current.style[style] = value;
91
104
  }
92
105
  });
93
106
  }, [floatingStyles, refs.floating, middlewareData, placement, open]);
@@ -126,7 +139,6 @@ const MenuButton = /*#__PURE__*/forwardRef(function MenuButton(_ref, forwardRef)
126
139
  id: id,
127
140
  legacyAutoalign: false,
128
141
  label: label,
129
- mode: "basic",
130
142
  size: size$1,
131
143
  open: open,
132
144
  onClose: handleClose,
@@ -730,11 +730,9 @@ function Callout(_ref8) {
730
730
  [`${prefix}--actionable-notification--${kind}`]: kind,
731
731
  [`${prefix}--actionable-notification--hide-close-button`]: true
732
732
  });
733
- const ref = useRef(null);
734
- useInteractiveChildrenNeedDescription(ref, `interactive child node(s) should have an \`aria-describedby\` property with a value matching the value of \`titleId\``);
735
- return /*#__PURE__*/React__default.createElement("div", _extends({
736
- ref: ref
737
- }, rest, {
733
+ const childrenContainer = useRef(null);
734
+ useInteractiveChildrenNeedDescription(childrenContainer, `interactive child node(s) should have an \`aria-describedby\` property with a value matching the value of \`titleId\``);
735
+ return /*#__PURE__*/React__default.createElement("div", _extends({}, rest, {
738
736
  className: containerClassName
739
737
  }), /*#__PURE__*/React__default.createElement("div", {
740
738
  className: `${prefix}--actionable-notification__details`
@@ -743,6 +741,7 @@ function Callout(_ref8) {
743
741
  kind: kind,
744
742
  iconDescription: statusIconDescription || `${kind} icon`
745
743
  }), /*#__PURE__*/React__default.createElement("div", {
744
+ ref: childrenContainer,
746
745
  className: `${prefix}--actionable-notification__text-wrapper`
747
746
  }, title && /*#__PURE__*/React__default.createElement(Text, {
748
747
  as: "div",
@@ -226,7 +226,7 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
226
226
  const textInput = React.useRef(null);
227
227
  const comboBoxInstanceId = useId.useId();
228
228
  const [isFocused, setIsFocused] = React.useState(false);
229
- const savedOnInputChange = React.useRef(onInputChange);
229
+ const prevInputValue = React.useRef(inputValue);
230
230
  const prevSelectedItemProp = React.useRef(selectedItemProp);
231
231
 
232
232
  // fully controlled combobox: handle changes to selectedItemProp
@@ -257,12 +257,12 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
257
257
  itemToString,
258
258
  inputValue
259
259
  }) : defaultShouldFilterItem());
260
+
261
+ // call onInputChange whenever inputValue is updated
260
262
  React.useEffect(() => {
261
- savedOnInputChange.current = onInputChange;
262
- }, [onInputChange]);
263
- React.useEffect(() => {
264
- if (savedOnInputChange.current) {
265
- savedOnInputChange.current(inputValue);
263
+ if (prevInputValue.current !== inputValue) {
264
+ prevInputValue.current = inputValue;
265
+ onInputChange && onInputChange(inputValue);
266
266
  }
267
267
  }, [inputValue]);
268
268
  const handleSelectionClear = () => {
@@ -176,7 +176,6 @@ const ComboButton = /*#__PURE__*/React__default["default"].forwardRef(function C
176
176
  ref: refs.setFloating,
177
177
  id: id,
178
178
  label: t('carbon.combo-button.additional-actions'),
179
- mode: "basic",
180
179
  size: size,
181
180
  open: open,
182
181
  onClose: handleClose
@@ -10,7 +10,6 @@ export interface ContextMenuProps {
10
10
  x: number;
11
11
  y: number;
12
12
  onClose: () => void;
13
- mode: string;
14
13
  }
15
14
  /**
16
15
  * @param {TriggerType} [trigger=document] The element or ref which should trigger the Menu on right-click
@@ -45,8 +45,7 @@ function useContextMenu() {
45
45
  open,
46
46
  x: position[0],
47
47
  y: position[1],
48
- onClose,
49
- mode: 'full'
48
+ onClose
50
49
  };
51
50
  }
52
51
 
@@ -27,6 +27,7 @@ export interface MenuProps extends React.HTMLAttributes<HTMLUListElement> {
27
27
  */
28
28
  menuAlignment?: string;
29
29
  /**
30
+ * @deprecated Menus now always support both icons as well as selectable items and nesting.
30
31
  * The mode of this menu. Defaults to full.
31
32
  * `full` supports nesting and selectable menu items, but no icons.
32
33
  * `basic` supports icons but no nesting or selectable menu items.
@@ -16,7 +16,7 @@ var React = require('react');
16
16
  var ReactDOM = require('react-dom');
17
17
  var useMergedRefs = require('../../internal/useMergedRefs.js');
18
18
  var usePrefix = require('../../internal/usePrefix.js');
19
- var warning = require('../../internal/warning.js');
19
+ var deprecate = require('../../prop-types/deprecate.js');
20
20
  var MenuContext = require('./MenuContext.js');
21
21
  var environment = require('../../internal/environment.js');
22
22
  var useLayoutDirection = require('../LayoutDirection/useLayoutDirection.js');
@@ -38,7 +38,7 @@ const Menu = /*#__PURE__*/React.forwardRef(function Menu(_ref, forwardRef) {
38
38
  containerRef,
39
39
  label,
40
40
  menuAlignment,
41
- mode = 'full',
41
+ mode,
42
42
  onClose,
43
43
  onOpen,
44
44
  open,
@@ -54,14 +54,10 @@ const Menu = /*#__PURE__*/React.forwardRef(function Menu(_ref, forwardRef) {
54
54
  const focusReturn = React.useRef(null);
55
55
  const context = React.useContext(MenuContext.MenuContext);
56
56
  const isRoot = context.state.isRoot;
57
- if (context.state.mode === 'basic' && !isRoot) {
58
- process.env.NODE_ENV !== "production" ? warning.warning(false, 'Nested menus are not supported when the menu is in "basic" mode.') : void 0;
59
- }
60
57
  const menuSize = isRoot ? size : context.state.size;
61
58
  const [childState, childDispatch] = React.useReducer(MenuContext.menuReducer, {
62
59
  ...context.state,
63
60
  isRoot: false,
64
- mode,
65
61
  size,
66
62
  requestCloseRoot: isRoot ? handleClose : context.state.requestCloseRoot
67
63
  });
@@ -293,6 +289,7 @@ const Menu = /*#__PURE__*/React.forwardRef(function Menu(_ref, forwardRef) {
293
289
  [`${prefix}--menu--open`]: open,
294
290
  [`${prefix}--menu--shown`]: open && !legacyAutoalign || position[0] >= 0 && position[1] >= 0,
295
291
  [`${prefix}--menu--with-icons`]: childContext.state.hasIcons,
292
+ [`${prefix}--menu--with-selectable-items`]: childContext.state.hasSelectableItems,
296
293
  [`${prefix}--autoalign`]: !legacyAutoalign
297
294
  });
298
295
  const rendered = /*#__PURE__*/React__default["default"].createElement(MenuContext.MenuContext.Provider, {
@@ -330,13 +327,14 @@ Menu.propTypes = {
330
327
  */
331
328
  menuAlignment: PropTypes__default["default"].string,
332
329
  /**
330
+ * **Deprecated**: Menus now always support both icons as well as selectable items and nesting.
333
331
  * The mode of this menu. Defaults to full.
334
332
  * `full` supports nesting and selectable menu items, but no icons.
335
333
  * `basic` supports icons but no nesting or selectable menu items.
336
334
  *
337
335
  * **This prop is not intended for use and will be set by the respective implementation (like useContextMenu, MenuButton, and ComboButton).**
338
336
  */
339
- mode: PropTypes__default["default"].oneOf(['full', 'basic']),
337
+ mode: deprecate["default"](PropTypes__default["default"].oneOf(['full', 'basic']), 'Menus now always support both icons as well as selectable items and nesting.'),
340
338
  /**
341
339
  * Provide an optional function to be called when the Menu should be closed.
342
340
  */
@@ -6,13 +6,13 @@
6
6
  */
7
7
  import { KeyboardEvent, RefObject } from 'react';
8
8
  type ActionType = {
9
- type: 'enableIcons' | 'registerItem';
9
+ type: 'enableIcons' | 'enableSelectableItems' | 'registerItem';
10
10
  payload: any;
11
11
  };
12
12
  type StateType = {
13
13
  isRoot: boolean;
14
- mode: 'full' | 'basic';
15
14
  hasIcons: boolean;
15
+ hasSelectableItems: boolean;
16
16
  size: 'xs' | 'sm' | 'md' | 'lg' | null;
17
17
  items: any[];
18
18
  requestCloseRoot: (e: Pick<KeyboardEvent<HTMLUListElement>, 'type'>) => void;
@@ -20,13 +20,13 @@ type StateType = {
20
20
  declare function menuReducer(state: StateType, action: ActionType): {
21
21
  hasIcons: boolean;
22
22
  isRoot: boolean;
23
- mode: "full" | "basic";
23
+ hasSelectableItems: boolean;
24
24
  size: "xs" | "sm" | "md" | "lg" | null;
25
25
  items: any[];
26
26
  requestCloseRoot: (e: Pick<KeyboardEvent<HTMLUListElement>, "type">) => void;
27
27
  };
28
28
  type DispatchFuncProps = {
29
- type: 'registerItem' | 'enableIcons';
29
+ type: ActionType['type'];
30
30
  payload: {
31
31
  ref: RefObject<HTMLLIElement>;
32
32
  disabled: boolean;
@@ -13,8 +13,8 @@ var React = require('react');
13
13
 
14
14
  const menuDefaultState = {
15
15
  isRoot: true,
16
- mode: 'full',
17
16
  hasIcons: false,
17
+ hasSelectableItems: false,
18
18
  size: null,
19
19
  items: [],
20
20
  requestCloseRoot: () => {}
@@ -26,6 +26,11 @@ function menuReducer(state, action) {
26
26
  ...state,
27
27
  hasIcons: true
28
28
  };
29
+ case 'enableSelectableItems':
30
+ return {
31
+ ...state,
32
+ hasSelectableItems: true
33
+ };
29
34
  case 'registerItem':
30
35
  return {
31
36
  ...state,
@@ -31,7 +31,7 @@ export interface MenuItemProps extends LiHTMLAttributes<HTMLLIElement> {
31
31
  */
32
32
  onClick?: (event: KeyboardEvent<HTMLLIElement> | MouseEvent<HTMLLIElement>) => void;
33
33
  /**
34
- * Only applicable if the parent menu is in `basic` mode. Sets the menu item's icon.
34
+ * Sets the menu item's icon.
35
35
  */
36
36
  renderIcon?: FC;
37
37
  /**