carbon-react 142.13.5 → 143.0.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/esm/__internal__/validations/validation-icon.component.js +2 -1
  2. package/esm/components/accordion/accordion-group/accordion-group.component.d.ts +2 -1
  3. package/esm/components/accordion/accordion-group/accordion-group.component.js +4 -1
  4. package/esm/components/advanced-color-picker/advanced-color-picker.component.js +3 -1
  5. package/esm/components/pages/page/page.component.js +1 -0
  6. package/esm/components/preview/preview.component.js +6 -2
  7. package/esm/components/select/__internal__/select-list/select-list.component.d.ts +4 -2
  8. package/esm/components/select/__internal__/select-list/select-list.component.js +8 -4
  9. package/esm/components/select/__internal__/utils/with-filter.hoc.js +3 -1
  10. package/esm/components/select/filterable-select/filterable-select.component.d.ts +4 -2
  11. package/esm/components/select/filterable-select/filterable-select.component.js +17 -3
  12. package/esm/components/select/multi-select/multi-select.component.d.ts +4 -2
  13. package/esm/components/select/multi-select/multi-select.component.js +17 -3
  14. package/esm/components/select/option/option.component.d.ts +5 -5
  15. package/esm/components/select/option/option.component.js +8 -8
  16. package/esm/components/select/option/option.style.d.ts +1 -0
  17. package/esm/components/select/option/option.style.js +9 -7
  18. package/esm/components/select/option-group-header/option-group-header.component.d.ts +1 -1
  19. package/esm/components/select/option-group-header/option-group-header.component.js +2 -2
  20. package/esm/components/select/option-row/option-row.component.d.ts +1 -1
  21. package/esm/components/select/option-row/option-row.component.js +3 -3
  22. package/esm/components/select/simple-select/simple-select.component.d.ts +4 -2
  23. package/esm/components/select/simple-select/simple-select.component.js +36 -43
  24. package/lib/__internal__/validations/validation-icon.component.js +2 -1
  25. package/lib/components/accordion/accordion-group/accordion-group.component.d.ts +2 -1
  26. package/lib/components/accordion/accordion-group/accordion-group.component.js +4 -1
  27. package/lib/components/advanced-color-picker/advanced-color-picker.component.js +3 -1
  28. package/lib/components/pages/page/page.component.js +1 -0
  29. package/lib/components/preview/preview.component.js +6 -2
  30. package/lib/components/select/__internal__/select-list/select-list.component.d.ts +4 -2
  31. package/lib/components/select/__internal__/select-list/select-list.component.js +8 -4
  32. package/lib/components/select/__internal__/utils/with-filter.hoc.js +3 -1
  33. package/lib/components/select/filterable-select/filterable-select.component.d.ts +4 -2
  34. package/lib/components/select/filterable-select/filterable-select.component.js +17 -3
  35. package/lib/components/select/multi-select/multi-select.component.d.ts +4 -2
  36. package/lib/components/select/multi-select/multi-select.component.js +17 -3
  37. package/lib/components/select/option/option.component.d.ts +5 -5
  38. package/lib/components/select/option/option.component.js +8 -8
  39. package/lib/components/select/option/option.style.d.ts +1 -0
  40. package/lib/components/select/option/option.style.js +9 -7
  41. package/lib/components/select/option-group-header/option-group-header.component.d.ts +1 -1
  42. package/lib/components/select/option-group-header/option-group-header.component.js +2 -2
  43. package/lib/components/select/option-row/option-row.component.d.ts +1 -1
  44. package/lib/components/select/option-row/option-row.component.js +3 -3
  45. package/lib/components/select/simple-select/simple-select.component.d.ts +4 -2
  46. package/lib/components/select/simple-select/simple-select.component.js +36 -43
  47. package/package.json +2 -2
@@ -48,12 +48,13 @@ const SimpleSelect = /*#__PURE__*/React.forwardRef(({
48
48
  virtualScrollOverscan,
49
49
  isOptional,
50
50
  required,
51
+ listWidth,
51
52
  ...props
52
53
  }, ref) => {
53
54
  const selectListId = useRef(guid());
54
55
  const containerRef = useRef(null);
55
56
  const listboxRef = useRef(null);
56
- const filterTimer = useRef();
57
+ const filterTimer = useRef(undefined);
57
58
  const isMouseDownReported = useRef();
58
59
  const isControlled = useRef(value !== undefined);
59
60
  const isTimerCounting = useRef();
@@ -71,7 +72,7 @@ const SimpleSelect = /*#__PURE__*/React.forwardRef(({
71
72
  id: inputId.current,
72
73
  label
73
74
  });
74
- const focusTimer = useRef(null);
75
+ const focusTimer = useRef(undefined);
75
76
  const componentIsUncontrolled = !isControlled || !onChange && defaultValue;
76
77
  if (!deprecateUncontrolledWarnTriggered && componentIsUncontrolled) {
77
78
  deprecateUncontrolledWarnTriggered = true;
@@ -100,9 +101,7 @@ const SimpleSelect = /*#__PURE__*/React.forwardRef(({
100
101
  if (!match) {
101
102
  return previousValue;
102
103
  }
103
- if (onChange) {
104
- onChange(createCustomEvent(match.props.value));
105
- }
104
+ onChange?.(createCustomEvent(match.props.value));
106
105
  if (isControlled.current) {
107
106
  return previousValue;
108
107
  }
@@ -115,14 +114,14 @@ const SimpleSelect = /*#__PURE__*/React.forwardRef(({
115
114
  const newVal = filterText.current + newCharacter;
116
115
  filterText.current = newVal;
117
116
  selectValueStartingWithText(newVal);
118
- clearTimeout(filterTimer.current);
117
+ window.clearTimeout(filterTimer.current);
119
118
  } else {
120
119
  filterText.current = newCharacter;
121
120
  selectValueStartingWithText(newCharacter);
122
121
  }
123
122
  isTimerCounting.current = true;
124
- clearTimeout(filterTimer.current);
125
- filterTimer.current = setTimeout(() => {
123
+ window.clearTimeout(filterTimer.current);
124
+ filterTimer.current = window.setTimeout(() => {
126
125
  isTimerCounting.current = false;
127
126
  filterText.current = "";
128
127
  }, 500);
@@ -131,18 +130,12 @@ const SimpleSelect = /*#__PURE__*/React.forwardRef(({
131
130
  const {
132
131
  key
133
132
  } = event;
134
- if (onKeyDown) {
135
- onKeyDown(event);
136
- }
137
- if (readOnly) {
138
- return;
139
- }
133
+ onKeyDown?.(event);
134
+ if (readOnly) return;
140
135
  if (key === " " || isNavigationKey(key)) {
141
136
  event.preventDefault();
142
137
  setOpenState(isAlreadyOpen => {
143
- if (!isAlreadyOpen && onOpen) {
144
- onOpen();
145
- }
138
+ if (!isAlreadyOpen) onOpen?.();
146
139
  return true;
147
140
  });
148
141
  } else if (key.length === 1 && !event.metaKey && !event.ctrlKey) {
@@ -184,21 +177,18 @@ const SimpleSelect = /*#__PURE__*/React.forwardRef(({
184
177
  }, [handleGlobalClick]);
185
178
  useEffect(() => {
186
179
  return function cleanup() {
187
- clearTimeout(filterTimer.current);
180
+ window.clearTimeout(filterTimer.current);
181
+ window.clearTimeout(focusTimer.current);
188
182
  };
189
183
  }, []);
190
184
  function handleTextboxClick(event) {
191
185
  isMouseDownReported.current = false;
192
- if (onClick) {
193
- onClick(event);
194
- }
186
+ onClick?.(event);
195
187
  setOpenState(isAlreadyOpen => {
196
188
  if (isAlreadyOpen) {
197
189
  return false;
198
190
  }
199
- if (onOpen) {
200
- onOpen();
201
- }
191
+ onOpen?.();
202
192
  return true;
203
193
  });
204
194
  }
@@ -212,9 +202,7 @@ const SimpleSelect = /*#__PURE__*/React.forwardRef(({
212
202
  if (isMouseDownReported.current) {
213
203
  return;
214
204
  }
215
- if (onBlur) {
216
- onBlur(event);
217
- }
205
+ onBlur?.(event);
218
206
  }
219
207
  function handleTextboxMouseDown() {
220
208
  isMouseDownReported.current = true;
@@ -223,28 +211,22 @@ const SimpleSelect = /*#__PURE__*/React.forwardRef(({
223
211
  if (isClickTriggeredBySelect.current) {
224
212
  return;
225
213
  }
226
- if (onFocus) {
227
- onFocus(event);
228
- }
214
+ onFocus?.(event);
229
215
  if (isMouseDownReported.current) {
230
216
  isMouseDownReported.current = false;
231
217
  return;
232
218
  }
233
219
  if (openOnFocus) {
234
- if (focusTimer.current) {
235
- clearTimeout(focusTimer.current);
236
- }
220
+ window.clearTimeout(focusTimer.current);
237
221
 
238
222
  // we need to use a timeout here as there is a race condition when rendered in a modal
239
223
  // whereby the select list isn't visible when the select is auto focused straight away
240
- focusTimer.current = setTimeout(() => {
224
+ focusTimer.current = window.setTimeout(() => {
241
225
  setOpenState(isAlreadyOpen => {
242
226
  if (isAlreadyOpen) {
243
227
  return true;
244
228
  }
245
- if (onOpen) {
246
- onOpen();
247
- }
229
+ onOpen?.();
248
230
  return true;
249
231
  });
250
232
  });
@@ -255,9 +237,7 @@ const SimpleSelect = /*#__PURE__*/React.forwardRef(({
255
237
  setSelectedValue(newValue);
256
238
  setTextValue(text);
257
239
  }
258
- if (onChange) {
259
- onChange(createCustomEvent(newValue, selectionConfirmed));
260
- }
240
+ onChange?.(createCustomEvent(newValue, selectionConfirmed));
261
241
  }
262
242
  function onSelectOption(optionData) {
263
243
  const {
@@ -314,6 +294,17 @@ const SimpleSelect = /*#__PURE__*/React.forwardRef(({
314
294
  ...filterOutStyledSystemSpacingProps(props)
315
295
  };
316
296
  }
297
+ let placement;
298
+ switch (listPlacement) {
299
+ case "top":
300
+ placement = "top-end";
301
+ break;
302
+ case "bottom":
303
+ placement = "bottom-end";
304
+ break;
305
+ default:
306
+ placement = listPlacement;
307
+ }
317
308
  const selectList = /*#__PURE__*/React.createElement(SelectList, {
318
309
  ref: listboxRef,
319
310
  id: selectListId.current,
@@ -328,11 +319,12 @@ const SimpleSelect = /*#__PURE__*/React.forwardRef(({
328
319
  onListScrollBottom: onListScrollBottom,
329
320
  tableHeader: tableHeader,
330
321
  multiColumn: multiColumn,
331
- listPlacement: listPlacement,
322
+ listPlacement: listWidth !== undefined ? placement : listPlacement,
332
323
  flipEnabled: flipEnabled,
333
324
  isOpen: isOpen,
334
325
  enableVirtualScroll: enableVirtualScroll,
335
- virtualScrollOverscan: virtualScrollOverscan
326
+ virtualScrollOverscan: virtualScrollOverscan,
327
+ listWidth: listWidth
336
328
  }, children);
337
329
  const marginProps = useFormSpacing(props);
338
330
  return /*#__PURE__*/React.createElement(StyledSelect, _extends({
@@ -486,7 +478,8 @@ if (process.env.NODE_ENV !== "production") {
486
478
  "leftChildren": PropTypes.node,
487
479
  "list": PropTypes.string,
488
480
  "listMaxHeight": PropTypes.number,
489
- "listPlacement": PropTypes.oneOf(["bottom", "left", "right", "top"]),
481
+ "listPlacement": PropTypes.oneOf(["bottom-end", "bottom-start", "bottom", "top-end", "top-start", "top"]),
482
+ "listWidth": PropTypes.number,
490
483
  "m": PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.oneOf([null]), PropTypes.number, PropTypes.shape({
491
484
  "__@toStringTag": PropTypes.string.isRequired,
492
485
  "description": PropTypes.string,
@@ -78,7 +78,8 @@ const ValidationIcon = ({
78
78
  setTriggeredByIcon(false);
79
79
  if (onBlur) onBlur(e);
80
80
  },
81
- isPartOfInput: isPartOfInput
81
+ isPartOfInput: isPartOfInput,
82
+ "data-role": "validation-icon-wrapper"
82
83
  }, (0, _utils.filterStyledSystemMarginProps)(rest)), /*#__PURE__*/_react.default.createElement(_icon.default, {
83
84
  "aria-describedby": validationTooltipId.current,
84
85
  key: `${validationType}-icon`,
@@ -1,9 +1,10 @@
1
1
  import React from "react";
2
2
  import { MarginProps } from "styled-system";
3
+ import { TagProps } from "../../../__internal__/utils/helpers/tags";
3
4
  declare type AccordionGroupChild = React.ReactElement | boolean | null | undefined | AccordionGroupChildArray;
4
5
  interface AccordionGroupChildArray extends Array<AccordionGroupChild> {
5
6
  }
6
- export interface AccordionGroupProps extends MarginProps {
7
+ export interface AccordionGroupProps extends MarginProps, Omit<TagProps, "data-component"> {
7
8
  /** An Accordion or list of Accordion components to be rendered inside the AccordionGroup */
8
9
  children?: AccordionGroupChild;
9
10
  }
@@ -13,6 +13,7 @@ var _accordion2 = require("../accordion.style");
13
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
14
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
15
15
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
16
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
16
17
  // typescript-to-proptypes breaks on recursive type references so it has to be an interface
17
18
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
18
19
 
@@ -58,7 +59,9 @@ const AccordionGroup = ({
58
59
  focusAccordion(ev, refs.length - 1);
59
60
  }
60
61
  }, [focusAccordion, refs]);
61
- return /*#__PURE__*/_react.default.createElement(_accordion2.StyledAccordionGroup, rest, filteredChildren.map((child, index) =>
62
+ return /*#__PURE__*/_react.default.createElement(_accordion2.StyledAccordionGroup, _extends({}, rest, {
63
+ "data-component": "accordion-group"
64
+ }), filteredChildren.map((child, index) =>
62
65
  /*#__PURE__*/
63
66
  // casted to ReactElement as there is no overload for an FunctionComponentElement in cloneElement
64
67
  _react.default.cloneElement(child, {
@@ -129,7 +129,9 @@ const AdvancedColorPicker = ({
129
129
  }
130
130
  return /*#__PURE__*/_react.default.createElement(_advancedColorPicker.StyledAdvancedColorPickerWrapper, _extends({
131
131
  m: "15px auto auto 15px"
132
- }, (0, _utils.filterStyledSystemMarginProps)(props)), /*#__PURE__*/_react.default.createElement(_advancedColorPicker.StyledAdvancedColorPickerCell, {
132
+ }, (0, _utils.filterStyledSystemMarginProps)(props), {
133
+ "data-role": "advanced-color-picker-wrapper"
134
+ }), /*#__PURE__*/_react.default.createElement(_advancedColorPicker.StyledAdvancedColorPickerCell, {
133
135
  "data-element": "color-picker-cell",
134
136
  "aria-label": l.advancedColorPicker.ariaLabel(),
135
137
  "aria-describedby": descriptionId.current,
@@ -44,6 +44,7 @@ const Page = ({
44
44
  hasContent: true
45
45
  }, title), /*#__PURE__*/_react.default.createElement(_page.StyledPageContent, _extends({
46
46
  "data-element": "carbon-page-content",
47
+ "data-role": "page-content",
47
48
  p: "34px 40px"
48
49
  }, (0, _utils.filterStyledSystemPaddingProps)(rest)), /*#__PURE__*/_react.default.createElement(_box.default, {
49
50
  boxSizing: "border-box",
@@ -41,9 +41,13 @@ const Preview = ({
41
41
  disableAnimation: disableAnimation || reduceMotion
42
42
  }, props)));
43
43
  }
44
- return /*#__PURE__*/_react.default.createElement(_preview.StyledPreview, marginProps, placeholders);
44
+ return /*#__PURE__*/_react.default.createElement(_preview.StyledPreview, _extends({
45
+ "data-role": "preview-wrapper"
46
+ }, marginProps), placeholders);
45
47
  }
46
- return /*#__PURE__*/_react.default.createElement(_preview.StyledPreview, marginProps, children);
48
+ return /*#__PURE__*/_react.default.createElement(_preview.StyledPreview, _extends({
49
+ "data-role": "preview-wrapper"
50
+ }, marginProps), children);
47
51
  };
48
52
  exports.Preview = Preview;
49
53
  var _default = exports.default = Preview;
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { Side } from "@floating-ui/dom";
2
+ export declare type ListPlacement = "top" | "bottom" | "top-start" | "bottom-start" | "top-end" | "bottom-end";
3
3
  export interface SelectListProps {
4
4
  /** The ID for the parent <div> */
5
5
  id?: string;
@@ -38,7 +38,7 @@ export interface SelectListProps {
38
38
  /** When true component will work in multi column mode, children should consist of OptionRow components in this mode */
39
39
  multiColumn?: boolean;
40
40
  /** Placement of the select list relative to the input element */
41
- listPlacement?: Side;
41
+ listPlacement?: ListPlacement;
42
42
  /** Use the opposite list placement if the set placement does not fit */
43
43
  flipEnabled?: boolean;
44
44
  /** @private @ignore
@@ -56,6 +56,8 @@ export interface SelectListProps {
56
56
  virtualScrollOverscan?: number;
57
57
  /** @private @ignore A callback for when a mouseDown event occurs on the component */
58
58
  onMouseDown?: () => void;
59
+ /** Override the default width of the list element. Number passed is converted into pixel value */
60
+ listWidth?: number;
59
61
  }
60
62
  declare const SelectList: React.ForwardRefExoticComponent<SelectListProps & React.RefAttributes<HTMLDivElement>>;
61
63
  export default SelectList;
@@ -53,6 +53,7 @@ const SelectList = /*#__PURE__*/_react.default.forwardRef(({
53
53
  multiselectValues,
54
54
  enableVirtualScroll,
55
55
  virtualScrollOverscan = 5,
56
+ listWidth,
56
57
  ...listProps
57
58
  }, listContainerRef) => {
58
59
  const [currentOptionsListIndex, setCurrentOptionsListIndex] = (0, _react.useState)(-1);
@@ -162,7 +163,9 @@ const SelectList = /*#__PURE__*/_react.default.forwardRef(({
162
163
  const childElementRefs = (0, _react.useRef)(Array.from({
163
164
  length: _react.default.Children.count(children)
164
165
  }));
165
- const optionChildrenList = (0, _react.useMemo)(() => childrenList.filter(child => /*#__PURE__*/_react.default.isValidElement(child) && (child.type === _option.default || child.type === _optionRow.default)), [childrenList]);
166
+ const optionChildrenList = (0, _react.useMemo)(() => childrenList.filter(child => {
167
+ return /*#__PURE__*/_react.default.isValidElement(child) && (child.type === _option.default || child.type === _optionRow.default);
168
+ }), [childrenList]);
166
169
  const {
167
170
  measureElement
168
171
  } = virtualizer;
@@ -381,12 +384,12 @@ const SelectList = /*#__PURE__*/_react.default.forwardRef(({
381
384
  elements
382
385
  }) {
383
386
  Object.assign(elements.floating.style, {
384
- width: `${rects.reference.width}px`
387
+ width: `${listWidth ?? rects.reference.width}px`
385
388
  });
386
389
  }
387
390
  }), ...(flipEnabled ? [(0, _dom.flip)({
388
391
  fallbackStrategy: "initialPlacement"
389
- })] : [])], [flipEnabled]);
392
+ })] : [])], [listWidth, flipEnabled]);
390
393
  const loader = isLoading ? /*#__PURE__*/_react.default.createElement(_selectList.StyledSelectLoaderContainer, {
391
394
  key: "loader"
392
395
  }, /*#__PURE__*/_react.default.createElement(_loader.default, null)) : undefined;
@@ -467,7 +470,8 @@ if (process.env.NODE_ENV !== "production") {
467
470
  "labelId": _propTypes.default.string,
468
471
  "listActionButton": _propTypes.default.node,
469
472
  "listMaxHeight": _propTypes.default.number,
470
- "listPlacement": _propTypes.default.oneOf(["bottom", "left", "right", "top"]),
473
+ "listPlacement": _propTypes.default.oneOf(["bottom-end", "bottom-start", "bottom", "top-end", "top-start", "top"]),
474
+ "listWidth": _propTypes.default.number,
471
475
  "multiColumn": _propTypes.default.bool,
472
476
  "multiselectValues": _propTypes.default.arrayOf(_propTypes.default.string),
473
477
  "onListAction": _propTypes.default.func,
@@ -115,7 +115,9 @@ const withFilter = WrappedComponent => {
115
115
  colSpan: colSpan
116
116
  }, noResultsMessage || noResultsText));
117
117
  }
118
- return /*#__PURE__*/_react.default.createElement(_option.default, null, noResultsMessage || noResultsText);
118
+ return /*#__PURE__*/_react.default.createElement(_option.default, {
119
+ isInteractive: true
120
+ }, noResultsMessage || noResultsText);
119
121
  }
120
122
  return addHighlightedContent(filteredElements, filterText);
121
123
  }
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
- import { Side } from "@floating-ui/dom";
3
2
  import { ButtonProps } from "../../button";
4
3
  import { FormInputPropTypes } from "../__internal__/select-textbox";
4
+ import { ListPlacement } from "../__internal__/select-list/select-list.component";
5
5
  import { CustomSelectChangeEvent } from "../simple-select";
6
6
  export interface FilterableSelectProps extends Omit<FormInputPropTypes, "defaultValue" | "value"> {
7
7
  /** Prop to specify the aria-label attribute of the component input */
@@ -49,7 +49,7 @@ export interface FilterableSelectProps extends Omit<FormInputPropTypes, "default
49
49
  /** Maximum list height - defaults to 180 */
50
50
  listMaxHeight?: number;
51
51
  /** Placement of the select list in relation to the input element */
52
- listPlacement?: Side;
52
+ listPlacement?: ListPlacement;
53
53
  /** Use the opposite list placement if the set placement does not fit */
54
54
  flipEnabled?: boolean;
55
55
  /** Set this prop to enable a virtualised list of options. If it is not used then all options will be in the
@@ -68,6 +68,8 @@ export interface FilterableSelectProps extends Omit<FormInputPropTypes, "default
68
68
  required?: boolean;
69
69
  /** Specify a callback triggered on change */
70
70
  onChange?: (ev: CustomSelectChangeEvent | React.ChangeEvent<HTMLInputElement>) => void;
71
+ /** Override the default width of the list element. Number passed is converted into pixel value */
72
+ listWidth?: number;
71
73
  }
72
74
  export declare const FilterableSelect: React.ForwardRefExoticComponent<FilterableSelectProps & React.RefAttributes<HTMLInputElement>>;
73
75
  export default FilterableSelect;
@@ -63,6 +63,7 @@ const FilterableSelect = exports.FilterableSelect = /*#__PURE__*/_react.default.
63
63
  disableDefaultFiltering = false,
64
64
  isOptional,
65
65
  required,
66
+ listWidth,
66
67
  ...textboxProps
67
68
  }, ref) => {
68
69
  const [activeDescendantId, setActiveDescendantId] = (0, _react.useState)();
@@ -405,6 +406,17 @@ const FilterableSelect = exports.FilterableSelect = /*#__PURE__*/_react.default.
405
406
  ...(0, _utils.filterOutStyledSystemSpacingProps)(textboxProps)
406
407
  };
407
408
  }
409
+ let placement;
410
+ switch (listPlacement) {
411
+ case "top":
412
+ placement = "top-end";
413
+ break;
414
+ case "bottom":
415
+ placement = "bottom-end";
416
+ break;
417
+ default:
418
+ placement = listPlacement;
419
+ }
408
420
  const selectListProps = {
409
421
  ref: listboxRef,
410
422
  id: selectListId.current,
@@ -423,11 +435,12 @@ const FilterableSelect = exports.FilterableSelect = /*#__PURE__*/_react.default.
423
435
  onListScrollBottom,
424
436
  tableHeader,
425
437
  multiColumn,
426
- listPlacement,
438
+ listPlacement: listWidth !== undefined ? placement : listPlacement,
427
439
  flipEnabled,
428
440
  isOpen,
429
441
  enableVirtualScroll,
430
- virtualScrollOverscan
442
+ virtualScrollOverscan,
443
+ listWidth
431
444
  };
432
445
  const selectList = disableDefaultFiltering ? /*#__PURE__*/_react.default.createElement(_selectList.default, selectListProps, children) : /*#__PURE__*/_react.default.createElement(FilterableSelectList, selectListProps, children);
433
446
  const marginProps = (0, _useFormSpacing.default)(textboxProps);
@@ -585,7 +598,8 @@ if (process.env.NODE_ENV !== "production") {
585
598
  "list": _propTypes.default.string,
586
599
  "listActionButton": _propTypes.default.oneOfType([_propTypes.default.element, _propTypes.default.bool]),
587
600
  "listMaxHeight": _propTypes.default.number,
588
- "listPlacement": _propTypes.default.oneOf(["bottom", "left", "right", "top"]),
601
+ "listPlacement": _propTypes.default.oneOf(["bottom-end", "bottom-start", "bottom", "top-end", "top-start", "top"]),
602
+ "listWidth": _propTypes.default.number,
589
603
  "m": _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.oneOf([null]), _propTypes.default.number, _propTypes.default.shape({
590
604
  "__@toStringTag": _propTypes.default.string.isRequired,
591
605
  "description": _propTypes.default.string,
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
- import { Side } from "@floating-ui/dom";
3
2
  import { FormInputPropTypes } from "../__internal__/select-textbox";
3
+ import { ListPlacement } from "../__internal__/select-list/select-list.component";
4
4
  import { CustomSelectChangeEvent } from "../simple-select";
5
5
  export interface MultiSelectProps extends Omit<FormInputPropTypes, "defaultValue" | "value"> {
6
6
  /** Prop to specify the aria-label attribute of the component input */
@@ -44,7 +44,7 @@ export interface MultiSelectProps extends Omit<FormInputPropTypes, "defaultValue
44
44
  /** Maximum list height - defaults to 180 */
45
45
  listMaxHeight?: number;
46
46
  /** Placement of the select list in relation to the input element */
47
- listPlacement?: Side;
47
+ listPlacement?: ListPlacement;
48
48
  /** Use the opposite list placement if the set placement does not fit */
49
49
  flipEnabled?: boolean;
50
50
  /** Wraps the pill text when it would overflow the input width */
@@ -60,6 +60,8 @@ export interface MultiSelectProps extends Omit<FormInputPropTypes, "defaultValue
60
60
  isOptional?: boolean;
61
61
  /** Specify a callback triggered on change */
62
62
  onChange?: (ev: CustomSelectChangeEvent | React.ChangeEvent<HTMLInputElement>) => void;
63
+ /** Override the default width of the list element. Number passed is converted into pixel value */
64
+ listWidth?: number;
63
65
  }
64
66
  export declare const MultiSelect: React.ForwardRefExoticComponent<MultiSelectProps & React.RefAttributes<HTMLInputElement>>;
65
67
  export default MultiSelect;
@@ -64,6 +64,7 @@ const MultiSelect = exports.MultiSelect = /*#__PURE__*/_react.default.forwardRef
64
64
  virtualScrollOverscan,
65
65
  isOptional,
66
66
  required,
67
+ listWidth,
67
68
  ...textboxProps
68
69
  }, ref) => {
69
70
  const [activeDescendantId, setActiveDescendantId] = (0, _react.useState)();
@@ -430,6 +431,17 @@ const MultiSelect = exports.MultiSelect = /*#__PURE__*/_react.default.forwardRef
430
431
  ...(0, _utils.filterOutStyledSystemSpacingProps)(textboxProps)
431
432
  };
432
433
  }
434
+ let placement;
435
+ switch (listPlacement) {
436
+ case "top":
437
+ placement = "top-end";
438
+ break;
439
+ case "bottom":
440
+ placement = "bottom-end";
441
+ break;
442
+ default:
443
+ placement = listPlacement;
444
+ }
433
445
  const selectList = /*#__PURE__*/_react.default.createElement(FilterableSelectList, {
434
446
  ref: listboxRef,
435
447
  id: selectListId.current,
@@ -444,13 +456,14 @@ const MultiSelect = exports.MultiSelect = /*#__PURE__*/_react.default.forwardRef
444
456
  isLoading: isLoading,
445
457
  tableHeader: tableHeader,
446
458
  multiColumn: multiColumn,
447
- listPlacement: listPlacement,
459
+ listPlacement: listWidth !== undefined ? placement : listPlacement,
448
460
  listMaxHeight: listMaxHeight,
449
461
  flipEnabled: flipEnabled,
450
462
  multiselectValues: actualValue,
451
463
  isOpen: isOpen,
452
464
  enableVirtualScroll: enableVirtualScroll,
453
- virtualScrollOverscan: virtualScrollOverscan
465
+ virtualScrollOverscan: virtualScrollOverscan,
466
+ listWidth: listWidth
454
467
  }, children);
455
468
  const marginProps = (0, _useFormSpacing.default)(textboxProps);
456
469
  return /*#__PURE__*/_react.default.createElement(_multiSelect.StyledSelectMultiSelect, _extends({
@@ -610,7 +623,8 @@ if (process.env.NODE_ENV !== "production") {
610
623
  "leftChildren": _propTypes.default.node,
611
624
  "list": _propTypes.default.string,
612
625
  "listMaxHeight": _propTypes.default.number,
613
- "listPlacement": _propTypes.default.oneOf(["bottom", "left", "right", "top"]),
626
+ "listPlacement": _propTypes.default.oneOf(["bottom-end", "bottom-start", "bottom", "top-end", "top-start", "top"]),
627
+ "listWidth": _propTypes.default.number,
614
628
  "m": _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.oneOf([null]), _propTypes.default.number, _propTypes.default.shape({
615
629
  "__@toStringTag": _propTypes.default.string.isRequired,
616
630
  "description": _propTypes.default.string,
@@ -1,17 +1,17 @@
1
1
  import React from "react";
2
2
  import { TagProps } from "../../../__internal__/utils/helpers/tags";
3
- export interface OptionProps extends Omit<React.InputHTMLAttributes<HTMLLIElement>, "value" | "onSelect" | "onClick">, TagProps {
3
+ export interface OptionProps extends Omit<React.InputHTMLAttributes<HTMLLIElement>, "value" | "onSelect" | "onClick">, Omit<TagProps, "data-component"> {
4
4
  /**
5
5
  * Unique identifier for the component.
6
6
  * Will use a randomly generated GUID if none is provided.
7
7
  */
8
8
  id?: string;
9
9
  /** The option's visible text, displayed within `<Textbox>` of `<Select>`, and used for filtering */
10
- text: string;
11
- /** Optional: alternative rendered content, displayed within `<SelectList>` of `<Select>` (eg: an icon, an image, etc) */
10
+ text?: string;
11
+ /** Alternative rendered content, displayed within `<SelectList>` of `<Select>` (eg: an icon, an image, etc) */
12
12
  children?: React.ReactNode;
13
- /** The option's invisible internal value */
14
- value: string | Record<string, unknown>;
13
+ /** The option's invisible internal value, if this is not passed the option will not be treated as interactive or selectable */
14
+ value?: string | Record<string, unknown>;
15
15
  /** MultiSelect only - custom Pill border color - provide any color from palette or any valid css color value. */
16
16
  borderColor?: string;
17
17
  /** MultiSelect only - fill Pill background with color */
@@ -29,11 +29,11 @@ const Option = /*#__PURE__*/_react.default.forwardRef(({
29
29
  const selectListContext = (0, _react.useContext)(_selectList.default);
30
30
  let isSelected = selectListContext.currentOptionsListIndex === index;
31
31
  const internalIdRef = (0, _react.useRef)(id || (0, _guid.default)());
32
- if (selectListContext.multiselectValues) {
32
+ if (selectListContext.multiselectValues && value) {
33
33
  isSelected = selectListContext.multiselectValues.includes(value);
34
34
  }
35
35
  function handleClick() {
36
- if (disabled) {
36
+ if (disabled || !value) {
37
37
  return;
38
38
  }
39
39
  if (!onClick) {
@@ -52,15 +52,16 @@ const Option = /*#__PURE__*/_react.default.forwardRef(({
52
52
  ref: ref,
53
53
  "aria-selected": isSelected,
54
54
  "aria-disabled": disabled,
55
- "data-component": "option",
56
55
  isDisabled: disabled,
57
56
  onClick: handleClick,
58
57
  isHighlighted: selectListContext.currentOptionsListIndex === index,
59
58
  role: "option",
60
59
  hidden: hidden,
61
- style: style
60
+ style: style,
61
+ isInteractive: !!value
62
62
  }, rest, {
63
- fill: undefined
63
+ fill: undefined,
64
+ "data-component": "option"
64
65
  }), children || text);
65
66
  });
66
67
  if (process.env.NODE_ENV !== "production") {
@@ -134,7 +135,6 @@ if (process.env.NODE_ENV !== "production") {
134
135
  "dangerouslySetInnerHTML": _propTypes.default.shape({
135
136
  "__html": _propTypes.default.oneOfType([_propTypes.default.object, _propTypes.default.string]).isRequired
136
137
  }),
137
- "data-component": _propTypes.default.string,
138
138
  "data-element": _propTypes.default.string,
139
139
  "data-role": _propTypes.default.string,
140
140
  "datatype": _propTypes.default.string,
@@ -404,7 +404,7 @@ if (process.env.NODE_ENV !== "production") {
404
404
  "suppressContentEditableWarning": _propTypes.default.bool,
405
405
  "suppressHydrationWarning": _propTypes.default.bool,
406
406
  "tabIndex": _propTypes.default.number,
407
- "text": _propTypes.default.string.isRequired,
407
+ "text": _propTypes.default.string,
408
408
  "title": _propTypes.default.string,
409
409
  "translate": _propTypes.default.oneOf(["no", "yes"]),
410
410
  "type": _propTypes.default.oneOfType([_propTypes.default.oneOf(["button", "checkbox", "color", "date", "datetime-local", "email", "file", "hidden", "image", "month", "number", "password", "radio", "range", "reset", "search", "submit", "tel", "text", "time", "url", "week"]), _propTypes.default.shape({
@@ -460,7 +460,7 @@ if (process.env.NODE_ENV !== "production") {
460
460
  })]),
461
461
  "typeof": _propTypes.default.string,
462
462
  "unselectable": _propTypes.default.oneOf(["off", "on"]),
463
- "value": _propTypes.default.oneOfType([_propTypes.default.object, _propTypes.default.string]).isRequired,
463
+ "value": _propTypes.default.oneOfType([_propTypes.default.object, _propTypes.default.string]),
464
464
  "vocab": _propTypes.default.string,
465
465
  "width": _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string])
466
466
  };
@@ -2,6 +2,7 @@ import { OptionProps } from ".";
2
2
  interface StyledOptionProps extends Pick<OptionProps, "id"> {
3
3
  isHighlighted?: boolean;
4
4
  isDisabled?: boolean;
5
+ isInteractive: boolean;
5
6
  }
6
7
  declare const StyledOption: import("styled-components").StyledComponent<"li", any, StyledOptionProps, never>;
7
8
  export default StyledOption;
@@ -8,7 +8,6 @@ var _styledComponents = _interopRequireWildcard(require("styled-components"));
8
8
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
9
9
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
10
10
  const StyledOption = _styledComponents.default.li`
11
- cursor: pointer;
12
11
  box-sizing: border-box;
13
12
  line-height: 16px;
14
13
  padding: 12px 16px;
@@ -20,19 +19,22 @@ const StyledOption = _styledComponents.default.li`
20
19
  width: 100%;
21
20
 
22
21
  ${({
22
+ isInteractive,
23
23
  isHighlighted
24
- }) => isHighlighted && (0, _styledComponents.css)`
25
- background-color: var(--colorsUtilityMajor200);
24
+ }) => isInteractive && (0, _styledComponents.css)`
25
+ cursor: pointer;
26
+ :hover {
27
+ background-color: var(--colorsUtilityMajor100);
28
+ }
29
+ ${isHighlighted && (0, _styledComponents.css)`
30
+ background-color: var(--colorsUtilityMajor200);
31
+ `}
26
32
  `}
27
33
 
28
34
  ${({
29
35
  hidden
30
36
  }) => hidden && "display: none;"}
31
37
 
32
- :hover {
33
- background-color: var(--colorsUtilityMajor100);
34
- }
35
-
36
38
  ${({
37
39
  isDisabled
38
40
  }) => isDisabled && (0, _styledComponents.css)`