@carbon/react 1.22.0 → 1.23.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 (85) hide show
  1. package/es/components/CodeSnippet/CodeSnippet.js +2 -2
  2. package/es/components/ComboBox/ComboBox.d.ts +151 -0
  3. package/es/components/ComboBox/ComboBox.js +28 -21
  4. package/es/components/ComposedModal/ComposedModal.js +2 -2
  5. package/es/components/DataTable/TableSelectRow.d.ts +88 -0
  6. package/es/components/DataTable/TableSelectRow.js +3 -5
  7. package/es/components/DataTable/tools/sorting.js +3 -0
  8. package/es/components/DatePicker/DatePicker.js +1 -1
  9. package/es/components/DatePicker/plugins/fixEventsPlugin.js +10 -1
  10. package/es/components/DatePicker/plugins/rangePlugin.js +1 -1
  11. package/es/components/FileUploader/FileUploaderButton.js +14 -16
  12. package/es/components/Grid/CSSGrid.d.ts +9 -0
  13. package/es/components/Grid/CSSGrid.js +8 -5
  14. package/es/components/Grid/Column.d.ts +73 -0
  15. package/es/components/Grid/Column.js +40 -34
  16. package/es/components/Grid/ColumnHang.d.ts +24 -0
  17. package/es/components/Grid/ColumnHang.js +7 -4
  18. package/es/components/Grid/FlexGrid.d.ts +9 -0
  19. package/es/components/Grid/FlexGrid.js +6 -3
  20. package/es/components/Grid/Grid.d.ts +9 -0
  21. package/es/components/Grid/Grid.js +6 -5
  22. package/es/components/Grid/GridContext.d.ts +38 -0
  23. package/es/components/Grid/GridContext.js +6 -6
  24. package/es/components/Grid/GridTypes.d.ts +37 -0
  25. package/es/components/Grid/Row.d.ts +34 -0
  26. package/es/components/Grid/Row.js +4 -2
  27. package/es/components/Grid/index.d.ts +11 -0
  28. package/es/components/NumberInput/NumberInput.d.ts +132 -0
  29. package/es/components/NumberInput/NumberInput.js +9 -7
  30. package/es/components/TextArea/TextArea.js +1 -0
  31. package/es/components/Toggle/Toggle.js +54 -33
  32. package/es/components/Toggletip/index.js +26 -1
  33. package/es/index.js +5 -5
  34. package/es/internal/useNormalizedInputProps.js +3 -3
  35. package/lib/components/CodeSnippet/CodeSnippet.js +4 -3
  36. package/lib/components/ComboBox/ComboBox.d.ts +151 -0
  37. package/lib/components/ComboBox/ComboBox.js +28 -21
  38. package/lib/components/ComposedModal/ComposedModal.js +2 -2
  39. package/lib/components/DataTable/TableSelectRow.d.ts +88 -0
  40. package/lib/components/DataTable/TableSelectRow.js +2 -4
  41. package/lib/components/DataTable/tools/sorting.js +3 -0
  42. package/lib/components/DatePicker/DatePicker.js +9 -8
  43. package/lib/components/DatePicker/plugins/fixEventsPlugin.js +10 -1
  44. package/lib/components/DatePicker/plugins/rangePlugin.js +6 -2
  45. package/lib/components/FileUploader/FileUploaderButton.js +14 -16
  46. package/lib/components/Grid/CSSGrid.d.ts +9 -0
  47. package/lib/components/Grid/CSSGrid.js +8 -5
  48. package/lib/components/Grid/Column.d.ts +73 -0
  49. package/lib/components/Grid/Column.js +36 -30
  50. package/lib/components/Grid/ColumnHang.d.ts +24 -0
  51. package/lib/components/Grid/ColumnHang.js +7 -4
  52. package/lib/components/Grid/FlexGrid.d.ts +9 -0
  53. package/lib/components/Grid/FlexGrid.js +6 -3
  54. package/lib/components/Grid/Grid.d.ts +9 -0
  55. package/lib/components/Grid/Grid.js +2 -1
  56. package/lib/components/Grid/GridContext.d.ts +38 -0
  57. package/lib/components/Grid/GridContext.js +6 -6
  58. package/lib/components/Grid/GridTypes.d.ts +37 -0
  59. package/lib/components/Grid/Row.d.ts +34 -0
  60. package/lib/components/Grid/Row.js +4 -2
  61. package/lib/components/Grid/index.d.ts +11 -0
  62. package/lib/components/NumberInput/NumberInput.d.ts +132 -0
  63. package/lib/components/NumberInput/NumberInput.js +9 -7
  64. package/lib/components/TextArea/TextArea.js +1 -0
  65. package/lib/components/Toggle/Toggle.js +53 -32
  66. package/lib/components/Toggletip/index.js +26 -1
  67. package/lib/index.js +10 -10
  68. package/lib/internal/useNormalizedInputProps.js +3 -3
  69. package/package.json +3 -5
  70. package/es/_virtual/ResizeObserver.es.js +0 -13
  71. package/es/_virtual/_commonjsHelpers.js +0 -42
  72. package/es/_virtual/index.js +0 -14
  73. package/es/_virtual/rangePlugin.js +0 -14
  74. package/es/node_modules/flatpickr/dist/l10n/index.js +0 -1423
  75. package/es/node_modules/flatpickr/dist/plugins/rangePlugin.js +0 -196
  76. package/es/node_modules/resize-observer-polyfill/dist/ResizeObserver.es.js +0 -1112
  77. package/es/node_modules/use-resize-observer/polyfilled.js +0 -111
  78. package/lib/_virtual/ResizeObserver.es.js +0 -17
  79. package/lib/_virtual/_commonjsHelpers.js +0 -48
  80. package/lib/_virtual/index.js +0 -18
  81. package/lib/_virtual/rangePlugin.js +0 -18
  82. package/lib/node_modules/flatpickr/dist/l10n/index.js +0 -1427
  83. package/lib/node_modules/flatpickr/dist/plugins/rangePlugin.js +0 -200
  84. package/lib/node_modules/resize-observer-polyfill/dist/ResizeObserver.es.js +0 -1116
  85. package/lib/node_modules/use-resize-observer/polyfilled.js +0 -119
@@ -127,11 +127,12 @@ var NumberInput = /*#__PURE__*/React__default.forwardRef(function NumberInput(pr
127
127
  var iconClasses = cx((_cx3 = {}, _defineProperty(_cx3, "".concat(prefix, "--number__invalid"), normalizedProps.invalid || normalizedProps.warn), _defineProperty(_cx3, "".concat(prefix, "--number__invalid--warning"), normalizedProps.warn), _cx3));
128
128
 
129
129
  if (controlledValue !== prevControlledValue) {
130
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
130
131
  setValue(controlledValue);
131
132
  setPrevControlledValue(controlledValue);
132
133
  }
133
134
 
134
- var ariaDescribedBy = null;
135
+ var ariaDescribedBy = undefined;
135
136
 
136
137
  if (normalizedProps.invalid) {
137
138
  ariaDescribedBy = normalizedProps.invalidId;
@@ -158,7 +159,7 @@ var NumberInput = /*#__PURE__*/React__default.forwardRef(function NumberInput(pr
158
159
  }
159
160
 
160
161
  var handleFocus = function handleFocus(evt) {
161
- if (evt.target.type === 'button') {
162
+ if ('type' in evt.target && evt.target.type === 'button') {
162
163
  setIsFocused(false);
163
164
  } else {
164
165
  setIsFocused(evt.type === 'focus' ? true : false);
@@ -166,10 +167,11 @@ var NumberInput = /*#__PURE__*/React__default.forwardRef(function NumberInput(pr
166
167
  };
167
168
 
168
169
  var outerElementClasses = cx("".concat(prefix, "--form-item"), (_cx4 = {}, _defineProperty(_cx4, customClassName, !!customClassName), _defineProperty(_cx4, "".concat(prefix, "--number-input--fluid--invalid"), isFluid && normalizedProps.invalid), _defineProperty(_cx4, "".concat(prefix, "--number-input--fluid--focus"), isFluid && isFocused), _defineProperty(_cx4, "".concat(prefix, "--number-input--fluid--disabled"), isFluid && disabled), _cx4));
170
+ var Icon = normalizedProps.icon;
169
171
  return /*#__PURE__*/React__default.createElement("div", {
170
172
  className: outerElementClasses,
171
- onFocus: isFluid ? handleFocus : null,
172
- onBlur: isFluid ? handleFocus : null
173
+ onFocus: isFluid ? handleFocus : undefined,
174
+ onBlur: isFluid ? handleFocus : undefined
173
175
  }, /*#__PURE__*/React__default.createElement("div", {
174
176
  className: numberInputClasses,
175
177
  "data-invalid": normalizedProps.invalid ? true : undefined
@@ -215,7 +217,7 @@ var NumberInput = /*#__PURE__*/React__default.forwardRef(function NumberInput(pr
215
217
  step: step,
216
218
  type: "number",
217
219
  value: value
218
- })), normalizedProps.icon ? /*#__PURE__*/React__default.createElement(normalizedProps.icon, {
220
+ })), Icon ? /*#__PURE__*/React__default.createElement(Icon, {
219
221
  className: iconClasses
220
222
  }) : null, !hideSteppers && /*#__PURE__*/React__default.createElement("div", {
221
223
  className: "".concat(prefix, "--number__controls")
@@ -238,7 +240,7 @@ var NumberInput = /*#__PURE__*/React__default.forwardRef(function NumberInput(pr
238
240
  _onClick(event, state);
239
241
  }
240
242
  },
241
- tabIndex: "-1",
243
+ tabIndex: -1,
242
244
  title: decrementNumLabel || iconDescription,
243
245
  type: "button"
244
246
  }, _Subtract || (_Subtract = /*#__PURE__*/React__default.createElement(Subtract, {
@@ -264,7 +266,7 @@ var NumberInput = /*#__PURE__*/React__default.forwardRef(function NumberInput(pr
264
266
  _onClick(event, state);
265
267
  }
266
268
  },
267
- tabIndex: "-1",
269
+ tabIndex: -1,
268
270
  title: incrementNumLabel || iconDescription,
269
271
  type: "button"
270
272
  }, _Add || (_Add = /*#__PURE__*/React__default.createElement(Add, {
@@ -104,6 +104,7 @@ var TextArea = /*#__PURE__*/React__default.forwardRef(function TextArea(_ref, fo
104
104
  useIsomorphicEffect(function () {
105
105
  if (other.cols) {
106
106
  textareaRef.current.style.width = null;
107
+ textareaRef.current.style.resize = 'none';
107
108
  } else {
108
109
  textareaRef.current.style.width = "100%";
109
110
  }
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import { objectWithoutProperties as _objectWithoutProperties, slicedToArray as _slicedToArray, defineProperty as _defineProperty, extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
- import React__default from 'react';
9
+ import React__default, { useRef } from 'react';
10
10
  import PropTypes from 'prop-types';
11
11
  import cx from 'classnames';
12
12
  import { useControllableState } from '../../internal/useControllableState.js';
@@ -41,6 +41,7 @@ function Toggle(_ref) {
41
41
  other = _objectWithoutProperties(_ref, _excluded);
42
42
 
43
43
  var prefix = usePrefix();
44
+ var buttonElement = useRef(null);
44
45
 
45
46
  var _useControllableState = useControllableState({
46
47
  value: toggled,
@@ -69,37 +70,53 @@ function Toggle(_ref) {
69
70
  var labelTextClasses = cx("".concat(prefix, "--toggle__label-text"), _defineProperty({}, "".concat(prefix, "--visually-hidden"), hideLabel));
70
71
  var appearanceClasses = cx("".concat(prefix, "--toggle__appearance"), _defineProperty({}, "".concat(prefix, "--toggle__appearance--sm"), isSm));
71
72
  var switchClasses = cx("".concat(prefix, "--toggle__switch"), _defineProperty({}, "".concat(prefix, "--toggle__switch--checked"), checked));
72
- return /*#__PURE__*/React__default.createElement("div", {
73
- className: wrapperClasses
74
- }, /*#__PURE__*/React__default.createElement("button", _extends({}, other, {
75
- id: id,
76
- className: "".concat(prefix, "--toggle__button"),
77
- role: "switch",
78
- type: "button",
79
- "aria-checked": checked,
80
- "aria-labelledby": ariaLabelledby,
81
- disabled: disabled,
82
- onClick: handleClick
83
- })), /*#__PURE__*/React__default.createElement(LabelComponent, {
84
- htmlFor: ariaLabelledby ? null : id,
85
- className: "".concat(prefix, "--toggle__label")
86
- }, labelText && /*#__PURE__*/React__default.createElement("span", {
87
- className: labelTextClasses
88
- }, labelText), /*#__PURE__*/React__default.createElement("div", {
89
- className: appearanceClasses
90
- }, /*#__PURE__*/React__default.createElement("div", {
91
- className: switchClasses
92
- }, isSm && /*#__PURE__*/React__default.createElement("svg", {
93
- className: "".concat(prefix, "--toggle__check"),
94
- width: "6px",
95
- height: "5px",
96
- viewBox: "0 0 6 5"
97
- }, _path || (_path = /*#__PURE__*/React__default.createElement("path", {
98
- d: "M2.2 2.7L5 0 6 1 2.2 5 0 2.7 1 1.5z"
99
- })))), renderSideLabel && /*#__PURE__*/React__default.createElement("span", {
100
- className: "".concat(prefix, "--toggle__text"),
101
- "aria-hidden": "true"
102
- }, sideLabel))));
73
+ return (
74
+ /*#__PURE__*/
75
+ // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
76
+ React__default.createElement("div", {
77
+ className: wrapperClasses,
78
+ onClick: ariaLabelledby ? function (e) {
79
+ // the underlying <button> can only be activated by keyboard as it is visually hidden;
80
+ // therefore, if this event's target is the <button>, it had to be triggered by
81
+ // the keyboard event which already calls handleClick. if we wouldn't catch this, the
82
+ // onClick and onToggle functions would be called twice whenever the user activates the
83
+ // toggle by keyboard and props['aria-labelledby'] is passed.
84
+ if (buttonElement.current && e.target !== buttonElement.current) {
85
+ handleClick(e);
86
+ buttonElement.current.focus();
87
+ }
88
+ } : null
89
+ }, /*#__PURE__*/React__default.createElement("button", _extends({}, other, {
90
+ ref: buttonElement,
91
+ id: id,
92
+ className: "".concat(prefix, "--toggle__button"),
93
+ role: "switch",
94
+ type: "button",
95
+ "aria-checked": checked,
96
+ "aria-labelledby": ariaLabelledby,
97
+ disabled: disabled,
98
+ onClick: handleClick
99
+ })), /*#__PURE__*/React__default.createElement(LabelComponent, {
100
+ htmlFor: ariaLabelledby ? null : id,
101
+ className: "".concat(prefix, "--toggle__label")
102
+ }, labelText && /*#__PURE__*/React__default.createElement("span", {
103
+ className: labelTextClasses
104
+ }, labelText), /*#__PURE__*/React__default.createElement("div", {
105
+ className: appearanceClasses
106
+ }, /*#__PURE__*/React__default.createElement("div", {
107
+ className: switchClasses
108
+ }, isSm && /*#__PURE__*/React__default.createElement("svg", {
109
+ className: "".concat(prefix, "--toggle__check"),
110
+ width: "6px",
111
+ height: "5px",
112
+ viewBox: "0 0 6 5"
113
+ }, _path || (_path = /*#__PURE__*/React__default.createElement("path", {
114
+ d: "M2.2 2.7L5 0 6 1 2.2 5 0 2.7 1 1.5z"
115
+ })))), renderSideLabel && /*#__PURE__*/React__default.createElement("span", {
116
+ className: "".concat(prefix, "--toggle__text"),
117
+ "aria-hidden": "true"
118
+ }, sideLabel))))
119
+ );
103
120
  }
104
121
  Toggle.propTypes = {
105
122
  /**
@@ -123,7 +140,11 @@ Toggle.propTypes = {
123
140
  disabled: PropTypes.bool,
124
141
 
125
142
  /**
126
- * Specify whether the label should be hidden, or not
143
+ * If true, the side labels (props.labelA and props.labelB) will be replaced by
144
+ * props.labelText, so that the toggle doesn't render a top label. In order to fully
145
+ * hide any labels, you can use props['aria-labelledby'] to refer to another element
146
+ * that labels the toggle. props.labelText would no longer be required in that case
147
+ * and can therefore be omitted.
127
148
  */
128
149
  hideLabel: PropTypes.bool,
129
150
 
@@ -102,10 +102,34 @@ function Toggletip(_ref2) {
102
102
 
103
103
  function onKeyDown(event) {
104
104
  if (open && match(event, Escape)) {
105
- actions.close();
105
+ actions.close(); // If the menu is closed while focus is still inside the menu, it should return to the trigger button (#12922)
106
+
107
+ var button = ref.current.children[0];
108
+
109
+ if (button && button.type === 'button') {
110
+ button.focus();
111
+ }
106
112
  }
107
113
  }
108
114
 
115
+ function handleBlur(event) {
116
+ // Do not close if the menu itself is clicked, should only close on focus out
117
+ if (open && event.relatedTarget === null) {
118
+ return;
119
+ }
120
+
121
+ if (!event.currentTarget.contains(event.relatedTarget)) {
122
+ // The menu should be closed when focus leaves the `Toggletip` (#12922)
123
+ actions.close();
124
+ }
125
+ } // If the `Toggletip` is the last focusable item in the tab order, it shoudl also close when the browser window loses focus (#12922)
126
+
127
+
128
+ useWindowEvent('blur', function () {
129
+ if (open) {
130
+ actions.close();
131
+ }
132
+ });
109
133
  useWindowEvent('click', function (event) {
110
134
  if (open && !ref.current.contains(event.target)) {
111
135
  actions.close();
@@ -122,6 +146,7 @@ function Toggletip(_ref2) {
122
146
  highContrast: true,
123
147
  open: open,
124
148
  onKeyDown: onKeyDown,
149
+ onBlur: handleBlur,
125
150
  ref: ref
126
151
  }, children));
127
152
  }
package/es/index.js CHANGED
@@ -14,6 +14,11 @@ export { default as Dropdown } from './components/Dropdown/Dropdown.js';
14
14
  export { default as DropdownSkeleton } from './components/Dropdown/Dropdown.Skeleton.js';
15
15
  export { default as FluidForm } from './components/FluidForm/FluidForm.js';
16
16
  export { FormContext } from './components/FluidForm/FormContext.js';
17
+ export { FlexGrid } from './components/Grid/FlexGrid.js';
18
+ export { Grid } from './components/Grid/Grid.js';
19
+ export { default as Row } from './components/Grid/Row.js';
20
+ export { default as Column } from './components/Grid/Column.js';
21
+ export { ColumnHang } from './components/Grid/ColumnHang.js';
17
22
  export { IdPrefix } from './components/IdPrefix/index.js';
18
23
  export { default as OverflowMenu } from './components/OverflowMenu/index.js';
19
24
  export { default as Slider } from './components/Slider/index.js';
@@ -70,8 +75,6 @@ export { default as FileUploaderDropContainer } from './components/FileUploader/
70
75
  export { default as FileUploaderItem } from './components/FileUploader/FileUploaderItem.js';
71
76
  export { default as FormItem } from './components/FormItem/FormItem.js';
72
77
  export { default as FormLabel } from './components/FormLabel/FormLabel.js';
73
- export { default as Row } from './components/Grid/Row.js';
74
- export { default as Column } from './components/Grid/Column.js';
75
78
  export { default as InlineLoading } from './components/InlineLoading/InlineLoading.js';
76
79
  export { default as Loading } from './components/Loading/Loading.js';
77
80
  export { default as NumberInputSkeleton } from './components/NumberInput/NumberInput.Skeleton.js';
@@ -150,9 +153,6 @@ export { default as FileUploader } from './components/FileUploader/FileUploader.
150
153
  export { default as FilterableMultiSelect } from './components/MultiSelect/FilterableMultiSelect.js';
151
154
  export { default as Form } from './components/Form/Form.js';
152
155
  export { default as FormGroup } from './components/FormGroup/FormGroup.js';
153
- export { FlexGrid } from './components/Grid/FlexGrid.js';
154
- export { Grid } from './components/Grid/Grid.js';
155
- export { ColumnHang } from './components/Grid/ColumnHang.js';
156
156
  export { default as Link } from './components/Link/Link.js';
157
157
  export { default as ListItem } from './components/ListItem/ListItem.js';
158
158
  export { default as Modal } from './components/Modal/Modal.js';
@@ -12,12 +12,12 @@ import { usePrefix } from './usePrefix.js';
12
12
  /**
13
13
  * @typedef {object} InputProps
14
14
  * @property {string} id - The input's id
15
- * @property {boolean} readOnly - Whether the input should be readonly
15
+ * @property {boolean | undefined} readOnly - Whether the input should be readonly
16
16
  * @property {boolean} disabled - Whether the input should be disabled
17
17
  * @property {boolean} invalid - Whether the input should be marked as invalid
18
- * @property {string} invalidText - The validation message displayed in case the input is considered invalid
18
+ * @property {React.ReactNode | undefined} invalidText - The validation message displayed in case the input is considered invalid
19
19
  * @property {boolean} warn - Whether the input should be in warning state
20
- * @property {string} warnText - The validation message displayed in case the input is in warning state
20
+ * @property {React.ReactNode | undefined} warnText - The validation message displayed in case the input is in warning state
21
21
  */
22
22
 
23
23
  /**
@@ -13,7 +13,7 @@ var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelper
13
13
  var PropTypes = require('prop-types');
14
14
  var React = require('react');
15
15
  var cx = require('classnames');
16
- var polyfilled = require('../../node_modules/use-resize-observer/polyfilled.js');
16
+ var useResizeObserver = require('use-resize-observer/polyfilled');
17
17
  var iconsReact = require('@carbon/icons-react');
18
18
  var Copy = require('../Copy/Copy.js');
19
19
  var Button = require('../Button/Button.js');
@@ -28,6 +28,7 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
28
28
  var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
29
29
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
30
30
  var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
31
+ var useResizeObserver__default = /*#__PURE__*/_interopDefaultLegacy(useResizeObserver);
31
32
  var copy__default = /*#__PURE__*/_interopDefaultLegacy(copy);
32
33
 
33
34
  var _excluded = ["className", "type", "children", "disabled", "feedback", "feedbackTimeout", "onClick", "ariaLabel", "copyText", "copyButtonDescription", "light", "showMoreText", "showLessText", "hideCopyButton", "wrapText", "maxCollapsedNumberOfRows", "maxExpandedNumberOfRows", "minCollapsedNumberOfRows", "minExpandedNumberOfRows"];
@@ -128,7 +129,7 @@ function CodeSnippet(_ref) {
128
129
  setHasLeftOverflow(horizontalOverflow && !!codeScrollLeft);
129
130
  setHasRightOverflow(horizontalOverflow && codeScrollLeft + codeClientWidth !== codeScrollWidth);
130
131
  }, [type, getCodeRefDimensions]);
131
- polyfilled["default"]({
132
+ useResizeObserver__default["default"]({
132
133
  ref: getCodeRef(),
133
134
  onResize: function onResize() {
134
135
  if (codeContentRef !== null && codeContentRef !== void 0 && codeContentRef.current && type === 'multi') {
@@ -150,7 +151,7 @@ function CodeSnippet(_ref) {
150
151
  handleScroll();
151
152
  }
152
153
  }
153
- });
154
+ }, [type, maxCollapsedNumberOfRows, maxExpandedNumberOfRows, minExpandedNumberOfRows, rowHeightInPixels]);
154
155
  React.useEffect(function () {
155
156
  handleScroll();
156
157
  }, [handleScroll]);
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2018
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 Downshift from 'downshift';
8
+ import { ReactNodeLike } from 'prop-types';
9
+ import React from 'react';
10
+ import { ListBoxType, ListBoxSize } from '../ListBox';
11
+ type ExcludedAttributes = 'id' | 'onChange' | 'onClick' | 'type' | 'size';
12
+ export interface ComboBoxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, ExcludedAttributes> {
13
+ /**
14
+ * 'aria-label' of the ListBox component.
15
+ */
16
+ ariaLabel?: string;
17
+ /**
18
+ * An optional className to add to the container node
19
+ */
20
+ className?: string;
21
+ /**
22
+ * Specify the direction of the combobox dropdown. Can be either top or bottom.
23
+ */
24
+ direction?: 'top' | 'bottom';
25
+ /**
26
+ * Specify if the control should be disabled, or not
27
+ */
28
+ disabled?: boolean;
29
+ /**
30
+ * Additional props passed to Downshift
31
+ */
32
+ downshiftProps?: React.ComponentProps<typeof Downshift>;
33
+ /**
34
+ * Provide helper text that is used alongside the control label for
35
+ * additional help
36
+ */
37
+ helperText?: string;
38
+ /**
39
+ * Specify a custom `id` for the input
40
+ */
41
+ id: string;
42
+ /**
43
+ * Allow users to pass in an arbitrary item or a string (in case their items are an array of strings)
44
+ * from their collection that are pre-selected
45
+ */
46
+ initialSelectedItem?: object | string | number;
47
+ /**
48
+ * Specify if the currently selected value is invalid.
49
+ */
50
+ invalid?: boolean;
51
+ /**
52
+ * Message which is displayed if the value is invalid.
53
+ */
54
+ invalidText?: ReactNodeLike;
55
+ /**
56
+ * Optional function to render items as custom components instead of strings.
57
+ * Defaults to null and is overridden by a getter
58
+ */
59
+ itemToElement?: React.ComponentType | null;
60
+ /**
61
+ * Helper function passed to downshift that allows the library to render a
62
+ * given item to a string label. By default, it extracts the `label` field
63
+ * from a given item to serve as the item label in the list
64
+ */
65
+ itemToString?: (item: unknown) => string;
66
+ /**
67
+ * We try to stay as generic as possible here to allow individuals to pass
68
+ * in a collection of whatever kind of data structure they prefer
69
+ */
70
+ items: (object | string | number)[];
71
+ /**
72
+ * @deprecated
73
+ * should use "light theme" (white background)?
74
+ */
75
+ light?: boolean;
76
+ /**
77
+ * `onChange` is a utility for this controlled component to communicate to a
78
+ * consuming component when a specific dropdown item is selected.
79
+ * `({ selectedItem }) => void`
80
+ // * @param {{ selectedItem }}
81
+ */
82
+ onChange: (data: {
83
+ selectedItem: any;
84
+ }) => void;
85
+ /**
86
+ * Callback function to notify consumer when the text input changes.
87
+ * This provides support to change available items based on the text.
88
+ * `(inputText) => void`
89
+ * @param {string} inputText
90
+ */
91
+ onInputChange?: (inputText: string) => void;
92
+ /**
93
+ * Helper function passed to Downshift that allows the user to observe internal
94
+ * state changes
95
+ * `(changes, stateAndHelpers) => void`
96
+ */
97
+ onStateChange?: (changes: object, stateAndHelpers: object) => void;
98
+ /**
99
+ * Callback function that fires when the combobox menu toggle is clicked
100
+ * `(evt) => void`
101
+ * @param {MouseEvent} event
102
+ */
103
+ onToggleClick?: (evt: MouseEvent) => void;
104
+ /**
105
+ * Used to provide a placeholder text node before a user enters any input.
106
+ * This is only present if the control has no items selected
107
+ */
108
+ placeholder?: string;
109
+ /**
110
+ * Is the ComboBox readonly?
111
+ */
112
+ readOnly?: boolean;
113
+ /**
114
+ * For full control of the selection
115
+ */
116
+ selectedItem?: object | string | number;
117
+ /**
118
+ * Specify your own filtering logic by passing in a `shouldFilterItem`
119
+ * function that takes in the current input and an item and passes back
120
+ * whether or not the item should be filtered.
121
+ */
122
+ shouldFilterItem?: (input: any) => boolean;
123
+ /**
124
+ * Specify the size of the ListBox. Currently supports either `sm`, `md` or `lg` as an option.
125
+ */
126
+ size?: ListBoxSize;
127
+ /**
128
+ * Provide text to be used in a `<label>` element that is tied to the
129
+ * combobox via ARIA attributes.
130
+ */
131
+ titleText?: ReactNodeLike;
132
+ /**
133
+ * Specify a custom translation function that takes in a message identifier
134
+ * and returns the localized string for the message
135
+ */
136
+ translateWithId?: (id: any) => string;
137
+ /**
138
+ * Currently supports either the default type, or an inline variant
139
+ */
140
+ type?: ListBoxType;
141
+ /**
142
+ * Specify whether the control is currently in warning state
143
+ */
144
+ warn?: boolean;
145
+ /**
146
+ * Provide the text that is displayed when the control is in warning state
147
+ */
148
+ warnText?: ReactNodeLike;
149
+ }
150
+ declare const ComboBox: React.ForwardRefExoticComponent<ComboBoxProps & React.RefAttributes<unknown>>;
151
+ export default ComboBox;
@@ -71,7 +71,8 @@ var getInputValue = function getInputValue(_ref) {
71
71
 
72
72
  var findHighlightedIndex = function findHighlightedIndex(_ref2, inputValue) {
73
73
  var items = _ref2.items,
74
- itemToString = _ref2.itemToString;
74
+ _ref2$itemToString = _ref2.itemToString,
75
+ itemToString = _ref2$itemToString === void 0 ? defaultItemToString : _ref2$itemToString;
75
76
 
76
77
  if (!inputValue) {
77
78
  return -1;
@@ -80,9 +81,9 @@ var findHighlightedIndex = function findHighlightedIndex(_ref2, inputValue) {
80
81
  var searchValue = inputValue.toLowerCase();
81
82
 
82
83
  for (var i = 0; i < items.length; i++) {
83
- var item = itemToString(items[i]).toLowerCase();
84
+ var _item = itemToString(items[i]).toLowerCase();
84
85
 
85
- if (item.indexOf(searchValue) !== -1) {
86
+ if (_item.indexOf(searchValue) !== -1) {
86
87
  return i;
87
88
  }
88
89
  }
@@ -92,7 +93,7 @@ var findHighlightedIndex = function findHighlightedIndex(_ref2, inputValue) {
92
93
 
93
94
  var getInstanceId = setupGetInstanceId["default"]();
94
95
  var ComboBox = /*#__PURE__*/React__default["default"].forwardRef(function (props, ref) {
95
- var _cx, _ref4, _Text;
96
+ var _cx, _ref4, _cx4, _Text;
96
97
 
97
98
  var ariaLabel = props.ariaLabel,
98
99
  containerClassName = props.className,
@@ -129,7 +130,7 @@ var ComboBox = /*#__PURE__*/React__default["default"].forwardRef(function (props
129
130
  var _useContext = React.useContext(FormContext.FormContext),
130
131
  isFluid = _useContext.isFluid;
131
132
 
132
- var textInput = React.useRef();
133
+ var textInput = React.useRef(null);
133
134
  var comboBoxInstanceId = getInstanceId();
134
135
 
135
136
  var _useState = React.useState(getInputValue({
@@ -147,12 +148,12 @@ var ComboBox = /*#__PURE__*/React__default["default"].forwardRef(function (props
147
148
  isFocused = _useState4[0],
148
149
  setIsFocused = _useState4[1];
149
150
 
150
- var _useState5 = React.useState(null),
151
+ var _useState5 = React.useState(),
151
152
  _useState6 = _rollupPluginBabelHelpers.slicedToArray(_useState5, 2),
152
153
  prevSelectedItem = _useState6[0],
153
154
  setPrevSelectedItem = _useState6[1];
154
155
 
155
- var _useState7 = React.useState(null),
156
+ var _useState7 = React.useState(false),
156
157
  _useState8 = _rollupPluginBabelHelpers.slicedToArray(_useState7, 2),
157
158
  doneInitialSelectedItem = _useState8[0],
158
159
  setDoneInitialSelectedItem = _useState8[1];
@@ -172,11 +173,11 @@ var ComboBox = /*#__PURE__*/React__default["default"].forwardRef(function (props
172
173
 
173
174
  var filterItems = function filterItems(items, itemToString, inputValue) {
174
175
  return items.filter(function (item) {
175
- return shouldFilterItem({
176
+ return shouldFilterItem ? shouldFilterItem({
176
177
  item: item,
177
178
  itemToString: itemToString,
178
179
  inputValue: inputValue
179
- });
180
+ }) : defaultShouldFilterItem();
180
181
  });
181
182
  };
182
183
 
@@ -239,7 +240,7 @@ var ComboBox = /*#__PURE__*/React__default["default"].forwardRef(function (props
239
240
  var comboBoxHelperId = !helperText ? undefined : "combobox-helper-text-".concat(comboBoxInstanceId);
240
241
  var helperClasses = cx__default["default"]("".concat(prefix, "--form__helper-text"), _rollupPluginBabelHelpers.defineProperty({}, "".concat(prefix, "--form__helper-text--disabled"), disabled));
241
242
  var wrapperClasses = cx__default["default"]("".concat(prefix, "--list-box__wrapper"), [enabled ? containerClassName : null, (_ref4 = {}, _rollupPluginBabelHelpers.defineProperty(_ref4, "".concat(prefix, "--list-box__wrapper--fluid--invalid"), isFluid && invalid), _rollupPluginBabelHelpers.defineProperty(_ref4, "".concat(prefix, "--list-box__wrapper--fluid--focus"), isFluid && isFocused), _ref4)]);
242
- var inputClasses = cx__default["default"]("".concat(prefix, "--text-input"), _rollupPluginBabelHelpers.defineProperty({}, "".concat(prefix, "--text-input--empty"), !inputValue)); // needs to be Capitalized for react to render it correctly
243
+ var inputClasses = cx__default["default"]("".concat(prefix, "--text-input"), (_cx4 = {}, _rollupPluginBabelHelpers.defineProperty(_cx4, "".concat(prefix, "--text-input--empty"), !inputValue), _rollupPluginBabelHelpers.defineProperty(_cx4, "".concat(prefix, "--combo-box--input--focus"), isFocused && !isFluid), _cx4)); // needs to be Capitalized for react to render it correctly
243
244
 
244
245
  var ItemToElement = itemToElement;
245
246
  return /*#__PURE__*/React__default["default"].createElement(Downshift__default["default"], _rollupPluginBabelHelpers["extends"]({}, downshiftProps, {
@@ -275,7 +276,8 @@ var ComboBox = /*#__PURE__*/React__default["default"].forwardRef(function (props
275
276
  highlightedIndex = _ref5.highlightedIndex,
276
277
  clearSelection = _ref5.clearSelection,
277
278
  toggleMenu = _ref5.toggleMenu;
278
- var rootProps = getRootProps({}, {
279
+ var rootProps = getRootProps( // @ts-ignore this is not supposed to be a required property
280
+ {}, {
279
281
  suppressRefError: true
280
282
  });
281
283
  var labelProps = getLabelProps();
@@ -317,11 +319,7 @@ var ComboBox = /*#__PURE__*/React__default["default"].forwardRef(function (props
317
319
  });
318
320
 
319
321
  var handleFocus = function handleFocus(evt) {
320
- if (evt.target.type === 'button') {
321
- setIsFocused(false);
322
- } else {
323
- setIsFocused(evt.type === 'focus' ? true : false);
324
- }
322
+ setIsFocused(evt.type === 'focus');
325
323
  };
326
324
 
327
325
  var readOnlyEventHandlers = readOnly ? {
@@ -373,7 +371,8 @@ var ComboBox = /*#__PURE__*/React__default["default"].forwardRef(function (props
373
371
  clearSelection: clearSelection,
374
372
  translateWithId: translateWithId,
375
373
  disabled: disabled || readOnly,
376
- onClearSelection: handleSelectionClear
374
+ onClearSelection: handleSelectionClear,
375
+ selectionCount: 0
377
376
  }), /*#__PURE__*/React__default["default"].createElement(ListBoxTrigger["default"], _rollupPluginBabelHelpers["extends"]({}, buttonProps, {
378
377
  isOpen: isOpen,
379
378
  translateWithId: translateWithId
@@ -385,15 +384,18 @@ var ComboBox = /*#__PURE__*/React__default["default"].forwardRef(function (props
385
384
  var itemProps = getItemProps((_getItemProps = {
386
385
  item: item,
387
386
  index: index
388
- }, _rollupPluginBabelHelpers.defineProperty(_getItemProps, 'aria-current', selectedItem === item ? true : null), _rollupPluginBabelHelpers.defineProperty(_getItemProps, 'aria-selected', highlightedIndex === index ? true : null), _rollupPluginBabelHelpers.defineProperty(_getItemProps, "disabled", item.disabled), _getItemProps));
387
+ }, _rollupPluginBabelHelpers.defineProperty(_getItemProps, 'aria-current', selectedItem === item ? 'true' : 'false'), _rollupPluginBabelHelpers.defineProperty(_getItemProps, 'aria-selected', highlightedIndex === index ? 'true' : 'false'), _rollupPluginBabelHelpers.defineProperty(_getItemProps, "disabled", item.disabled), _getItemProps));
389
388
  return /*#__PURE__*/React__default["default"].createElement(index$1["default"].MenuItem, _rollupPluginBabelHelpers["extends"]({
390
389
  key: itemProps.id,
391
390
  isActive: selectedItem === item,
392
391
  isHighlighted: highlightedIndex === index || (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id) && (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id) === item.id || false,
393
- title: itemToElement ? item.text : itemToString(item)
394
- }, itemProps), itemToElement ? /*#__PURE__*/React__default["default"].createElement(ItemToElement, _rollupPluginBabelHelpers["extends"]({
392
+ title: itemToElement ? item.text : itemToString ? itemToString(item) : undefined
393
+ }, itemProps), itemToElement ?
394
+ /*#__PURE__*/
395
+ // @ts-ignore
396
+ React__default["default"].createElement(ItemToElement, _rollupPluginBabelHelpers["extends"]({
395
397
  key: itemProps.id
396
- }, item)) : itemToString(item), selectedItem === item && /*#__PURE__*/React__default["default"].createElement(iconsReact.Checkmark, {
398
+ }, item)) : itemToString ? itemToString(item) : defaultItemToString(item), selectedItem === item && /*#__PURE__*/React__default["default"].createElement(iconsReact.Checkmark, {
397
399
  className: "".concat(prefix, "--list-box__menu-item__selected-icon")
398
400
  }));
399
401
  }) : null)), helperText && !invalid && !warn && !isFluid && (_Text || (_Text = /*#__PURE__*/React__default["default"].createElement(Text.Text, {
@@ -428,6 +430,7 @@ ComboBox.propTypes = {
428
430
  /**
429
431
  * Additional props passed to Downshift
430
432
  */
433
+ // @ts-ignore
431
434
  downshiftProps: PropTypes__default["default"].shape(Downshift__default["default"].propTypes),
432
435
 
433
436
  /**
@@ -484,6 +487,7 @@ ComboBox.propTypes = {
484
487
  /**
485
488
  * `onChange` is a utility for this controlled component to communicate to a
486
489
  * consuming component when a specific dropdown item is selected.
490
+ * `({ selectedItem }) => void`
487
491
  * @param {{ selectedItem }}
488
492
  */
489
493
  onChange: PropTypes__default["default"].func.isRequired,
@@ -491,6 +495,7 @@ ComboBox.propTypes = {
491
495
  /**
492
496
  * Callback function to notify consumer when the text input changes.
493
497
  * This provides support to change available items based on the text.
498
+ * `(inputText) => void`
494
499
  * @param {string} inputText
495
500
  */
496
501
  onInputChange: PropTypes__default["default"].func,
@@ -498,11 +503,13 @@ ComboBox.propTypes = {
498
503
  /**
499
504
  * Helper function passed to Downshift that allows the user to observe internal
500
505
  * state changes
506
+ * `(changes, stateAndHelpers) => void`
501
507
  */
502
508
  onStateChange: PropTypes__default["default"].func,
503
509
 
504
510
  /**
505
511
  * Callback function that fires when the combobox menu toggle is clicked
512
+ * `(evt) => void`
506
513
  * @param {MouseEvent} event
507
514
  */
508
515
  onToggleClick: PropTypes__default["default"].func,
@@ -104,7 +104,7 @@ var ComposedModal = /*#__PURE__*/React__default["default"].forwardRef(function C
104
104
  onKeyDown(evt);
105
105
  }
106
106
 
107
- function handleClick(evt) {
107
+ function handleMousedown(evt) {
108
108
  if (!innerModal.current.contains(evt.target) && preventCloseOnClickOutside) {
109
109
  return;
110
110
  }
@@ -204,7 +204,7 @@ var ComposedModal = /*#__PURE__*/React__default["default"].forwardRef(function C
204
204
  ref: ref,
205
205
  "aria-hidden": !open,
206
206
  onBlur: handleBlur,
207
- onClick: handleClick,
207
+ onMouseDown: handleMousedown,
208
208
  onKeyDown: handleKeyDown,
209
209
  className: modalClass,
210
210
  tabIndex: "-1"