carbon-react 142.13.5 → 143.0.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 (29) 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 +5 -3
  9. package/esm/components/select/filterable-select/filterable-select.component.d.ts +4 -2
  10. package/esm/components/select/filterable-select/filterable-select.component.js +17 -3
  11. package/esm/components/select/multi-select/multi-select.component.d.ts +4 -2
  12. package/esm/components/select/multi-select/multi-select.component.js +17 -3
  13. package/esm/components/select/simple-select/simple-select.component.d.ts +4 -2
  14. package/esm/components/select/simple-select/simple-select.component.js +36 -43
  15. package/lib/__internal__/validations/validation-icon.component.js +2 -1
  16. package/lib/components/accordion/accordion-group/accordion-group.component.d.ts +2 -1
  17. package/lib/components/accordion/accordion-group/accordion-group.component.js +4 -1
  18. package/lib/components/advanced-color-picker/advanced-color-picker.component.js +3 -1
  19. package/lib/components/pages/page/page.component.js +1 -0
  20. package/lib/components/preview/preview.component.js +6 -2
  21. package/lib/components/select/__internal__/select-list/select-list.component.d.ts +4 -2
  22. package/lib/components/select/__internal__/select-list/select-list.component.js +5 -3
  23. package/lib/components/select/filterable-select/filterable-select.component.d.ts +4 -2
  24. package/lib/components/select/filterable-select/filterable-select.component.js +17 -3
  25. package/lib/components/select/multi-select/multi-select.component.d.ts +4 -2
  26. package/lib/components/select/multi-select/multi-select.component.js +17 -3
  27. package/lib/components/select/simple-select/simple-select.component.d.ts +4 -2
  28. package/lib/components/select/simple-select/simple-select.component.js +36 -43
  29. package/package.json +1 -1
@@ -69,7 +69,8 @@ export const ValidationIcon = ({
69
69
  setTriggeredByIcon(false);
70
70
  if (onBlur) onBlur(e);
71
71
  },
72
- isPartOfInput: isPartOfInput
72
+ isPartOfInput: isPartOfInput,
73
+ "data-role": "validation-icon-wrapper"
73
74
  }, filterStyledSystemMarginProps(rest)), /*#__PURE__*/React.createElement(Icon, {
74
75
  "aria-describedby": validationTooltipId.current,
75
76
  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
  }
@@ -1,3 +1,4 @@
1
+ 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); }
1
2
  import React, { useMemo, useCallback } from "react";
2
3
  import PropTypes from "prop-types";
3
4
  import invariant from "invariant";
@@ -50,7 +51,9 @@ export const AccordionGroup = ({
50
51
  focusAccordion(ev, refs.length - 1);
51
52
  }
52
53
  }, [focusAccordion, refs]);
53
- return /*#__PURE__*/React.createElement(StyledAccordionGroup, rest, filteredChildren.map((child, index) =>
54
+ return /*#__PURE__*/React.createElement(StyledAccordionGroup, _extends({}, rest, {
55
+ "data-component": "accordion-group"
56
+ }), filteredChildren.map((child, index) =>
54
57
  /*#__PURE__*/
55
58
  // casted to ReactElement as there is no overload for an FunctionComponentElement in cloneElement
56
59
  React.cloneElement(child, {
@@ -120,7 +120,9 @@ export const AdvancedColorPicker = ({
120
120
  }
121
121
  return /*#__PURE__*/React.createElement(StyledAdvancedColorPickerWrapper, _extends({
122
122
  m: "15px auto auto 15px"
123
- }, filterStyledSystemMarginProps(props)), /*#__PURE__*/React.createElement(StyledAdvancedColorPickerCell, {
123
+ }, filterStyledSystemMarginProps(props), {
124
+ "data-role": "advanced-color-picker-wrapper"
125
+ }), /*#__PURE__*/React.createElement(StyledAdvancedColorPickerCell, {
124
126
  "data-element": "color-picker-cell",
125
127
  "aria-label": l.advancedColorPicker.ariaLabel(),
126
128
  "aria-describedby": descriptionId.current,
@@ -35,6 +35,7 @@ const Page = ({
35
35
  hasContent: true
36
36
  }, title), /*#__PURE__*/React.createElement(StyledPageContent, _extends({
37
37
  "data-element": "carbon-page-content",
38
+ "data-role": "page-content",
38
39
  p: "34px 40px"
39
40
  }, filterStyledSystemPaddingProps(rest)), /*#__PURE__*/React.createElement(Box, {
40
41
  boxSizing: "border-box",
@@ -34,8 +34,12 @@ export const Preview = ({
34
34
  disableAnimation: disableAnimation || reduceMotion
35
35
  }, props)));
36
36
  }
37
- return /*#__PURE__*/React.createElement(StyledPreview, marginProps, placeholders);
37
+ return /*#__PURE__*/React.createElement(StyledPreview, _extends({
38
+ "data-role": "preview-wrapper"
39
+ }, marginProps), placeholders);
38
40
  }
39
- return /*#__PURE__*/React.createElement(StyledPreview, marginProps, children);
41
+ return /*#__PURE__*/React.createElement(StyledPreview, _extends({
42
+ "data-role": "preview-wrapper"
43
+ }, marginProps), children);
40
44
  };
41
45
  export 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;
@@ -44,6 +44,7 @@ const SelectList = /*#__PURE__*/React.forwardRef(({
44
44
  multiselectValues,
45
45
  enableVirtualScroll,
46
46
  virtualScrollOverscan = 5,
47
+ listWidth,
47
48
  ...listProps
48
49
  }, listContainerRef) => {
49
50
  const [currentOptionsListIndex, setCurrentOptionsListIndex] = useState(-1);
@@ -372,12 +373,12 @@ const SelectList = /*#__PURE__*/React.forwardRef(({
372
373
  elements
373
374
  }) {
374
375
  Object.assign(elements.floating.style, {
375
- width: `${rects.reference.width}px`
376
+ width: `${listWidth ?? rects.reference.width}px`
376
377
  });
377
378
  }
378
379
  }), ...(flipEnabled ? [flip({
379
380
  fallbackStrategy: "initialPlacement"
380
- })] : [])], [flipEnabled]);
381
+ })] : [])], [listWidth, flipEnabled]);
381
382
  const loader = isLoading ? /*#__PURE__*/React.createElement(StyledSelectLoaderContainer, {
382
383
  key: "loader"
383
384
  }, /*#__PURE__*/React.createElement(Loader, null)) : undefined;
@@ -458,7 +459,8 @@ if (process.env.NODE_ENV !== "production") {
458
459
  "labelId": PropTypes.string,
459
460
  "listActionButton": PropTypes.node,
460
461
  "listMaxHeight": PropTypes.number,
461
- "listPlacement": PropTypes.oneOf(["bottom", "left", "right", "top"]),
462
+ "listPlacement": PropTypes.oneOf(["bottom-end", "bottom-start", "bottom", "top-end", "top-start", "top"]),
463
+ "listWidth": PropTypes.number,
462
464
  "multiColumn": PropTypes.bool,
463
465
  "multiselectValues": PropTypes.arrayOf(PropTypes.string),
464
466
  "onListAction": PropTypes.func,
@@ -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;
@@ -54,6 +54,7 @@ const FilterableSelect = /*#__PURE__*/React.forwardRef(({
54
54
  disableDefaultFiltering = false,
55
55
  isOptional,
56
56
  required,
57
+ listWidth,
57
58
  ...textboxProps
58
59
  }, ref) => {
59
60
  const [activeDescendantId, setActiveDescendantId] = useState();
@@ -396,6 +397,17 @@ const FilterableSelect = /*#__PURE__*/React.forwardRef(({
396
397
  ...filterOutStyledSystemSpacingProps(textboxProps)
397
398
  };
398
399
  }
400
+ let placement;
401
+ switch (listPlacement) {
402
+ case "top":
403
+ placement = "top-end";
404
+ break;
405
+ case "bottom":
406
+ placement = "bottom-end";
407
+ break;
408
+ default:
409
+ placement = listPlacement;
410
+ }
399
411
  const selectListProps = {
400
412
  ref: listboxRef,
401
413
  id: selectListId.current,
@@ -414,11 +426,12 @@ const FilterableSelect = /*#__PURE__*/React.forwardRef(({
414
426
  onListScrollBottom,
415
427
  tableHeader,
416
428
  multiColumn,
417
- listPlacement,
429
+ listPlacement: listWidth !== undefined ? placement : listPlacement,
418
430
  flipEnabled,
419
431
  isOpen,
420
432
  enableVirtualScroll,
421
- virtualScrollOverscan
433
+ virtualScrollOverscan,
434
+ listWidth
422
435
  };
423
436
  const selectList = disableDefaultFiltering ? /*#__PURE__*/React.createElement(SelectList, selectListProps, children) : /*#__PURE__*/React.createElement(FilterableSelectList, selectListProps, children);
424
437
  const marginProps = useFormSpacing(textboxProps);
@@ -576,7 +589,8 @@ if (process.env.NODE_ENV !== "production") {
576
589
  "list": PropTypes.string,
577
590
  "listActionButton": PropTypes.oneOfType([PropTypes.element, PropTypes.bool]),
578
591
  "listMaxHeight": PropTypes.number,
579
- "listPlacement": PropTypes.oneOf(["bottom", "left", "right", "top"]),
592
+ "listPlacement": PropTypes.oneOf(["bottom-end", "bottom-start", "bottom", "top-end", "top-start", "top"]),
593
+ "listWidth": PropTypes.number,
580
594
  "m": PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.oneOf([null]), PropTypes.number, PropTypes.shape({
581
595
  "__@toStringTag": PropTypes.string.isRequired,
582
596
  "description": PropTypes.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;
@@ -55,6 +55,7 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
55
55
  virtualScrollOverscan,
56
56
  isOptional,
57
57
  required,
58
+ listWidth,
58
59
  ...textboxProps
59
60
  }, ref) => {
60
61
  const [activeDescendantId, setActiveDescendantId] = useState();
@@ -421,6 +422,17 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
421
422
  ...filterOutStyledSystemSpacingProps(textboxProps)
422
423
  };
423
424
  }
425
+ let placement;
426
+ switch (listPlacement) {
427
+ case "top":
428
+ placement = "top-end";
429
+ break;
430
+ case "bottom":
431
+ placement = "bottom-end";
432
+ break;
433
+ default:
434
+ placement = listPlacement;
435
+ }
424
436
  const selectList = /*#__PURE__*/React.createElement(FilterableSelectList, {
425
437
  ref: listboxRef,
426
438
  id: selectListId.current,
@@ -435,13 +447,14 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
435
447
  isLoading: isLoading,
436
448
  tableHeader: tableHeader,
437
449
  multiColumn: multiColumn,
438
- listPlacement: listPlacement,
450
+ listPlacement: listWidth !== undefined ? placement : listPlacement,
439
451
  listMaxHeight: listMaxHeight,
440
452
  flipEnabled: flipEnabled,
441
453
  multiselectValues: actualValue,
442
454
  isOpen: isOpen,
443
455
  enableVirtualScroll: enableVirtualScroll,
444
- virtualScrollOverscan: virtualScrollOverscan
456
+ virtualScrollOverscan: virtualScrollOverscan,
457
+ listWidth: listWidth
445
458
  }, children);
446
459
  const marginProps = useFormSpacing(textboxProps);
447
460
  return /*#__PURE__*/React.createElement(StyledSelectMultiSelect, _extends({
@@ -601,7 +614,8 @@ if (process.env.NODE_ENV !== "production") {
601
614
  "leftChildren": PropTypes.node,
602
615
  "list": PropTypes.string,
603
616
  "listMaxHeight": PropTypes.number,
604
- "listPlacement": PropTypes.oneOf(["bottom", "left", "right", "top"]),
617
+ "listPlacement": PropTypes.oneOf(["bottom-end", "bottom-start", "bottom", "top-end", "top-start", "top"]),
618
+ "listWidth": PropTypes.number,
605
619
  "m": PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.oneOf([null]), PropTypes.number, PropTypes.shape({
606
620
  "__@toStringTag": PropTypes.string.isRequired,
607
621
  "description": PropTypes.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
  export interface OptionData {
5
5
  text?: string;
6
6
  value?: string | Record<string, unknown>;
@@ -51,7 +51,7 @@ export interface SimpleSelectProps extends Omit<FormInputPropTypes, "defaultValu
51
51
  /** Maximum list height - defaults to 180 */
52
52
  listMaxHeight?: number;
53
53
  /** Placement of the select list in relation to the input element */
54
- listPlacement?: Side;
54
+ listPlacement?: ListPlacement;
55
55
  /** Use the opposite list placement if the set placement does not fit */
56
56
  flipEnabled?: boolean;
57
57
  /** Set this prop to enable a virtualised list of options. If it is not used then all options will be in the
@@ -67,6 +67,8 @@ export interface SimpleSelectProps extends Omit<FormInputPropTypes, "defaultValu
67
67
  isRequired?: boolean;
68
68
  /** Specify a callback triggered on change */
69
69
  onChange?: (ev: CustomSelectChangeEvent | React.ChangeEvent<HTMLInputElement>) => void;
70
+ /** Override the default width of the list element. Number passed is converted into pixel value */
71
+ listWidth?: number;
70
72
  }
71
73
  export declare const SimpleSelect: React.ForwardRefExoticComponent<SimpleSelectProps & React.RefAttributes<HTMLInputElement>>;
72
74
  export default SimpleSelect;
@@ -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);
@@ -381,12 +382,12 @@ const SelectList = /*#__PURE__*/_react.default.forwardRef(({
381
382
  elements
382
383
  }) {
383
384
  Object.assign(elements.floating.style, {
384
- width: `${rects.reference.width}px`
385
+ width: `${listWidth ?? rects.reference.width}px`
385
386
  });
386
387
  }
387
388
  }), ...(flipEnabled ? [(0, _dom.flip)({
388
389
  fallbackStrategy: "initialPlacement"
389
- })] : [])], [flipEnabled]);
390
+ })] : [])], [listWidth, flipEnabled]);
390
391
  const loader = isLoading ? /*#__PURE__*/_react.default.createElement(_selectList.StyledSelectLoaderContainer, {
391
392
  key: "loader"
392
393
  }, /*#__PURE__*/_react.default.createElement(_loader.default, null)) : undefined;
@@ -467,7 +468,8 @@ if (process.env.NODE_ENV !== "production") {
467
468
  "labelId": _propTypes.default.string,
468
469
  "listActionButton": _propTypes.default.node,
469
470
  "listMaxHeight": _propTypes.default.number,
470
- "listPlacement": _propTypes.default.oneOf(["bottom", "left", "right", "top"]),
471
+ "listPlacement": _propTypes.default.oneOf(["bottom-end", "bottom-start", "bottom", "top-end", "top-start", "top"]),
472
+ "listWidth": _propTypes.default.number,
471
473
  "multiColumn": _propTypes.default.bool,
472
474
  "multiselectValues": _propTypes.default.arrayOf(_propTypes.default.string),
473
475
  "onListAction": _propTypes.default.func,
@@ -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,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
  export interface OptionData {
5
5
  text?: string;
6
6
  value?: string | Record<string, unknown>;
@@ -51,7 +51,7 @@ export interface SimpleSelectProps extends Omit<FormInputPropTypes, "defaultValu
51
51
  /** Maximum list height - defaults to 180 */
52
52
  listMaxHeight?: number;
53
53
  /** Placement of the select list in relation to the input element */
54
- listPlacement?: Side;
54
+ listPlacement?: ListPlacement;
55
55
  /** Use the opposite list placement if the set placement does not fit */
56
56
  flipEnabled?: boolean;
57
57
  /** Set this prop to enable a virtualised list of options. If it is not used then all options will be in the
@@ -67,6 +67,8 @@ export interface SimpleSelectProps extends Omit<FormInputPropTypes, "defaultValu
67
67
  isRequired?: boolean;
68
68
  /** Specify a callback triggered on change */
69
69
  onChange?: (ev: CustomSelectChangeEvent | React.ChangeEvent<HTMLInputElement>) => void;
70
+ /** Override the default width of the list element. Number passed is converted into pixel value */
71
+ listWidth?: number;
70
72
  }
71
73
  export declare const SimpleSelect: React.ForwardRefExoticComponent<SimpleSelectProps & React.RefAttributes<HTMLInputElement>>;
72
74
  export default SimpleSelect;
@@ -57,12 +57,13 @@ const SimpleSelect = exports.SimpleSelect = /*#__PURE__*/_react.default.forwardR
57
57
  virtualScrollOverscan,
58
58
  isOptional,
59
59
  required,
60
+ listWidth,
60
61
  ...props
61
62
  }, ref) => {
62
63
  const selectListId = (0, _react.useRef)((0, _guid.default)());
63
64
  const containerRef = (0, _react.useRef)(null);
64
65
  const listboxRef = (0, _react.useRef)(null);
65
- const filterTimer = (0, _react.useRef)();
66
+ const filterTimer = (0, _react.useRef)(undefined);
66
67
  const isMouseDownReported = (0, _react.useRef)();
67
68
  const isControlled = (0, _react.useRef)(value !== undefined);
68
69
  const isTimerCounting = (0, _react.useRef)();
@@ -80,7 +81,7 @@ const SimpleSelect = exports.SimpleSelect = /*#__PURE__*/_react.default.forwardR
80
81
  id: inputId.current,
81
82
  label
82
83
  });
83
- const focusTimer = (0, _react.useRef)(null);
84
+ const focusTimer = (0, _react.useRef)(undefined);
84
85
  const componentIsUncontrolled = !isControlled || !onChange && defaultValue;
85
86
  if (!deprecateUncontrolledWarnTriggered && componentIsUncontrolled) {
86
87
  deprecateUncontrolledWarnTriggered = true;
@@ -109,9 +110,7 @@ const SimpleSelect = exports.SimpleSelect = /*#__PURE__*/_react.default.forwardR
109
110
  if (!match) {
110
111
  return previousValue;
111
112
  }
112
- if (onChange) {
113
- onChange(createCustomEvent(match.props.value));
114
- }
113
+ onChange?.(createCustomEvent(match.props.value));
115
114
  if (isControlled.current) {
116
115
  return previousValue;
117
116
  }
@@ -124,14 +123,14 @@ const SimpleSelect = exports.SimpleSelect = /*#__PURE__*/_react.default.forwardR
124
123
  const newVal = filterText.current + newCharacter;
125
124
  filterText.current = newVal;
126
125
  selectValueStartingWithText(newVal);
127
- clearTimeout(filterTimer.current);
126
+ window.clearTimeout(filterTimer.current);
128
127
  } else {
129
128
  filterText.current = newCharacter;
130
129
  selectValueStartingWithText(newCharacter);
131
130
  }
132
131
  isTimerCounting.current = true;
133
- clearTimeout(filterTimer.current);
134
- filterTimer.current = setTimeout(() => {
132
+ window.clearTimeout(filterTimer.current);
133
+ filterTimer.current = window.setTimeout(() => {
135
134
  isTimerCounting.current = false;
136
135
  filterText.current = "";
137
136
  }, 500);
@@ -140,18 +139,12 @@ const SimpleSelect = exports.SimpleSelect = /*#__PURE__*/_react.default.forwardR
140
139
  const {
141
140
  key
142
141
  } = event;
143
- if (onKeyDown) {
144
- onKeyDown(event);
145
- }
146
- if (readOnly) {
147
- return;
148
- }
142
+ onKeyDown?.(event);
143
+ if (readOnly) return;
149
144
  if (key === " " || (0, _isNavigationKey.default)(key)) {
150
145
  event.preventDefault();
151
146
  setOpenState(isAlreadyOpen => {
152
- if (!isAlreadyOpen && onOpen) {
153
- onOpen();
154
- }
147
+ if (!isAlreadyOpen) onOpen?.();
155
148
  return true;
156
149
  });
157
150
  } else if (key.length === 1 && !event.metaKey && !event.ctrlKey) {
@@ -193,21 +186,18 @@ const SimpleSelect = exports.SimpleSelect = /*#__PURE__*/_react.default.forwardR
193
186
  }, [handleGlobalClick]);
194
187
  (0, _react.useEffect)(() => {
195
188
  return function cleanup() {
196
- clearTimeout(filterTimer.current);
189
+ window.clearTimeout(filterTimer.current);
190
+ window.clearTimeout(focusTimer.current);
197
191
  };
198
192
  }, []);
199
193
  function handleTextboxClick(event) {
200
194
  isMouseDownReported.current = false;
201
- if (onClick) {
202
- onClick(event);
203
- }
195
+ onClick?.(event);
204
196
  setOpenState(isAlreadyOpen => {
205
197
  if (isAlreadyOpen) {
206
198
  return false;
207
199
  }
208
- if (onOpen) {
209
- onOpen();
210
- }
200
+ onOpen?.();
211
201
  return true;
212
202
  });
213
203
  }
@@ -221,9 +211,7 @@ const SimpleSelect = exports.SimpleSelect = /*#__PURE__*/_react.default.forwardR
221
211
  if (isMouseDownReported.current) {
222
212
  return;
223
213
  }
224
- if (onBlur) {
225
- onBlur(event);
226
- }
214
+ onBlur?.(event);
227
215
  }
228
216
  function handleTextboxMouseDown() {
229
217
  isMouseDownReported.current = true;
@@ -232,28 +220,22 @@ const SimpleSelect = exports.SimpleSelect = /*#__PURE__*/_react.default.forwardR
232
220
  if (isClickTriggeredBySelect.current) {
233
221
  return;
234
222
  }
235
- if (onFocus) {
236
- onFocus(event);
237
- }
223
+ onFocus?.(event);
238
224
  if (isMouseDownReported.current) {
239
225
  isMouseDownReported.current = false;
240
226
  return;
241
227
  }
242
228
  if (openOnFocus) {
243
- if (focusTimer.current) {
244
- clearTimeout(focusTimer.current);
245
- }
229
+ window.clearTimeout(focusTimer.current);
246
230
 
247
231
  // we need to use a timeout here as there is a race condition when rendered in a modal
248
232
  // whereby the select list isn't visible when the select is auto focused straight away
249
- focusTimer.current = setTimeout(() => {
233
+ focusTimer.current = window.setTimeout(() => {
250
234
  setOpenState(isAlreadyOpen => {
251
235
  if (isAlreadyOpen) {
252
236
  return true;
253
237
  }
254
- if (onOpen) {
255
- onOpen();
256
- }
238
+ onOpen?.();
257
239
  return true;
258
240
  });
259
241
  });
@@ -264,9 +246,7 @@ const SimpleSelect = exports.SimpleSelect = /*#__PURE__*/_react.default.forwardR
264
246
  setSelectedValue(newValue);
265
247
  setTextValue(text);
266
248
  }
267
- if (onChange) {
268
- onChange(createCustomEvent(newValue, selectionConfirmed));
269
- }
249
+ onChange?.(createCustomEvent(newValue, selectionConfirmed));
270
250
  }
271
251
  function onSelectOption(optionData) {
272
252
  const {
@@ -323,6 +303,17 @@ const SimpleSelect = exports.SimpleSelect = /*#__PURE__*/_react.default.forwardR
323
303
  ...(0, _utils.filterOutStyledSystemSpacingProps)(props)
324
304
  };
325
305
  }
306
+ let placement;
307
+ switch (listPlacement) {
308
+ case "top":
309
+ placement = "top-end";
310
+ break;
311
+ case "bottom":
312
+ placement = "bottom-end";
313
+ break;
314
+ default:
315
+ placement = listPlacement;
316
+ }
326
317
  const selectList = /*#__PURE__*/_react.default.createElement(_selectList.default, {
327
318
  ref: listboxRef,
328
319
  id: selectListId.current,
@@ -337,11 +328,12 @@ const SimpleSelect = exports.SimpleSelect = /*#__PURE__*/_react.default.forwardR
337
328
  onListScrollBottom: onListScrollBottom,
338
329
  tableHeader: tableHeader,
339
330
  multiColumn: multiColumn,
340
- listPlacement: listPlacement,
331
+ listPlacement: listWidth !== undefined ? placement : listPlacement,
341
332
  flipEnabled: flipEnabled,
342
333
  isOpen: isOpen,
343
334
  enableVirtualScroll: enableVirtualScroll,
344
- virtualScrollOverscan: virtualScrollOverscan
335
+ virtualScrollOverscan: virtualScrollOverscan,
336
+ listWidth: listWidth
345
337
  }, children);
346
338
  const marginProps = (0, _useFormSpacing.default)(props);
347
339
  return /*#__PURE__*/_react.default.createElement(_select.default, _extends({
@@ -495,7 +487,8 @@ if (process.env.NODE_ENV !== "production") {
495
487
  "leftChildren": _propTypes.default.node,
496
488
  "list": _propTypes.default.string,
497
489
  "listMaxHeight": _propTypes.default.number,
498
- "listPlacement": _propTypes.default.oneOf(["bottom", "left", "right", "top"]),
490
+ "listPlacement": _propTypes.default.oneOf(["bottom-end", "bottom-start", "bottom", "top-end", "top-start", "top"]),
491
+ "listWidth": _propTypes.default.number,
499
492
  "m": _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.oneOf([null]), _propTypes.default.number, _propTypes.default.shape({
500
493
  "__@toStringTag": _propTypes.default.string.isRequired,
501
494
  "description": _propTypes.default.string,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "carbon-react",
3
- "version": "142.13.5",
3
+ "version": "143.0.0",
4
4
  "description": "A library of reusable React components for easily building user interfaces.",
5
5
  "files": [
6
6
  "lib",