@carbon/react 1.23.0 → 1.23.1

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.
Files changed (47) hide show
  1. package/es/components/Dropdown/Dropdown.Skeleton.d.ts +15 -0
  2. package/es/components/Dropdown/Dropdown.Skeleton.js +1 -2
  3. package/es/components/Dropdown/index.js +1 -0
  4. package/es/components/FluidDropdown/FluidDropdown.js +1 -0
  5. package/es/components/Heading/index.js +11 -4
  6. package/es/components/Menu/Menu.js +164 -216
  7. package/es/components/Menu/MenuContext.js +44 -0
  8. package/es/components/Menu/MenuItem.js +401 -23
  9. package/es/components/MultiSelect/MultiSelect.js +6 -0
  10. package/es/components/OverflowMenu/OverflowMenu.js +2 -2
  11. package/es/components/OverflowMenuV2/index.js +4 -14
  12. package/es/components/Search/Search.js +3 -3
  13. package/es/index.d.ts +1 -1
  14. package/es/index.js +2 -6
  15. package/es/prop-types/isRequiredOneOf.js +2 -2
  16. package/lib/components/Dropdown/Dropdown.Skeleton.d.ts +15 -0
  17. package/lib/components/Dropdown/Dropdown.Skeleton.js +1 -2
  18. package/lib/components/Dropdown/index.js +2 -0
  19. package/lib/components/FluidDropdown/FluidDropdown.js +1 -0
  20. package/lib/components/Heading/index.js +11 -4
  21. package/lib/components/Menu/Menu.js +163 -216
  22. package/lib/components/Menu/MenuContext.js +53 -0
  23. package/lib/components/Menu/MenuItem.js +406 -23
  24. package/lib/components/MultiSelect/MultiSelect.js +6 -0
  25. package/lib/components/OverflowMenu/OverflowMenu.js +2 -2
  26. package/lib/components/OverflowMenuV2/index.js +5 -15
  27. package/lib/components/Search/Search.js +3 -3
  28. package/lib/index.d.ts +1 -1
  29. package/lib/index.js +7 -11
  30. package/lib/prop-types/isRequiredOneOf.js +2 -2
  31. package/package.json +4 -4
  32. package/es/components/Menu/MenuDivider.js +0 -19
  33. package/es/components/Menu/MenuGroup.js +0 -34
  34. package/es/components/Menu/MenuOption.js +0 -250
  35. package/es/components/Menu/MenuRadioGroup.js +0 -50
  36. package/es/components/Menu/MenuRadioGroupOptions.js +0 -64
  37. package/es/components/Menu/MenuSelectableItem.js +0 -57
  38. package/es/components/Menu/_utils.js +0 -177
  39. package/es/components/Menu/index.js +0 -25
  40. package/lib/components/Menu/MenuDivider.js +0 -27
  41. package/lib/components/Menu/MenuGroup.js +0 -43
  42. package/lib/components/Menu/MenuOption.js +0 -260
  43. package/lib/components/Menu/MenuRadioGroup.js +0 -59
  44. package/lib/components/Menu/MenuRadioGroupOptions.js +0 -73
  45. package/lib/components/Menu/MenuSelectableItem.js +0 -66
  46. package/lib/components/Menu/_utils.js +0 -191
  47. package/lib/components/Menu/index.js +0 -31
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2023
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import React from 'react';
8
+ import { ListBoxSize } from '../ListBox';
9
+ import { ReactAttr } from '../../types/common';
10
+ export interface DropdownSkeletonProps extends ReactAttr<HTMLDivElement> {
11
+ size?: ListBoxSize;
12
+ }
13
+ declare const DropdownSkeleton: React.FC<DropdownSkeletonProps>;
14
+ export default DropdownSkeleton;
15
+ export { DropdownSkeleton };
@@ -42,6 +42,5 @@ DropdownSkeleton.propTypes = {
42
42
  */
43
43
  size: ListBoxSize
44
44
  };
45
- var DropdownSkeleton$1 = DropdownSkeleton;
46
45
 
47
- export { DropdownSkeleton, DropdownSkeleton$1 as default };
46
+ export { DropdownSkeleton, DropdownSkeleton as default };
@@ -7,3 +7,4 @@
7
7
 
8
8
  import Dropdown from './Dropdown.js';
9
9
  export { default as Dropdown, default } from './Dropdown.js';
10
+ export { default as DropdownSkeleton } from './Dropdown.Skeleton.js';
@@ -10,6 +10,7 @@ import PropTypes from 'prop-types';
10
10
  import React__default from 'react';
11
11
  import cx from 'classnames';
12
12
  import Dropdown from '../Dropdown/Dropdown.js';
13
+ import '../Dropdown/Dropdown.Skeleton.js';
13
14
  import { usePrefix } from '../../internal/usePrefix.js';
14
15
  import { FormContext } from '../FluidForm/FormContext.js';
15
16
 
@@ -9,18 +9,20 @@ import { objectWithoutProperties as _objectWithoutProperties } from '../../_virt
9
9
  import PropTypes from 'prop-types';
10
10
  import React__default from 'react';
11
11
 
12
- var _excluded = ["as", "children"];
12
+ var _excluded = ["as", "level", "children"];
13
13
  var HeadingContext = /*#__PURE__*/React__default.createContext(1);
14
14
 
15
15
  function Section(_ref) {
16
16
  var _ref$as = _ref.as,
17
17
  BaseComponent = _ref$as === void 0 ? 'section' : _ref$as,
18
+ levelOverride = _ref.level,
18
19
  children = _ref.children,
19
20
  rest = _objectWithoutProperties(_ref, _excluded);
20
21
 
21
- var level = React__default.useContext(HeadingContext);
22
+ var parentLevel = React__default.useContext(HeadingContext);
23
+ var level = typeof levelOverride !== 'undefined' ? levelOverride : parentLevel + 1;
22
24
  return /*#__PURE__*/React__default.createElement(HeadingContext.Provider, {
23
- value: Math.min(level + 1, 6)
25
+ value: Math.min(level, 6)
24
26
  }, /*#__PURE__*/React__default.createElement(BaseComponent, rest, children));
25
27
  }
26
28
 
@@ -39,7 +41,12 @@ Section.propTypes = {
39
41
  /**
40
42
  * Specify a class name for the outermost node of the component
41
43
  */
42
- className: PropTypes.string
44
+ className: PropTypes.string,
45
+
46
+ /**
47
+ * Overrides the level of the section
48
+ */
49
+ level: PropTypes.number
43
50
  };
44
51
 
45
52
  function Heading(props) {
@@ -5,62 +5,70 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, defineProperty as _defineProperty, objectSpread2 as _objectSpread2, typeof as _typeof } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
- import React__default, { useRef, useState, useEffect } from 'react';
10
- import ReactDOM from 'react-dom';
8
+ import { objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2, slicedToArray as _slicedToArray, defineProperty as _defineProperty, extends as _extends, typeof as _typeof } from '../../_virtual/_rollupPluginBabelHelpers.js';
11
9
  import cx from 'classnames';
12
10
  import PropTypes from 'prop-types';
11
+ import React__default, { useRef, useContext, useReducer, useMemo, useState, useEffect } from 'react';
12
+ import { createPortal } from 'react-dom';
13
+ import { useMergedRefs } from '../../internal/useMergedRefs.js';
13
14
  import { usePrefix } from '../../internal/usePrefix.js';
14
- import { getParentMenu, getNextNode, getParentNode, getValidNodes, clickedElementHasSubnodes, getPosition, capWithinRange, resetFocus, focusNode } from './_utils.js';
15
- import MenuGroup from './MenuGroup.js';
16
- import MenuRadioGroup from './MenuRadioGroup.js';
17
- import MenuRadioGroupOptions from './MenuRadioGroupOptions.js';
18
- import MenuSelectableItem from './MenuSelectableItem.js';
15
+ import { MenuContext, menuReducer } from './MenuContext.js';
19
16
  import { match } from '../../internal/keyboard/match.js';
20
- import { Tab, Enter, Space, Escape, ArrowLeft, ArrowUp, ArrowDown } from '../../internal/keyboard/keys.js';
17
+ import { Escape, ArrowLeft, ArrowUp, ArrowDown } from '../../internal/keyboard/keys.js';
21
18
 
22
- var _excluded = ["children", "className", "id", "level", "open", "size", "target", "x", "y", "onClose"];
23
- var margin = 16; // distance to keep to body edges, in px
19
+ var _excluded = ["children", "className", "label", "onClose", "open", "size", "target", "x", "y"];
20
+ var spacing = 8; // distance to keep to window edges, in px
24
21
 
25
- var defaultSize = 'sm';
26
-
27
- var Menu = function Menu(_ref) {
28
- var _classnames;
22
+ var Menu = /*#__PURE__*/React__default.forwardRef(function Menu(_ref, forwardRef) {
23
+ var _cx;
29
24
 
30
25
  var children = _ref.children,
31
26
  className = _ref.className,
32
- id = _ref.id,
33
- _ref$level = _ref.level,
34
- level = _ref$level === void 0 ? 1 : _ref$level,
27
+ label = _ref.label,
28
+ onClose = _ref.onClose,
35
29
  open = _ref.open,
36
30
  _ref$size = _ref.size,
37
- size = _ref$size === void 0 ? defaultSize : _ref$size,
31
+ size = _ref$size === void 0 ? 'sm' : _ref$size,
38
32
  _ref$target = _ref.target,
39
33
  target = _ref$target === void 0 ? document.body : _ref$target,
40
34
  _ref$x = _ref.x,
41
35
  x = _ref$x === void 0 ? 0 : _ref$x,
42
36
  _ref$y = _ref.y,
43
37
  y = _ref$y === void 0 ? 0 : _ref$y,
44
- _ref$onClose = _ref.onClose,
45
- onClose = _ref$onClose === void 0 ? function () {} : _ref$onClose,
46
38
  rest = _objectWithoutProperties(_ref, _excluded);
47
39
 
48
- var rootRef = useRef(null);
49
-
50
- var _useState = useState(1),
40
+ var prefix = usePrefix();
41
+ var focusReturn = useRef(null);
42
+ var context = useContext(MenuContext);
43
+ var isRoot = context.state.isRoot;
44
+ var menuSize = isRoot ? size : context.state.size;
45
+
46
+ var _useReducer = useReducer(menuReducer, _objectSpread2(_objectSpread2({}, context.state), {}, {
47
+ isRoot: false,
48
+ size: size,
49
+ requestCloseRoot: isRoot ? handleClose : context.state.requestCloseRoot
50
+ })),
51
+ _useReducer2 = _slicedToArray(_useReducer, 2),
52
+ childState = _useReducer2[0],
53
+ childDispatch = _useReducer2[1];
54
+
55
+ var childContext = useMemo(function () {
56
+ return {
57
+ state: childState,
58
+ dispatch: childDispatch
59
+ };
60
+ }, [childState, childDispatch]);
61
+ var menu = useRef();
62
+ var ref = useMergedRefs([forwardRef, menu]);
63
+
64
+ var _useState = useState([-1, -1]),
51
65
  _useState2 = _slicedToArray(_useState, 2),
52
- direction = _useState2[0],
53
- setDirection = _useState2[1]; // 1 = to right, -1 = to left
54
-
66
+ position = _useState2[0],
67
+ setPosition = _useState2[1];
55
68
 
56
- var _useState3 = useState([x, y]),
57
- _useState4 = _slicedToArray(_useState3, 2),
58
- position = _useState4[0],
59
- setPosition = _useState4[1];
60
-
61
- var isRootMenu = level === 1;
62
- var focusReturn = useRef(null);
63
- var prefix = usePrefix();
69
+ var focusableItems = childContext.state.items.filter(function (item) {
70
+ return !item.disabled;
71
+ });
64
72
 
65
73
  function returnFocus() {
66
74
  if (focusReturn.current) {
@@ -68,261 +76,201 @@ var Menu = function Menu(_ref) {
68
76
  }
69
77
  }
70
78
 
71
- function close(eventType) {
72
- var isKeyboardEvent = /^key/.test(eventType);
79
+ function handleOpen() {
80
+ if (menu.current) {
81
+ focusReturn.current = document.activeElement;
82
+ setPosition(calculatePosition());
83
+ menu.current.focus();
84
+ }
85
+ }
73
86
 
74
- if (isKeyboardEvent) {
87
+ function handleClose(e) {
88
+ if (/^key/.test(e.type)) {
75
89
  window.addEventListener('keyup', returnFocus, {
76
90
  once: true
77
91
  });
78
- } else {
79
- window.addEventListener('mouseup', returnFocus, {
92
+ } else if (e.type === 'click' && menu.current) {
93
+ menu.current.addEventListener('focusout', returnFocus, {
80
94
  once: true
81
95
  });
96
+ } else {
97
+ returnFocus();
82
98
  }
83
99
 
84
- onClose();
85
- }
86
-
87
- function getContainerBoundaries() {
88
- var _document$body = document.body,
89
- bodyWidth = _document$body.clientWidth,
90
- bodyHeight = _document$body.clientHeight;
91
- return [margin, margin, bodyWidth - margin, bodyHeight - margin];
92
- }
93
-
94
- function getTargetBoundaries() {
95
- var xIsRange = _typeof(x) === 'object' && x.length === 2;
96
- var yIsRange = _typeof(y) === 'object' && y.length === 2;
97
- var targetBoundaries = [xIsRange ? x[0] : x, yIsRange ? y[0] : y, xIsRange ? x[1] : x, yIsRange ? y[1] : y];
98
-
99
- if (!isRootMenu) {
100
- var _getParentMenu;
101
-
102
- var _getParentMenu$getBou = (_getParentMenu = getParentMenu(rootRef.current)) === null || _getParentMenu === void 0 ? void 0 : _getParentMenu.getBoundingClientRect(),
103
- parentWidth = _getParentMenu$getBou.width;
104
-
105
- targetBoundaries[2] -= parentWidth;
106
- }
107
-
108
- var containerBoundaries = getContainerBoundaries();
109
- return [capWithinRange(targetBoundaries[0], containerBoundaries[0], containerBoundaries[2]), capWithinRange(targetBoundaries[1], containerBoundaries[1], containerBoundaries[3]), capWithinRange(targetBoundaries[2], containerBoundaries[0], containerBoundaries[2]), capWithinRange(targetBoundaries[3], containerBoundaries[1], containerBoundaries[3])];
110
- }
100
+ childDispatch({
101
+ type: 'clearRegisteredItems'
102
+ });
111
103
 
112
- function focusNode$1(node) {
113
- if (node) {
114
- resetFocus(rootRef.current);
115
- focusNode(node);
104
+ if (onClose) {
105
+ onClose();
116
106
  }
117
107
  }
118
108
 
119
- function handleKeyDown(event) {
120
- if (match(event, Tab)) {
121
- event.preventDefault();
122
- close(event.type);
123
- }
109
+ function handleKeyDown(e) {
110
+ e.stopPropagation();
111
+ var currentItem = focusableItems.findIndex(function (item) {
112
+ return item.ref.current.contains(document.activeElement);
113
+ });
114
+ var indexToFocus = currentItem; // if the user presses escape or this is a submenu
115
+ // and the user presses ArrowLeft, close it
124
116
 
125
- if (event.target.tagName === 'LI' && (match(event, Enter) || match(event, Space))) {
126
- handleClick(event);
117
+ if ((match(e, Escape) || !isRoot && match(e, ArrowLeft)) && onClose) {
118
+ handleClose(e);
127
119
  } else {
128
- event.stopPropagation();
129
- }
130
-
131
- if (match(event, Escape) || !isRootMenu && match(event, ArrowLeft)) {
132
- close(event.type);
133
- }
134
-
135
- var nodeToFocus;
136
-
137
- if (event.target.tagName === 'LI') {
138
- var currentNode = event.target;
120
+ // if currentItem is -1, the menu itself is focused.
121
+ // in this case, the arrow keys define the first item
122
+ // to be focused.
123
+ if (match(e, ArrowUp)) {
124
+ indexToFocus = currentItem === -1 ? focusableItems.length - 1 : indexToFocus - 1;
125
+ }
139
126
 
140
- if (match(event, ArrowUp)) {
141
- nodeToFocus = getNextNode(currentNode, -1);
142
- } else if (match(event, ArrowDown)) {
143
- nodeToFocus = getNextNode(currentNode, 1);
144
- } else if (match(event, ArrowLeft)) {
145
- nodeToFocus = getParentNode(currentNode);
127
+ if (match(e, ArrowDown)) {
128
+ indexToFocus = currentItem === -1 ? 0 : indexToFocus + 1;
146
129
  }
147
- } else if (event.target.tagName === 'UL') {
148
- var validNodes = getValidNodes(event.target);
149
130
 
150
- if (validNodes.length > 0 && match(event, ArrowUp)) {
151
- nodeToFocus = validNodes[validNodes.length - 1];
152
- } else if (validNodes.length > 0 && match(event, ArrowDown)) {
153
- nodeToFocus = validNodes[0];
131
+ if (indexToFocus < 0) {
132
+ indexToFocus = 0;
154
133
  }
155
- }
156
134
 
157
- focusNode$1(nodeToFocus);
135
+ if (indexToFocus >= focusableItems.length) {
136
+ indexToFocus = focusableItems.length - 1;
137
+ }
158
138
 
159
- if (rest.onKeyDown) {
160
- rest.onKeyDown(event);
139
+ if (indexToFocus !== currentItem) {
140
+ var nodeToFocus = focusableItems[indexToFocus];
141
+ nodeToFocus.ref.current.focus();
142
+ }
161
143
  }
162
144
  }
163
145
 
164
- function handleClick(event) {
165
- if (!clickedElementHasSubnodes(event) && event.target.tagName !== 'UL') {
166
- close(event.type);
167
- } else {
168
- event.stopPropagation();
146
+ function handleBlur(e) {
147
+ if (open && onClose && isRoot && !menu.current.contains(e.relatedTarget)) {
148
+ handleClose(e);
169
149
  }
170
150
  }
171
151
 
172
- function getCorrectedPosition(preferredDirection) {
173
- var _rootRef$current;
174
-
175
- var elementRect = (_rootRef$current = rootRef.current) === null || _rootRef$current === void 0 ? void 0 : _rootRef$current.getBoundingClientRect();
176
- var elementDimensions = [elementRect.width, elementRect.height];
177
- var targetBoundaries = getTargetBoundaries();
178
- var containerBoundaries = getContainerBoundaries();
152
+ function fitValue(range, axis) {
153
+ var _menu$current$getBoun = menu.current.getBoundingClientRect(),
154
+ width = _menu$current$getBoun.width,
155
+ height = _menu$current$getBoun.height;
156
+
157
+ var alignment = isRoot ? 'vertical' : 'horizontal';
158
+ var axes = {
159
+ x: {
160
+ max: window.innerWidth,
161
+ size: width,
162
+ anchor: alignment === 'horizontal' ? range[1] : range[0],
163
+ reversedAnchor: alignment === 'horizontal' ? range[0] : range[1],
164
+ offset: 0
165
+ },
166
+ y: {
167
+ max: window.innerHeight,
168
+ size: height,
169
+ anchor: alignment === 'horizontal' ? range[0] : range[1],
170
+ reversedAnchor: alignment === 'horizontal' ? range[1] : range[0],
171
+ offset: isRoot ? 0 : 4 // top padding in menu, used to align the menu items
179
172
 
180
- var _getPosition = getPosition(elementDimensions, targetBoundaries, containerBoundaries, preferredDirection, isRootMenu, rootRef.current),
181
- correctedPosition = _getPosition.position,
182
- correctedDirection = _getPosition.direction;
183
-
184
- setDirection(correctedDirection);
185
- return correctedPosition;
173
+ }
174
+ };
175
+ var _axes$axis = axes[axis],
176
+ max = _axes$axis.max,
177
+ size = _axes$axis.size,
178
+ anchor = _axes$axis.anchor,
179
+ reversedAnchor = _axes$axis.reversedAnchor,
180
+ offset = _axes$axis.offset; // get values for different scenarios, set to false if they don't work
181
+
182
+ var options = [// towards max (preferred)
183
+ max - spacing - size - anchor >= 0 ? anchor - offset : false, // towards min / reversed (first fallback)
184
+ reversedAnchor - size >= 0 ? reversedAnchor - size + offset : false, // align at max (second fallback)
185
+ max - spacing - size];
186
+ var bestOption = options.find(function (option) {
187
+ return option !== false;
188
+ });
189
+ return bestOption >= spacing ? bestOption : spacing;
186
190
  }
187
191
 
188
- function handleBlur(event) {
189
- var _rootRef$current2;
190
-
191
- if (isRootMenu && !((_rootRef$current2 = rootRef.current) !== null && _rootRef$current2 !== void 0 && _rootRef$current2.contains(event.relatedTarget))) {
192
- close(event.type);
192
+ function calculatePosition() {
193
+ if (menu.current) {
194
+ var ranges = {
195
+ x: _typeof(x) === 'object' && x.length === 2 ? x : [x, x],
196
+ y: _typeof(y) === 'object' && y.length === 2 ? y : [y, y]
197
+ };
198
+ return [fitValue(ranges.x, 'x'), fitValue(ranges.y, 'y')];
193
199
  }
200
+
201
+ return [-1, -1];
194
202
  }
195
203
 
196
204
  useEffect(function () {
197
205
  if (open) {
198
- focusReturn.current = document.activeElement;
199
- var localDirection = 1;
200
-
201
- if (isRootMenu) {
202
- var _rootRef$current3;
203
-
204
- (_rootRef$current3 = rootRef.current) === null || _rootRef$current3 === void 0 ? void 0 : _rootRef$current3.focus();
205
- } else {
206
- var parentMenu = getParentMenu(rootRef.current);
207
-
208
- if (parentMenu) {
209
- localDirection = Number(parentMenu.dataset.direction);
210
- }
211
- }
212
-
213
- var correctedPosition = getCorrectedPosition(localDirection);
214
- setPosition(correctedPosition);
215
- } else {
216
- setPosition([0, 0]);
206
+ handleOpen();
217
207
  } // eslint-disable-next-line react-hooks/exhaustive-deps
218
208
 
219
- }, [open, x, y]);
220
- var someNodesHaveIcons = React__default.Children.toArray(children).some(function (node) {
221
- return node.type === MenuSelectableItem || node.type === MenuRadioGroup;
222
- });
223
- var options = React__default.Children.map(children, function (node) {
224
- if ( /*#__PURE__*/React__default.isValidElement(node)) {
225
- return /*#__PURE__*/React__default.cloneElement(node, {
226
- indented: someNodesHaveIcons,
227
- level: level
228
- });
229
- }
230
- });
231
- var classes = cx("".concat(prefix, "--menu"), (_classnames = {}, _defineProperty(_classnames, "".concat(prefix, "--menu--open"), open), _defineProperty(_classnames, "".concat(prefix, "--menu--invisible"), open && position[0] === 0 && position[1] === 0), _defineProperty(_classnames, "".concat(prefix, "--menu--root"), isRootMenu), _classnames), size !== defaultSize && "".concat(prefix, "--menu--").concat(size), className);
232
-
233
- var ulAttributes = _objectSpread2(_objectSpread2({}, rest), {}, {
234
- id: id,
235
- ref: rootRef,
236
- className: classes,
237
- onKeyDown: handleKeyDown,
238
- onClick: handleClick,
239
- onBlur: handleBlur,
240
- role: 'menu',
209
+ }, [open]);
210
+ var classNames = cx(className, "".concat(prefix, "--menu"), "".concat(prefix, "--menu--").concat(menuSize), (_cx = {}, _defineProperty(_cx, "".concat(prefix, "--menu--open"), open), _defineProperty(_cx, "".concat(prefix, "--menu--shown"), position[0] >= 0 && position[1] >= 0), _defineProperty(_cx, "".concat(prefix, "--menu--with-icons"), childContext.state.hasIcons), _cx));
211
+ var rendered = /*#__PURE__*/React__default.createElement(MenuContext.Provider, {
212
+ value: childContext
213
+ }, /*#__PURE__*/React__default.createElement("ul", _extends({}, rest, {
214
+ className: classNames,
215
+ role: "menu",
216
+ ref: ref,
217
+ "aria-label": label,
241
218
  tabIndex: -1,
242
- 'data-direction': direction,
243
- 'data-level': level,
219
+ onKeyDown: handleKeyDown,
220
+ onBlur: handleBlur // eslint-disable-next-line react/forbid-dom-props
221
+ ,
244
222
  style: {
245
223
  left: "".concat(position[0], "px"),
246
224
  top: "".concat(position[1], "px")
247
225
  }
248
- });
249
-
250
- var childrenToRender = options; // if the only child is a radiogroup, don't render it as radiogroup component, but
251
- // only the items to prevent duplicate markup
252
-
253
- if (options && options.length === 1 && options[0].type === MenuRadioGroup) {
254
- var radioGroupProps = options[0].props;
255
- ulAttributes['aria-label'] = radioGroupProps.label;
256
- childrenToRender = /*#__PURE__*/React__default.createElement(MenuRadioGroupOptions, {
257
- items: radioGroupProps.items,
258
- initialSelectedItem: radioGroupProps.initialSelectedItem,
259
- onChange: radioGroupProps.onChange
260
- });
261
- } // if the only child is a generic group, don't render it as group component, but
262
- // only the children to prevent duplicate markup
263
-
264
-
265
- if (options && options.length === 1 && options[0].type === MenuGroup) {
266
- var groupProps = options[0].props;
267
- ulAttributes['aria-label'] = groupProps.label;
268
- childrenToRender = React__default.Children.toArray(options[0].props.children);
269
- }
270
-
271
- var menu = /*#__PURE__*/React__default.createElement("ul", ulAttributes, childrenToRender);
272
- return isRootMenu ? open && /*#__PURE__*/ReactDOM.createPortal(menu, target) || null : menu;
273
- };
274
-
226
+ }), children));
227
+ return isRoot ? open && /*#__PURE__*/createPortal(rendered, target) || null : rendered;
228
+ });
275
229
  Menu.propTypes = {
276
230
  /**
277
- * Specify the children of the Menu
231
+ * A collection of MenuItems to be rendered within this Menu.
278
232
  */
279
233
  children: PropTypes.node,
280
234
 
281
235
  /**
282
- * Specify a custom className to apply to the ul node
236
+ * Additional CSS class names.
283
237
  */
284
238
  className: PropTypes.string,
285
239
 
286
240
  /**
287
- * Define an ID for this menu
288
- */
289
- id: PropTypes.string,
290
-
291
- /**
292
- * Internal: keeps track of the nesting level of the menu
241
+ * A label describing the Menu.
293
242
  */
294
- level: PropTypes.number,
243
+ label: PropTypes.string,
295
244
 
296
245
  /**
297
- * Function called when the menu is closed
246
+ * Provide an optional function to be called when the Menu should be closed.
298
247
  */
299
248
  onClose: PropTypes.func,
300
249
 
301
250
  /**
302
- * Specify whether the Menu is currently open
251
+ * Whether the Menu is open or not.
303
252
  */
304
253
  open: PropTypes.bool,
305
254
 
306
255
  /**
307
- * Specify the size of the menu, from a list of available sizes.
256
+ * Specify the size of the Menu.
308
257
  */
309
- size: PropTypes.oneOf(['sm', 'md', 'lg']),
258
+ size: PropTypes.oneOf(['xs', 'sm', 'md', 'lg']),
310
259
 
311
260
  /**
312
- * Optionally pass an element the Menu should be appended to as a child. Defaults to document.body.
261
+ * Specify a DOM node where the Menu should be rendered in. Defaults to document.body.
313
262
  */
314
263
  target: PropTypes.object,
315
264
 
316
265
  /**
317
- * Specify the x position where this menu is rendered
266
+ * Specify the x position of the Menu. Either pass a single number or an array with two numbers describing your activator's boundaries ([x1, x2])
318
267
  */
319
268
  x: PropTypes.oneOfType([PropTypes.number, PropTypes.arrayOf(PropTypes.number)]),
320
269
 
321
270
  /**
322
- * Specify the y position where this menu is rendered
271
+ * Specify the y position of the Menu. Either pass a single number or an array with two numbers describing your activator's boundaries ([y1, y2])
323
272
  */
324
273
  y: PropTypes.oneOfType([PropTypes.number, PropTypes.arrayOf(PropTypes.number)])
325
274
  };
326
- var Menu$1 = Menu;
327
275
 
328
- export { Menu$1 as default };
276
+ export { Menu };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2022
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import { objectSpread2 as _objectSpread2, toConsumableArray as _toConsumableArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
+ import React__default from 'react';
10
+
11
+ var menuDefaultState = {
12
+ isRoot: true,
13
+ hasIcons: false,
14
+ size: null,
15
+ items: [],
16
+ requestCloseRoot: function requestCloseRoot() {}
17
+ };
18
+
19
+ function menuReducer(state, action) {
20
+ switch (action.type) {
21
+ case 'enableIcons':
22
+ return _objectSpread2(_objectSpread2({}, state), {}, {
23
+ hasIcons: true
24
+ });
25
+
26
+ case 'registerItem':
27
+ return _objectSpread2(_objectSpread2({}, state), {}, {
28
+ items: [].concat(_toConsumableArray(state.items), [action.payload])
29
+ });
30
+
31
+ case 'clearRegisteredItems':
32
+ return _objectSpread2(_objectSpread2({}, state), {}, {
33
+ items: []
34
+ });
35
+ }
36
+ }
37
+
38
+ var MenuContext = /*#__PURE__*/React__default.createContext({
39
+ state: menuDefaultState,
40
+ // 'dispatch' is populated by the root menu
41
+ dispatch: function dispatch() {}
42
+ });
43
+
44
+ export { MenuContext, menuReducer };