@carbon/react 1.32.0-rc.0 → 1.33.0-rc.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.
Files changed (86) hide show
  1. package/README.md +22 -7
  2. package/es/components/ComboBox/ComboBox.js +43 -10
  3. package/es/components/ContentSwitcher/ContentSwitcher.js +5 -5
  4. package/es/components/DataTable/DataTable.js +110 -130
  5. package/es/components/DataTable/Table.js +1 -1
  6. package/es/components/DatePicker/DatePicker.d.ts +14 -13
  7. package/es/components/DatePicker/DatePicker.js +3 -0
  8. package/es/components/DatePickerInput/DatePickerInput.d.ts +2 -2
  9. package/es/components/Dropdown/Dropdown.js +31 -6
  10. package/es/components/FileUploader/FileUploader.Skeleton.d.ts +29 -0
  11. package/es/components/FileUploader/FileUploader.d.ts +175 -0
  12. package/es/components/FileUploader/FileUploader.js +3 -3
  13. package/es/components/FileUploader/FileUploaderButton.d.ts +140 -0
  14. package/es/components/FileUploader/FileUploaderButton.js +11 -7
  15. package/es/components/FileUploader/FileUploaderDropContainer.d.ts +139 -0
  16. package/es/components/FileUploader/FileUploaderDropContainer.js +3 -3
  17. package/es/components/FileUploader/FileUploaderItem.d.ts +110 -0
  18. package/es/components/FileUploader/Filename.d.ts +71 -0
  19. package/es/components/FileUploader/Filename.js +6 -4
  20. package/es/components/InlineCheckbox/InlineCheckbox.js +3 -1
  21. package/es/components/Loading/Loading.d.ts +65 -0
  22. package/es/components/Notification/Notification.d.ts +4 -4
  23. package/es/components/Notification/Notification.js +3 -3
  24. package/es/components/OverflowMenu/OverflowMenu.js +36 -41
  25. package/es/components/Slider/Slider.js +59 -68
  26. package/es/components/Tabs/Tabs.d.ts +9 -1
  27. package/es/components/Tabs/Tabs.js +16 -3
  28. package/es/components/Toggle/Toggle.d.ts +129 -0
  29. package/es/components/Toggle/Toggle.js +2 -2
  30. package/es/components/Toggle/index.d.ts +11 -0
  31. package/es/components/UIShell/HeaderMenu.js +29 -36
  32. package/es/components/UIShell/HeaderName.d.ts +39 -0
  33. package/es/components/UIShell/HeaderName.js +2 -7
  34. package/es/components/UIShell/HeaderPanel.js +61 -5
  35. package/es/components/UIShell/Link.js +2 -1
  36. package/es/components/UIShell/SideNav.d.ts +1 -1
  37. package/es/components/UIShell/Switcher.js +45 -5
  38. package/es/components/UIShell/SwitcherItem.js +45 -6
  39. package/es/index.js +1 -1
  40. package/es/internal/FloatingMenu.js +47 -51
  41. package/es/internal/useControllableState.js +1 -1
  42. package/es/internal/useId.js +10 -1
  43. package/es/internal/useMatchMedia.js +44 -0
  44. package/lib/components/ComboBox/ComboBox.js +43 -10
  45. package/lib/components/ContentSwitcher/ContentSwitcher.js +5 -5
  46. package/lib/components/DataTable/DataTable.js +110 -130
  47. package/lib/components/DataTable/Table.js +1 -1
  48. package/lib/components/DatePicker/DatePicker.d.ts +14 -13
  49. package/lib/components/DatePicker/DatePicker.js +3 -0
  50. package/lib/components/DatePickerInput/DatePickerInput.d.ts +2 -2
  51. package/lib/components/Dropdown/Dropdown.js +30 -5
  52. package/lib/components/FileUploader/FileUploader.Skeleton.d.ts +29 -0
  53. package/lib/components/FileUploader/FileUploader.d.ts +175 -0
  54. package/lib/components/FileUploader/FileUploader.js +3 -3
  55. package/lib/components/FileUploader/FileUploaderButton.d.ts +140 -0
  56. package/lib/components/FileUploader/FileUploaderButton.js +11 -7
  57. package/lib/components/FileUploader/FileUploaderDropContainer.d.ts +139 -0
  58. package/lib/components/FileUploader/FileUploaderDropContainer.js +3 -3
  59. package/lib/components/FileUploader/FileUploaderItem.d.ts +110 -0
  60. package/lib/components/FileUploader/Filename.d.ts +71 -0
  61. package/lib/components/FileUploader/Filename.js +6 -4
  62. package/lib/components/InlineCheckbox/InlineCheckbox.js +3 -1
  63. package/lib/components/Loading/Loading.d.ts +65 -0
  64. package/lib/components/Notification/Notification.d.ts +4 -4
  65. package/lib/components/Notification/Notification.js +3 -3
  66. package/lib/components/OverflowMenu/OverflowMenu.js +36 -41
  67. package/lib/components/Slider/Slider.js +59 -68
  68. package/lib/components/Tabs/Tabs.d.ts +9 -1
  69. package/lib/components/Tabs/Tabs.js +16 -3
  70. package/lib/components/Toggle/Toggle.d.ts +129 -0
  71. package/lib/components/Toggle/Toggle.js +2 -2
  72. package/lib/components/Toggle/index.d.ts +11 -0
  73. package/lib/components/UIShell/HeaderMenu.js +29 -36
  74. package/lib/components/UIShell/HeaderName.d.ts +39 -0
  75. package/lib/components/UIShell/HeaderName.js +2 -7
  76. package/lib/components/UIShell/HeaderPanel.js +60 -4
  77. package/lib/components/UIShell/Link.js +2 -1
  78. package/lib/components/UIShell/SideNav.d.ts +1 -1
  79. package/lib/components/UIShell/Switcher.js +44 -4
  80. package/lib/components/UIShell/SwitcherItem.js +45 -6
  81. package/lib/index.js +2 -2
  82. package/lib/internal/FloatingMenu.js +47 -51
  83. package/lib/internal/useControllableState.js +1 -1
  84. package/lib/internal/useId.js +9 -0
  85. package/lib/internal/useMatchMedia.js +48 -0
  86. package/package.json +22 -19
@@ -6,19 +6,23 @@
6
6
  */
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
- import React__default from 'react';
9
+ import React__default, { useRef } from 'react';
10
10
  import cx from 'classnames';
11
11
  import PropTypes from 'prop-types';
12
12
  import { AriaLabelPropType } from '../../prop-types/AriaPropTypes.js';
13
13
  import { usePrefix } from '../../internal/usePrefix.js';
14
+ import { useMergedRefs } from '../../internal/useMergedRefs.js';
14
15
 
15
- const Switcher = /*#__PURE__*/React__default.forwardRef(function Switcher(props, ref) {
16
+ const Switcher = /*#__PURE__*/React__default.forwardRef(function Switcher(props, forwardRef) {
17
+ const switcherRef = useRef(null);
18
+ const ref = useMergedRefs([switcherRef, forwardRef]);
16
19
  const prefix = usePrefix();
17
20
  const {
18
21
  'aria-label': ariaLabel,
19
22
  'aria-labelledby': ariaLabelledBy,
20
23
  className: customClassName,
21
- children
24
+ children,
25
+ expanded
22
26
  } = props;
23
27
  const accessibilityLabel = {
24
28
  'aria-label': ariaLabel,
@@ -27,10 +31,42 @@ const Switcher = /*#__PURE__*/React__default.forwardRef(function Switcher(props,
27
31
  const className = cx(`${prefix}--switcher`, {
28
32
  [customClassName]: !!customClassName
29
33
  });
34
+ const handleSwitcherItemFocus = _ref => {
35
+ let {
36
+ currentIndex,
37
+ direction
38
+ } = _ref;
39
+ const enabledIndices = React__default.Children.toArray(children).reduce((acc, curr, i) => {
40
+ if (Object.keys(curr.props).length !== 0) {
41
+ acc.push(i);
42
+ }
43
+ return acc;
44
+ }, []);
45
+ const nextValidIndex = (() => {
46
+ const nextIndex = enabledIndices.indexOf(currentIndex) + direction;
47
+ switch (enabledIndices[nextIndex]) {
48
+ case undefined:
49
+ if (direction === -1) {
50
+ return enabledIndices[enabledIndices.length - 1];
51
+ }
52
+ return 0;
53
+ default:
54
+ return enabledIndices[nextIndex];
55
+ }
56
+ })();
57
+ const switcherItem = switcherRef.current.children[nextValidIndex].children[0];
58
+ switcherItem?.focus();
59
+ };
60
+ const childrenWithProps = React__default.Children.toArray(children).map((child, index) => /*#__PURE__*/React__default.cloneElement(child, {
61
+ handleSwitcherItemFocus,
62
+ index,
63
+ key: index,
64
+ expanded
65
+ }));
30
66
  return /*#__PURE__*/React__default.createElement("ul", _extends({
31
67
  ref: ref,
32
68
  className: className
33
- }, accessibilityLabel), children);
69
+ }, accessibilityLabel), childrenWithProps);
34
70
  });
35
71
  Switcher.displayName = 'Switcher';
36
72
  Switcher.propTypes = {
@@ -45,7 +81,11 @@ Switcher.propTypes = {
45
81
  /**
46
82
  * Optionally provide a custom class to apply to the underlying `<ul>` node
47
83
  */
48
- className: PropTypes.string
84
+ className: PropTypes.string,
85
+ /**
86
+ * Specify whether the panel is expanded
87
+ */
88
+ expanded: PropTypes.bool
49
89
  };
50
90
  var Switcher$1 = Switcher;
51
91
 
@@ -12,18 +12,24 @@ import PropTypes from 'prop-types';
12
12
  import { AriaLabelPropType } from '../../prop-types/AriaPropTypes.js';
13
13
  import Link from './Link.js';
14
14
  import { usePrefix } from '../../internal/usePrefix.js';
15
+ import { match } from '../../internal/keyboard/match.js';
16
+ import { ArrowDown, ArrowUp } from '../../internal/keyboard/keys.js';
15
17
 
16
- const SwitcherItem = /*#__PURE__*/React__default.forwardRef(function SwitcherItem(props, ref) {
17
- const prefix = usePrefix();
18
- const {
18
+ const SwitcherItem = /*#__PURE__*/React__default.forwardRef(function SwitcherItem(_ref, ref) {
19
+ let {
19
20
  'aria-label': ariaLabel,
20
21
  'aria-labelledby': ariaLabelledBy,
21
22
  className: customClassName,
22
23
  children,
23
24
  isSelected,
24
- tabIndex = 0,
25
+ expanded,
26
+ tabIndex = expanded ? 0 : -1,
27
+ index,
28
+ handleSwitcherItemFocus,
29
+ onKeyDown = () => {},
25
30
  ...rest
26
- } = props;
31
+ } = _ref;
32
+ const prefix = usePrefix();
27
33
  const className = cx(`${prefix}--switcher__item`, {
28
34
  [customClassName]: !!customClassName
29
35
  });
@@ -34,9 +40,30 @@ const SwitcherItem = /*#__PURE__*/React__default.forwardRef(function SwitcherIte
34
40
  const linkClassName = cx(`${prefix}--switcher__item-link`, {
35
41
  [`${prefix}--switcher__item-link--selected`]: isSelected
36
42
  });
43
+ function setTabFocus(evt) {
44
+ if (match(evt, ArrowDown)) {
45
+ evt.preventDefault();
46
+ handleSwitcherItemFocus?.({
47
+ currentIndex: index,
48
+ direction: 1
49
+ });
50
+ }
51
+ if (match(evt, ArrowUp)) {
52
+ evt.preventDefault();
53
+ handleSwitcherItemFocus?.({
54
+ currentIndex: index,
55
+ direction: -1
56
+ });
57
+ }
58
+ }
37
59
  return /*#__PURE__*/React__default.createElement("li", {
38
60
  className: className
39
- }, /*#__PURE__*/React__default.createElement(Link, _extends({}, rest, {
61
+ }, /*#__PURE__*/React__default.createElement(Link, _extends({
62
+ onKeyDown: evt => {
63
+ setTabFocus(evt);
64
+ onKeyDown(evt);
65
+ }
66
+ }, rest, {
40
67
  ref: ref,
41
68
  className: linkClassName,
42
69
  tabIndex: tabIndex
@@ -56,6 +83,18 @@ SwitcherItem.propTypes = {
56
83
  * Optionally provide a custom class to apply to the underlying `<li>` node
57
84
  */
58
85
  className: PropTypes.string,
86
+ /**
87
+ * event handlers
88
+ */
89
+ handleSwitcherItemFocus: PropTypes.func,
90
+ /**
91
+ * Specify the index of the SwitcherItem
92
+ */
93
+ index: PropTypes.number,
94
+ /**
95
+ * event handlers
96
+ */
97
+ onKeyDown: PropTypes.func,
59
98
  /**
60
99
  * Specify the tab index of the Link
61
100
  */
package/es/index.js CHANGED
@@ -59,6 +59,7 @@ export { default as TextAreaSkeleton } from './components/TextArea/TextArea.Skel
59
59
  import './components/TextInput/index.js';
60
60
  export { ClickableTile, ExpandableTile, SelectableTile, Tile, TileAboveTheFoldContent, TileBelowTheFoldContent } from './components/Tile/Tile.js';
61
61
  export { default as TileGroup } from './components/TileGroup/index.js';
62
+ export { Toggle } from './components/Toggle/Toggle.js';
62
63
  export { default as ToggleSkeleton } from './components/Toggle/Toggle.Skeleton.js';
63
64
  export { default as ToggleSmallSkeleton } from './components/ToggleSmall/ToggleSmall.Skeleton.js';
64
65
  export { Toggletip, ToggletipActions, ToggletipButton, ToggletipContent, ToggletipLabel } from './components/Toggletip/index.js';
@@ -110,7 +111,6 @@ export { default as NumberInputSkeleton } from './components/NumberInput/NumberI
110
111
  export { default as ProgressIndicatorSkeleton } from './components/ProgressIndicator/ProgressIndicator.Skeleton.js';
111
112
  export { default as TextInputSkeleton } from './components/TextInput/TextInput.Skeleton.js';
112
113
  export { default as TextInput } from './components/TextInput/TextInput.js';
113
- export { Toggle } from './components/Toggle/Toggle.js';
114
114
  export { default as TreeNode } from './components/TreeView/TreeNode.js';
115
115
  export { default as TreeView } from './components/TreeView/TreeView.js';
116
116
  export { default as HeaderContainer } from './components/UIShell/HeaderContainer.js';
@@ -142,6 +142,7 @@ class FloatingMenu extends React__default.Component {
142
142
  var _this;
143
143
  super(...arguments);
144
144
  _this = this;
145
+ // `true` if the menu body is mounted and calculation of the position is in progress.
145
146
  _defineProperty(this, "_placeInProgress", false);
146
147
  _defineProperty(this, "state", {
147
148
  /**
@@ -150,10 +151,36 @@ class FloatingMenu extends React__default.Component {
150
151
  */
151
152
  floatingPosition: undefined
152
153
  });
154
+ /**
155
+ * The cached reference to the menu container.
156
+ * Only used if React portal API is not available.
157
+ * @type {Element}
158
+ * @private
159
+ */
153
160
  _defineProperty(this, "_menuContainer", null);
161
+ /**
162
+ * The cached reference to the menu body.
163
+ * The reference is set via callback ref instead of object ref,
164
+ * in order to hook the event when the element ref gets available,
165
+ * which can be at a different timing from `cDM()`, presumably with SSR scenario.
166
+ * @type {Element}
167
+ * @private
168
+ */
154
169
  _defineProperty(this, "_menuBody", null);
170
+ /**
171
+ * Focus sentinel refs for focus trap behavior
172
+ */
155
173
  _defineProperty(this, "startSentinel", /*#__PURE__*/React__default.createRef());
156
174
  _defineProperty(this, "endSentinel", /*#__PURE__*/React__default.createRef());
175
+ /**
176
+ * Calculates the position in the viewport of floating menu,
177
+ * once this component is mounted or updated upon change in the following props:
178
+ *
179
+ * * `menuOffset` (The adjustment that should be applied to the calculated floating menu's position)
180
+ * * `menuDirection` (Where the floating menu menu should be placed relative to the trigger button)
181
+ *
182
+ * @private
183
+ */
157
184
  _defineProperty(this, "_updateMenuSize", function () {
158
185
  let prevProps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
159
186
  let isAdjustment = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@@ -227,6 +254,11 @@ class FloatingMenu extends React__default.Component {
227
254
  }
228
255
  }
229
256
  });
257
+ /**
258
+ * Set focus on floating menu content after menu placement.
259
+ * @param {Element} menuBody The DOM element of the menu body.
260
+ * @private
261
+ */
230
262
  _defineProperty(this, "_focusMenuContent", menuBody => {
231
263
  const primaryFocusNode = menuBody.querySelector(this.props.selectorPrimaryFocus || null);
232
264
  const tabbableNode = menuBody.querySelector(selectorTabbable);
@@ -243,6 +275,10 @@ class FloatingMenu extends React__default.Component {
243
275
  process.env.NODE_ENV !== "production" ? warning(focusableNode === null, 'Floating Menus must have at least a programmatically focusable child. ' + 'This can be accomplished by adding tabIndex="-1" to the content element.') : void 0;
244
276
  }
245
277
  });
278
+ /**
279
+ * A callback for called when menu body is mounted or unmounted.
280
+ * @param {Element} menuBody The menu body being mounted. `null` if the menu body is being unmounted.
281
+ */
246
282
  _defineProperty(this, "_menuRef", menuBody => {
247
283
  const {
248
284
  menuRef
@@ -253,6 +289,10 @@ class FloatingMenu extends React__default.Component {
253
289
  this._updateMenuSize();
254
290
  }
255
291
  });
292
+ /**
293
+ * @returns The child nodes, with styles containing the floating menu position.
294
+ * @private
295
+ */
256
296
  _defineProperty(this, "_getChildrenWithProps", () => {
257
297
  const {
258
298
  styles,
@@ -281,6 +321,12 @@ class FloatingMenu extends React__default.Component {
281
321
  }
282
322
  });
283
323
  });
324
+ /**
325
+ * Blur handler for when focus wrap behavior is enabled
326
+ * @param {Event} event
327
+ * @param {Element} event.target previously focused node
328
+ * @param {Element} event.relatedTarget current focused node
329
+ */
284
330
  _defineProperty(this, "handleBlur", _ref2 => {
285
331
  let {
286
332
  target: oldActiveNode,
@@ -302,33 +348,7 @@ class FloatingMenu extends React__default.Component {
302
348
  });
303
349
  }
304
350
  });
305
- } // `true` if the menu body is mounted and calculation of the position is in progress.
306
- /**
307
- * The cached reference to the menu container.
308
- * Only used if React portal API is not available.
309
- * @type {Element}
310
- * @private
311
- */
312
- /**
313
- * The cached reference to the menu body.
314
- * The reference is set via callback ref instead of object ref,
315
- * in order to hook the event when the element ref gets available,
316
- * which can be at a different timing from `cDM()`, presumably with SSR scenario.
317
- * @type {Element}
318
- * @private
319
- */
320
- /**
321
- * Focus sentinel refs for focus trap behavior
322
- */
323
- /**
324
- * Calculates the position in the viewport of floating menu,
325
- * once this component is mounted or updated upon change in the following props:
326
- *
327
- * * `menuOffset` (The adjustment that should be applied to the calculated floating menu's position)
328
- * * `menuDirection` (Where the floating menu menu should be placed relative to the trigger button)
329
- *
330
- * @private
331
- */
351
+ }
332
352
  componentWillUnmount() {
333
353
  this.hResize.release();
334
354
  }
@@ -337,12 +357,6 @@ class FloatingMenu extends React__default.Component {
337
357
  this._updateMenuSize();
338
358
  });
339
359
  }
340
- /**
341
- * Set focus on floating menu content after menu placement.
342
- * @param {Element} menuBody The DOM element of the menu body.
343
- * @private
344
- */
345
-
346
360
  componentDidUpdate(prevProps) {
347
361
  this._updateMenuSize(prevProps);
348
362
  const {
@@ -358,24 +372,6 @@ class FloatingMenu extends React__default.Component {
358
372
  }
359
373
  }
360
374
  }
361
-
362
- /**
363
- * A callback for called when menu body is mounted or unmounted.
364
- * @param {Element} menuBody The menu body being mounted. `null` if the menu body is being unmounted.
365
- */
366
-
367
- /**
368
- * @returns The child nodes, with styles containing the floating menu position.
369
- * @private
370
- */
371
-
372
- /**
373
- * Blur handler for when focus wrap behavior is enabled
374
- * @param {Event} event
375
- * @param {Element} event.target previously focused node
376
- * @param {Element} event.relatedTarget current focused node
377
- */
378
-
379
375
  render() {
380
376
  const {
381
377
  context: prefix
@@ -22,7 +22,7 @@ import { warning } from './warning.js';
22
22
  * @param {string} [config.name] - the name of the custom component
23
23
  * @param {any} config.defaultValue - the default value used for the state. This will be
24
24
  * the fallback value used if `value` is not defined.
25
- * @param {Function} config.onChange - an optional function that is called when
25
+ * @param {Function|undefined} config.onChange - an optional function that is called when
26
26
  * the value of the state changes. This is useful for communicating to parents of
27
27
  * controlled components that the value is requesting to be changed.
28
28
  * @param {any} config.value - a controlled value. Omitting this means that the state is
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import { useLayoutEffect, useEffect, useState } from 'react';
8
+ import { useLayoutEffect, useEffect, useState, useId as useId$1 } from 'react';
9
9
  import setupGetInstanceId from '../tools/setupGetInstanceId.js';
10
10
  import { canUseDOM } from './environment.js';
11
11
  import { useIdPrefix } from './useIdPrefix.js';
@@ -39,6 +39,15 @@ function useId() {
39
39
  serverHandoffCompleted = true;
40
40
  }
41
41
  }, []);
42
+ if (useId$1) {
43
+ const id = nativeReactUseId(_prefix, prefix);
44
+ return id;
45
+ }
46
+ return id;
47
+ }
48
+ function nativeReactUseId(_prefix, prefix) {
49
+ const getId = useId$1();
50
+ const id = `${_prefix ? `${_prefix}-` : ``}${prefix}-${getId}`;
42
51
  return id;
43
52
  }
44
53
 
@@ -0,0 +1,44 @@
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
+
8
+ import { useState, useEffect } from 'react';
9
+ import { canUseDOM } from './environment.js';
10
+
11
+ function useMatchMedia(mediaQueryString) {
12
+ const [matches, setMatches] = useState(() => {
13
+ if (canUseDOM) {
14
+ const mediaQueryList = window.matchMedia(mediaQueryString);
15
+ return mediaQueryList.matches;
16
+ }
17
+ return false;
18
+ });
19
+ useEffect(() => {
20
+ function listener(event) {
21
+ setMatches(event.matches);
22
+ }
23
+ const mediaQueryList = window.matchMedia(mediaQueryString);
24
+ // Support fallback to `addListener` for broader browser support
25
+ if (mediaQueryList.addEventListener) {
26
+ mediaQueryList.addEventListener('change', listener);
27
+ } else {
28
+ mediaQueryList.addListener(listener);
29
+ }
30
+
31
+ // Make sure the media query list is in sync with the matches state
32
+ setMatches(mediaQueryList.matches);
33
+ return () => {
34
+ if (mediaQueryList.addEventListener) {
35
+ mediaQueryList.removeEventListener('change', listener);
36
+ } else {
37
+ mediaQueryList.removeListener(listener);
38
+ }
39
+ };
40
+ }, [mediaQueryString]);
41
+ return matches;
42
+ }
43
+
44
+ export { useMatchMedia };
@@ -37,6 +37,14 @@ var Downshift__default = /*#__PURE__*/_interopDefaultLegacy(Downshift);
37
37
  var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
38
38
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
39
39
 
40
+ const {
41
+ keyDownArrowDown,
42
+ keyDownArrowUp,
43
+ keyDownEscape,
44
+ clickButton,
45
+ blurButton,
46
+ changeInput
47
+ } = Downshift__default["default"].stateChangeTypes;
40
48
  const defaultItemToString = item => {
41
49
  if (typeof item === 'string') {
42
50
  return item;
@@ -126,6 +134,7 @@ const ComboBox = /*#__PURE__*/React__default["default"].forwardRef((props, ref)
126
134
  const [isFocused, setIsFocused] = React.useState(false);
127
135
  const [prevSelectedItem, setPrevSelectedItem] = React.useState();
128
136
  const [doneInitialSelectedItem, setDoneInitialSelectedItem] = React.useState(false);
137
+ const [highlightedIndex, setHighlightedIndex] = React.useState();
129
138
  const savedOnInputChange = React.useRef(onInputChange);
130
139
  if (!doneInitialSelectedItem || prevSelectedItem !== selectedItem) {
131
140
  setDoneInitialSelectedItem(true);
@@ -165,19 +174,43 @@ const ComboBox = /*#__PURE__*/React__default["default"].forwardRef((props, ref)
165
174
  textInput.current.focus();
166
175
  }
167
176
  };
168
- const handleOnStateChange = (newState, _ref3) => {
169
- let {
170
- setHighlightedIndex
171
- } = _ref3;
172
- if (Object.prototype.hasOwnProperty.call(newState, 'inputValue')) {
177
+ const getHighlightedIndex = changes => {
178
+ if (Object.prototype.hasOwnProperty.call(changes, 'inputValue')) {
173
179
  const {
174
180
  inputValue
175
- } = newState;
181
+ } = changes;
176
182
  const filteredItems = filterItems(items, itemToString, inputValue);
177
- setHighlightedIndex(findHighlightedIndex({
183
+ const indexToHighlight = findHighlightedIndex({
178
184
  ...props,
179
185
  items: filteredItems
180
- }, inputValue));
186
+ }, inputValue);
187
+ setHighlightedIndex(indexToHighlight);
188
+ return indexToHighlight;
189
+ }
190
+ return highlightedIndex;
191
+ };
192
+ const handleOnStateChange = (changes, _ref3) => {
193
+ let {
194
+ setHighlightedIndex: updateHighlightedIndex
195
+ } = _ref3;
196
+ const {
197
+ type
198
+ } = changes;
199
+ switch (type) {
200
+ case keyDownArrowDown:
201
+ case keyDownArrowUp:
202
+ setHighlightedIndex(changes.highlightedIndex);
203
+ break;
204
+ case blurButton:
205
+ case keyDownEscape:
206
+ setHighlightedIndex(changes.highlightedIndex);
207
+ break;
208
+ case clickButton:
209
+ setHighlightedIndex(changes.highlightedIndex);
210
+ break;
211
+ case changeInput:
212
+ updateHighlightedIndex(getHighlightedIndex(changes));
213
+ break;
181
214
  }
182
215
  };
183
216
  const handleToggleClick = isOpen => event => {
@@ -239,7 +272,6 @@ const ComboBox = /*#__PURE__*/React__default["default"].forwardRef((props, ref)
239
272
  isOpen,
240
273
  inputValue,
241
274
  selectedItem,
242
- highlightedIndex,
243
275
  clearSelection,
244
276
  toggleMenu
245
277
  } = _ref4;
@@ -337,6 +369,7 @@ const ComboBox = /*#__PURE__*/React__default["default"].forwardRef((props, ref)
337
369
  "aria-expanded": rootProps['aria-expanded'],
338
370
  "aria-haspopup": "listbox",
339
371
  "aria-controls": inputProps['aria-controls'],
372
+ "aria-owns": getMenuProps().id,
340
373
  title: textInput?.current?.value
341
374
  }, inputProps, rest, readOnlyEventHandlers, {
342
375
  readOnly: readOnly,
@@ -368,7 +401,7 @@ const ComboBox = /*#__PURE__*/React__default["default"].forwardRef((props, ref)
368
401
  return /*#__PURE__*/React__default["default"].createElement(index["default"].MenuItem, _rollupPluginBabelHelpers["extends"]({
369
402
  key: itemProps.id,
370
403
  isActive: selectedItem === item,
371
- isHighlighted: highlightedIndex === index$1 || selectedItem?.id && selectedItem?.id === item.id || false,
404
+ isHighlighted: highlightedIndex === index$1,
372
405
  title: itemToElement ? item.text : itemToString ? itemToString(item) : undefined
373
406
  }, itemProps), itemToElement ?
374
407
  /*#__PURE__*/
@@ -30,6 +30,11 @@ var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
30
30
  class ContentSwitcher extends React__default["default"].Component {
31
31
  constructor() {
32
32
  super(...arguments);
33
+ /**
34
+ * The DOM references of child `<Switch>`.
35
+ * @type {Array<Element>}
36
+ * @private
37
+ */
33
38
  _rollupPluginBabelHelpers.defineProperty(this, "_switchRefs", []);
34
39
  _rollupPluginBabelHelpers.defineProperty(this, "state", {
35
40
  selectedIndex: undefined
@@ -87,11 +92,6 @@ class ContentSwitcher extends React__default["default"].Component {
87
92
  }
88
93
  });
89
94
  }
90
- /**
91
- * The DOM references of child `<Switch>`.
92
- * @type {Array<Element>}
93
- * @private
94
- */
95
95
  static getDerivedStateFromProps(_ref, state) {
96
96
  let {
97
97
  selectedIndex