@carbon/react 1.70.0-rc.0 → 1.71.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +756 -756
  2. package/es/components/AILabel/index.js +15 -15
  3. package/es/components/CheckboxGroup/CheckboxGroup.js +1 -1
  4. package/es/components/CodeSnippet/CodeSnippet.d.ts +5 -2
  5. package/es/components/CodeSnippet/CodeSnippet.js +40 -1
  6. package/es/components/ComboBox/ComboBox.js +28 -23
  7. package/es/components/ComboButton/index.js +40 -1
  8. package/es/components/ComposedModal/ComposedModal.js +6 -2
  9. package/es/components/ContentSwitcher/ContentSwitcher.d.ts +2 -2
  10. package/es/components/ContentSwitcher/ContentSwitcher.js +1 -1
  11. package/es/components/Copy/Copy.d.ts +5 -2
  12. package/es/components/Copy/Copy.js +40 -1
  13. package/es/components/CopyButton/CopyButton.d.ts +5 -2
  14. package/es/components/CopyButton/CopyButton.js +40 -1
  15. package/es/components/DataTable/Table.d.ts +9 -1
  16. package/es/components/DataTable/Table.js +7 -2
  17. package/es/components/DataTable/TableSelectRow.js +14 -6
  18. package/es/components/DataTable/TableToolbarSearch.js +1 -1
  19. package/es/components/DataTable/stories/examples/TableToolbarFilter.d.ts +1 -1
  20. package/es/components/DatePicker/DatePicker.js +0 -8
  21. package/es/components/DatePicker/plugins/appendToPlugin.js +2 -2
  22. package/es/components/DatePicker/plugins/fixEventsPlugin.js +4 -4
  23. package/es/components/DatePicker/plugins/rangePlugin.js +2 -2
  24. package/es/components/DatePickerInput/DatePickerInput.d.ts +6 -1
  25. package/es/components/DatePickerInput/DatePickerInput.js +16 -10
  26. package/es/components/Dropdown/Dropdown.d.ts +5 -0
  27. package/es/components/Dropdown/Dropdown.js +132 -92
  28. package/es/components/FeatureFlags/index.js +1 -2
  29. package/es/components/IconButton/index.d.ts +4 -1
  30. package/es/components/IconButton/index.js +40 -1
  31. package/es/components/InlineCheckbox/InlineCheckbox.d.ts +50 -0
  32. package/es/components/InlineCheckbox/InlineCheckbox.js +3 -6
  33. package/es/components/InlineCheckbox/index.d.ts +9 -0
  34. package/es/components/LayoutDirection/LayoutDirection.d.ts +44 -0
  35. package/es/components/LayoutDirection/LayoutDirectionContext.d.ts +10 -0
  36. package/es/components/LayoutDirection/useLayoutDirection.d.ts +12 -0
  37. package/es/components/Menu/MenuItem.js +0 -3
  38. package/es/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
  39. package/es/components/MultiSelect/FilterableMultiSelect.js +1 -2
  40. package/es/components/MultiSelect/MultiSelect.js +1 -1
  41. package/es/components/Notification/Notification.d.ts +9 -2
  42. package/es/components/Notification/Notification.js +16 -2
  43. package/es/components/NumberInput/NumberInput.d.ts +5 -0
  44. package/es/components/NumberInput/NumberInput.js +17 -9
  45. package/es/components/OverflowMenu/OverflowMenu.js +1 -1
  46. package/es/components/OverflowMenu/next/index.js +40 -1
  47. package/es/components/Pagination/Pagination.js +2 -2
  48. package/es/components/Pagination/experimental/PageSelector.js +1 -1
  49. package/es/components/PaginationNav/PaginationNav.d.ts +1 -1
  50. package/es/components/PaginationNav/PaginationNav.js +10 -5
  51. package/es/components/Popover/index.js +2 -2
  52. package/es/components/SkeletonText/SkeletonText.js +1 -1
  53. package/es/components/Tabs/Tabs.js +46 -29
  54. package/es/components/TextArea/TextArea.d.ts +5 -0
  55. package/es/components/TextArea/TextArea.js +15 -7
  56. package/es/components/TextInput/TextInput.d.ts +5 -0
  57. package/es/components/TextInput/TextInput.js +15 -7
  58. package/es/components/TreeView/TreeNode.js +1 -1
  59. package/es/components/TreeView/TreeView.js +1 -1
  60. package/es/components/UIShell/HeaderMenu.js +1 -1
  61. package/es/components/UIShell/SideNav.js +1 -1
  62. package/es/components/UIShell/SideNavItems.js +1 -1
  63. package/es/components/UIShell/SideNavMenu.js +1 -1
  64. package/es/components/UIShell/SideNavMenuItem.d.ts +5 -1
  65. package/es/components/UIShell/SideNavMenuItem.js +7 -2
  66. package/es/components/UIShell/Switcher.js +1 -1
  67. package/lib/components/AILabel/index.js +15 -15
  68. package/lib/components/CheckboxGroup/CheckboxGroup.js +1 -1
  69. package/lib/components/CodeSnippet/CodeSnippet.d.ts +5 -2
  70. package/lib/components/CodeSnippet/CodeSnippet.js +40 -1
  71. package/lib/components/ComboBox/ComboBox.js +29 -23
  72. package/lib/components/ComboButton/index.js +40 -1
  73. package/lib/components/ComposedModal/ComposedModal.js +6 -2
  74. package/lib/components/ContentSwitcher/ContentSwitcher.d.ts +2 -2
  75. package/lib/components/ContentSwitcher/ContentSwitcher.js +1 -1
  76. package/lib/components/Copy/Copy.d.ts +5 -2
  77. package/lib/components/Copy/Copy.js +40 -1
  78. package/lib/components/CopyButton/CopyButton.d.ts +5 -2
  79. package/lib/components/CopyButton/CopyButton.js +40 -1
  80. package/lib/components/DataTable/Table.d.ts +9 -1
  81. package/lib/components/DataTable/Table.js +7 -2
  82. package/lib/components/DataTable/TableSelectRow.js +14 -6
  83. package/lib/components/DataTable/TableToolbarSearch.js +1 -1
  84. package/lib/components/DataTable/stories/examples/TableToolbarFilter.d.ts +1 -1
  85. package/lib/components/DatePicker/DatePicker.js +0 -8
  86. package/lib/components/DatePicker/plugins/appendToPlugin.js +2 -2
  87. package/lib/components/DatePicker/plugins/fixEventsPlugin.js +4 -4
  88. package/lib/components/DatePicker/plugins/rangePlugin.js +2 -2
  89. package/lib/components/DatePickerInput/DatePickerInput.d.ts +6 -1
  90. package/lib/components/DatePickerInput/DatePickerInput.js +16 -10
  91. package/lib/components/Dropdown/Dropdown.d.ts +5 -0
  92. package/lib/components/Dropdown/Dropdown.js +131 -91
  93. package/lib/components/FeatureFlags/index.js +1 -2
  94. package/lib/components/IconButton/index.d.ts +4 -1
  95. package/lib/components/IconButton/index.js +40 -1
  96. package/lib/components/InlineCheckbox/InlineCheckbox.d.ts +50 -0
  97. package/lib/components/InlineCheckbox/InlineCheckbox.js +3 -6
  98. package/lib/components/InlineCheckbox/index.d.ts +9 -0
  99. package/lib/components/LayoutDirection/LayoutDirection.d.ts +44 -0
  100. package/lib/components/LayoutDirection/LayoutDirectionContext.d.ts +10 -0
  101. package/lib/components/LayoutDirection/useLayoutDirection.d.ts +12 -0
  102. package/lib/components/Menu/MenuItem.js +0 -3
  103. package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
  104. package/lib/components/MultiSelect/FilterableMultiSelect.js +1 -2
  105. package/lib/components/MultiSelect/MultiSelect.js +1 -1
  106. package/lib/components/Notification/Notification.d.ts +9 -2
  107. package/lib/components/Notification/Notification.js +16 -2
  108. package/lib/components/NumberInput/NumberInput.d.ts +5 -0
  109. package/lib/components/NumberInput/NumberInput.js +17 -9
  110. package/lib/components/OverflowMenu/OverflowMenu.js +1 -1
  111. package/lib/components/OverflowMenu/next/index.js +40 -1
  112. package/lib/components/Pagination/Pagination.js +2 -2
  113. package/lib/components/Pagination/experimental/PageSelector.js +1 -1
  114. package/lib/components/PaginationNav/PaginationNav.d.ts +1 -1
  115. package/lib/components/PaginationNav/PaginationNav.js +10 -5
  116. package/lib/components/Popover/index.js +2 -2
  117. package/lib/components/SkeletonText/SkeletonText.js +1 -1
  118. package/lib/components/Tabs/Tabs.js +46 -29
  119. package/lib/components/TextArea/TextArea.d.ts +5 -0
  120. package/lib/components/TextArea/TextArea.js +15 -7
  121. package/lib/components/TextInput/TextInput.d.ts +5 -0
  122. package/lib/components/TextInput/TextInput.js +15 -7
  123. package/lib/components/TreeView/TreeNode.js +1 -1
  124. package/lib/components/TreeView/TreeView.js +1 -1
  125. package/lib/components/UIShell/HeaderMenu.js +1 -1
  126. package/lib/components/UIShell/SideNav.js +1 -1
  127. package/lib/components/UIShell/SideNavItems.js +1 -1
  128. package/lib/components/UIShell/SideNavMenu.js +1 -1
  129. package/lib/components/UIShell/SideNavMenuItem.d.ts +5 -1
  130. package/lib/components/UIShell/SideNavMenuItem.js +7 -2
  131. package/lib/components/UIShell/Switcher.js +1 -1
  132. package/package.json +5 -5
@@ -13,7 +13,7 @@ interface TableToolbarFilterProps {
13
13
  /**
14
14
  * Provide an optional hook that is called each time the input is updated
15
15
  */
16
- onChange?: (event: '' | ChangeEvent<HTMLInputElement>, value?: string) => void;
16
+ onChange?: (event: '' | ChangeEvent<HTMLInputElement>) => void;
17
17
  /**
18
18
  * Provide an function that is called when the apply button is clicked
19
19
  */
@@ -530,9 +530,6 @@ const DatePicker = /*#__PURE__*/React__default.forwardRef(function DatePicker(_r
530
530
  const closeCalendar = event => {
531
531
  calendarRef.current.close();
532
532
  // Remove focus from endDate calendar input
533
- if (document.activeElement instanceof HTMLElement) {
534
- document.activeElement.blur();
535
- }
536
533
  onCalendarClose(calendarRef.current.selectedDates, '', calendarRef.current, {
537
534
  type: 'clickOutside'
538
535
  });
@@ -558,12 +555,7 @@ const DatePicker = /*#__PURE__*/React__default.forwardRef(function DatePicker(_r
558
555
  if (!calendarRef.current || !startInputField.current) return;
559
556
  const handleKeyDown = event => {
560
557
  if (match(event, Tab) && !event.shiftKey && document.activeElement === endInputField.current && calendarRef.current.isOpen) {
561
- event.preventDefault();
562
558
  calendarRef.current.close();
563
- // Remove focus from endDate calendar input
564
- document.activeElement instanceof HTMLElement &&
565
- // this is to fix the TS warning
566
- document?.activeElement?.blur();
567
559
  onCalendarClose(calendarRef.current.selectedDates, '', calendarRef.current, event);
568
560
  }
569
561
  };
@@ -9,7 +9,7 @@
9
9
  * @param {object} config Plugin configuration.
10
10
  * @returns {Plugin} A Flatpickr plugin to put adjust the position of calendar dropdown.
11
11
  */
12
- var carbonFlatpickrAppendToPlugin = (config => fp => {
12
+ var carbonFlatpickrAppendToPlugin = config => fp => {
13
13
  /**
14
14
  * Adjusts the floating menu position after Flatpicker sets it.
15
15
  */
@@ -51,6 +51,6 @@ var carbonFlatpickrAppendToPlugin = (config => fp => {
51
51
  onReady: register,
52
52
  onPreCalendarPosition: handlePreCalendarPosition
53
53
  };
54
- });
54
+ };
55
55
 
56
56
  export { carbonFlatpickrAppendToPlugin as default };
@@ -12,7 +12,7 @@ import { Enter, ArrowLeft, ArrowRight, ArrowDown } from '../../../internal/keybo
12
12
  * @param {object} config Plugin configuration.
13
13
  * @returns {Plugin} A Flatpickr plugin to fix Flatpickr's behavior of certain events.
14
14
  */
15
- var carbonFlatpickrFixEventsPlugin = (config => fp => {
15
+ var carbonFlatpickrFixEventsPlugin = config => fp => {
16
16
  const {
17
17
  inputFrom,
18
18
  inputTo,
@@ -76,7 +76,7 @@ var carbonFlatpickrFixEventsPlugin = (config => fp => {
76
76
  if (inputTo === target && fp.selectedDates[1]) {
77
77
  // Using getTime() enables the ability to more readily compare the date currently
78
78
  // selected in the calendar and the date currently in the value of the input
79
- const withoutTime = date => date.setHours(0, 0, 0, 0);
79
+ const withoutTime = date => date?.setHours(0, 0, 0, 0);
80
80
  const selectedToDate = withoutTime(new Date(fp.selectedDates[1]));
81
81
  const currentValueToDate = withoutTime(parseDateWithFormat(inputTo.value));
82
82
 
@@ -88,7 +88,7 @@ var carbonFlatpickrFixEventsPlugin = (config => fp => {
88
88
  fp.setDate([inputFrom.value, inputTo && inputTo.value], true, fp.config.dateFormat);
89
89
  }
90
90
  }
91
- const isValidDate = date => date.toString() !== 'Invalid Date';
91
+ const isValidDate = date => date?.toString() !== 'Invalid Date';
92
92
  // save end date in calendar inmediately after it's been written down
93
93
  if (inputTo === target && fp.selectedDates.length === 1 && inputTo.value) {
94
94
  if (isValidDate(parseDateWithFormat(inputTo.value))) {
@@ -150,6 +150,6 @@ var carbonFlatpickrFixEventsPlugin = (config => fp => {
150
150
  onReady: [register, init],
151
151
  onDestroy: [release]
152
152
  };
153
- });
153
+ };
154
154
 
155
155
  export { carbonFlatpickrFixEventsPlugin as default };
@@ -14,7 +14,7 @@ import rangePlugin from 'flatpickr/dist/plugins/rangePlugin';
14
14
  * Workaround for: https://github.com/flatpickr/flatpickr/issues/1944
15
15
  * * A logic to ensure `fp.setDate()` call won't end up with "startDate to endDate" set to the first `<input>`
16
16
  */
17
- var carbonFlatpickrRangePlugin = (config => {
17
+ var carbonFlatpickrRangePlugin = config => {
18
18
  const factory = rangePlugin(Object.assign({
19
19
  position: 'left'
20
20
  }, config));
@@ -49,6 +49,6 @@ var carbonFlatpickrRangePlugin = (config => {
49
49
  onPreCalendarPosition() {}
50
50
  });
51
51
  };
52
- });
52
+ };
53
53
 
54
54
  export { carbonFlatpickrRangePlugin as default };
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import { ReactElementLike, ReactNodeArray } from 'prop-types';
8
- import React from 'react';
8
+ import React, { ReactNode } from 'react';
9
9
  import { ReactAttr } from '../../types/common';
10
10
  type ExcludedAttributes = 'value' | 'onChange' | 'locale' | 'children';
11
11
  export type ReactNodeLike = ReactElementLike | ReactNodeArray | string | number | boolean | null | undefined;
@@ -19,6 +19,10 @@ export interface DatePickerInputProps extends Omit<ReactAttr<HTMLInputElement>,
19
19
  * * `range` - With calendar dropdown and a date range.
20
20
  */
21
21
  datePickerType?: 'simple' | 'single' | 'range';
22
+ /**
23
+ * **Experimental**: Provide a `decorator` component to be rendered inside the `DatePickerInput` component
24
+ */
25
+ decorator?: ReactNode;
22
26
  /**
23
27
  * Specify whether or not the input should be disabled
24
28
  */
@@ -77,6 +81,7 @@ export interface DatePickerInputProps extends Omit<ReactAttr<HTMLInputElement>,
77
81
  */
78
82
  size?: 'sm' | 'md' | 'lg';
79
83
  /**
84
+ * @deprecated please use decorator instead.
80
85
  * **Experimental**: Provide a `Slug` component to be rendered inside the `DatePickerInput` component
81
86
  */
82
87
  slug?: ReactNodeLike;
@@ -14,11 +14,13 @@ import '../FluidForm/FluidForm.js';
14
14
  import { FormContext } from '../FluidForm/FormContext.js';
15
15
  import { useId } from '../../internal/useId.js';
16
16
  import '../Text/index.js';
17
+ import deprecate from '../../prop-types/deprecate.js';
17
18
  import { Text } from '../Text/Text.js';
18
19
 
19
20
  const DatePickerInput = /*#__PURE__*/React__default.forwardRef(function DatePickerInput(props, ref) {
20
21
  const {
21
22
  datePickerType,
23
+ decorator,
22
24
  disabled = false,
23
25
  helperText,
24
26
  hideLabel,
@@ -61,7 +63,8 @@ const DatePickerInput = /*#__PURE__*/React__default.forwardRef(function DatePick
61
63
  const wrapperClasses = cx(`${prefix}--date-picker-input__wrapper`, {
62
64
  [`${prefix}--date-picker-input__wrapper--invalid`]: invalid,
63
65
  [`${prefix}--date-picker-input__wrapper--warn`]: warn,
64
- [`${prefix}--date-picker-input__wrapper--slug`]: slug
66
+ [`${prefix}--date-picker-input__wrapper--slug`]: slug,
67
+ [`${prefix}--date-picker-input__wrapper--decorator`]: decorator
65
68
  });
66
69
  const labelClasses = cx(`${prefix}--label`, {
67
70
  [`${prefix}--visually-hidden`]: hideLabel,
@@ -95,10 +98,10 @@ const DatePickerInput = /*#__PURE__*/React__default.forwardRef(function DatePick
95
98
  }
96
99
  const input = /*#__PURE__*/React__default.createElement("input", inputProps);
97
100
 
98
- // Slug is always size `mini`
99
- let normalizedSlug;
100
- if (slug && slug['type']?.displayName === 'AILabel') {
101
- normalizedSlug = /*#__PURE__*/React__default.cloneElement(slug, {
101
+ // AILabel always size `mini`
102
+ let normalizedDecorator = /*#__PURE__*/React__default.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
103
+ if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
104
+ normalizedDecorator = /*#__PURE__*/React__default.cloneElement(normalizedDecorator, {
102
105
  size: 'mini'
103
106
  });
104
107
  }
@@ -110,7 +113,9 @@ const DatePickerInput = /*#__PURE__*/React__default.forwardRef(function DatePick
110
113
  className: labelClasses
111
114
  }, labelText), /*#__PURE__*/React__default.createElement("div", {
112
115
  className: wrapperClasses
113
- }, /*#__PURE__*/React__default.createElement("span", null, input, normalizedSlug, isFluid && /*#__PURE__*/React__default.createElement(DatePickerIcon, {
116
+ }, /*#__PURE__*/React__default.createElement("span", null, input, slug ? normalizedDecorator : decorator ? /*#__PURE__*/React__default.createElement("div", {
117
+ className: `${prefix}--date-picker-input-inner-wrapper--decorator`
118
+ }, normalizedDecorator) : '', isFluid && /*#__PURE__*/React__default.createElement(DatePickerIcon, {
114
119
  datePickerType: datePickerType
115
120
  }), /*#__PURE__*/React__default.createElement(DatePickerIcon, {
116
121
  datePickerType: datePickerType,
@@ -141,6 +146,10 @@ DatePickerInput.propTypes = {
141
146
  * * `range` - With calendar dropdown and a date range.
142
147
  */
143
148
  datePickerType: PropTypes.oneOf(['simple', 'single', 'range']),
149
+ /**
150
+ * **Experimental**: Provide a decorator component to be rendered inside the `RadioButton` component
151
+ */
152
+ decorator: PropTypes.node,
144
153
  /**
145
154
  * Specify whether or not the input should be disabled
146
155
  */
@@ -204,10 +213,7 @@ DatePickerInput.propTypes = {
204
213
  * Specify the size of the Date Picker Input. Currently supports either `sm`, `md`, or `lg` as an option.
205
214
  */
206
215
  size: PropTypes.oneOf(['sm', 'md', 'lg']),
207
- /**
208
- * **Experimental**: Provide a `Slug` component to be rendered inside the `DatePickerInput` component
209
- */
210
- slug: PropTypes.node,
216
+ slug: deprecate(PropTypes.node, 'The `slug` prop has been deprecated and will be removed in the next major version. Use the decorator prop instead.'),
211
217
  /**
212
218
  * Specify the type of the `<input>`
213
219
  */
@@ -27,6 +27,10 @@ export interface DropdownProps<ItemType> extends Omit<ReactAttr<HTMLDivElement>,
27
27
  * **Experimental**: Will attempt to automatically align the floating element to avoid collisions with the viewport and being clipped by ancestor elements.
28
28
  */
29
29
  autoAlign?: boolean;
30
+ /**
31
+ * **Experimental**: Provide a `decorator` component to be rendered inside the `Dropdown` component
32
+ */
33
+ decorator?: ReactNode;
30
34
  /**
31
35
  * Specify the direction of the dropdown. Can be either top or bottom.
32
36
  */
@@ -120,6 +124,7 @@ export interface DropdownProps<ItemType> extends Omit<ReactAttr<HTMLDivElement>,
120
124
  */
121
125
  size?: ListBoxSize;
122
126
  /**
127
+ * @deprecated please use `decorator` instead.
123
128
  * **Experimental**: Provide a `Slug` component to be rendered inside the `Dropdown` component
124
129
  */
125
130
  slug?: ReactNode;
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
9
- import React__default, { useEffect, useContext, useState, useMemo } from 'react';
9
+ import React__default, { useEffect, useContext, useCallback, useMemo, useState } from 'react';
10
10
  import { useSelect } from 'downshift';
11
11
  import cx from 'classnames';
12
12
  import PropTypes from 'prop-types';
@@ -39,13 +39,50 @@ const defaultItemToString = item => {
39
39
  }
40
40
  return '';
41
41
  };
42
+ /**
43
+ * Custom state reducer for `useSelect` in Downshift, providing control over
44
+ * state changes.
45
+ *
46
+ * This function is called each time `useSelect` updates its internal state or
47
+ * triggers `onStateChange`. It allows for fine-grained control of state
48
+ * updates by modifying or overriding the default changes from Downshift's
49
+ * reducer.
50
+ * https://github.com/downshift-js/downshift/tree/master/src/hooks/useSelect#statereducer
51
+ *
52
+ * @param {Object} state - The current full state of the Downshift component.
53
+ * @param {Object} actionAndChanges - Contains the action type and proposed
54
+ * changes from the default Downshift reducer.
55
+ * @param {Object} actionAndChanges.changes - Suggested state changes.
56
+ * @param {string} actionAndChanges.type - The action type for the state
57
+ * change (e.g., item selection).
58
+ * @returns {Object} - The modified state based on custom logic or default
59
+ * changes if no custom logic applies.
60
+ */
61
+ function stateReducer(state, actionAndChanges) {
62
+ const {
63
+ changes,
64
+ type
65
+ } = actionAndChanges;
66
+ switch (type) {
67
+ case ItemMouseMove:
68
+ case MenuMouseLeave:
69
+ if (changes.highlightedIndex === state.highlightedIndex) {
70
+ // Prevent state update if highlightedIndex hasn't changed
71
+ return state;
72
+ }
73
+ return changes;
74
+ default:
75
+ return changes;
76
+ }
77
+ }
42
78
  const Dropdown = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
43
79
  let {
44
80
  autoAlign = false,
45
81
  className: containerClassName,
82
+ decorator,
46
83
  disabled = false,
47
84
  direction = 'bottom',
48
- items,
85
+ items: itemsProp,
49
86
  label,
50
87
  ['aria-label']: ariaLabel,
51
88
  ariaLabel: deprecatedAriaLabel,
@@ -118,49 +155,47 @@ const Dropdown = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
118
155
  const {
119
156
  isFluid
120
157
  } = useContext(FormContext);
121
- const selectProps = {
158
+ const onSelectedItemChange = useCallback(_ref3 => {
159
+ let {
160
+ selectedItem
161
+ } = _ref3;
162
+ if (onChange) {
163
+ onChange({
164
+ selectedItem: selectedItem ?? null
165
+ });
166
+ }
167
+ }, [onChange]);
168
+ const isItemDisabled = useCallback((item, _index) => {
169
+ const isObject = item !== null && typeof item === 'object';
170
+ return isObject && 'disabled' in item && item.disabled === true;
171
+ }, []);
172
+ const onHighlightedIndexChange = useCallback(changes => {
173
+ const {
174
+ highlightedIndex
175
+ } = changes;
176
+ if (highlightedIndex !== undefined && highlightedIndex > -1 && typeof window !== undefined) {
177
+ const itemArray = document.querySelectorAll(`li.${prefix}--list-box__menu-item[role="option"]`);
178
+ const highlightedItem = itemArray[highlightedIndex];
179
+ if (highlightedItem) {
180
+ highlightedItem.scrollIntoView({
181
+ behavior: 'smooth',
182
+ block: 'nearest'
183
+ });
184
+ }
185
+ }
186
+ }, [prefix]);
187
+ const items = useMemo(() => itemsProp, [itemsProp]);
188
+ const selectProps = useMemo(() => ({
122
189
  items,
123
190
  itemToString,
124
191
  initialSelectedItem,
125
192
  onSelectedItemChange,
126
193
  stateReducer,
127
- isItemDisabled(item, _index) {
128
- const isObject = item !== null && typeof item === 'object';
129
- return isObject && 'disabled' in item && item.disabled === true;
130
- },
131
- onHighlightedIndexChange: _ref3 => {
132
- let {
133
- highlightedIndex
134
- } = _ref3;
135
- if (highlightedIndex > -1 && typeof window !== undefined) {
136
- const itemArray = document.querySelectorAll(`li.${prefix}--list-box__menu-item[role="option"]`);
137
- const highlightedItem = itemArray[highlightedIndex];
138
- if (highlightedItem) {
139
- highlightedItem.scrollIntoView({
140
- behavior: 'smooth',
141
- block: 'nearest'
142
- });
143
- }
144
- }
145
- },
194
+ isItemDisabled,
195
+ onHighlightedIndexChange,
146
196
  ...downshiftProps
147
- };
197
+ }), [items, itemToString, initialSelectedItem, onSelectedItemChange, stateReducer, isItemDisabled, onHighlightedIndexChange, downshiftProps]);
148
198
  const dropdownInstanceId = useId();
149
- function stateReducer(state, actionAndChanges) {
150
- const {
151
- changes,
152
- type
153
- } = actionAndChanges;
154
- switch (type) {
155
- case ItemMouseMove:
156
- case MenuMouseLeave:
157
- return {
158
- ...changes,
159
- highlightedIndex: state.highlightedIndex
160
- };
161
- }
162
- return changes;
163
- }
164
199
 
165
200
  // only set selectedItem if the prop is defined. Setting if it is undefined
166
201
  // will overwrite default selected items from useSelect
@@ -205,80 +240,79 @@ const Dropdown = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
205
240
  [`${prefix}--list-box__wrapper--inline--invalid`]: inline && invalid,
206
241
  [`${prefix}--list-box__wrapper--fluid--invalid`]: isFluid && invalid,
207
242
  [`${prefix}--list-box__wrapper--fluid--focus`]: isFluid && isFocused && !isOpen,
208
- [`${prefix}--list-box__wrapper--slug`]: slug
243
+ [`${prefix}--list-box__wrapper--slug`]: slug,
244
+ [`${prefix}--list-box__wrapper--decorator`]: decorator
209
245
  });
210
246
  const helperId = !helperText ? undefined : `dropdown-helper-text-${dropdownInstanceId}`;
211
247
 
212
248
  // needs to be Capitalized for react to render it correctly
213
249
  const ItemToElement = itemToElement;
214
- const toggleButtonProps = getToggleButtonProps({
250
+ const toggleButtonProps = useMemo(() => getToggleButtonProps({
215
251
  'aria-label': ariaLabel || deprecatedAriaLabel
216
- });
252
+ }), [getToggleButtonProps, ariaLabel, deprecatedAriaLabel, isOpen]);
217
253
  const helper = helperText && !isFluid ? /*#__PURE__*/React__default.createElement("div", {
218
254
  id: helperId,
219
255
  className: helperClasses
220
256
  }, helperText) : null;
221
- function onSelectedItemChange(_ref4) {
222
- let {
223
- selectedItem
224
- } = _ref4;
225
- if (onChange) {
226
- onChange({
227
- selectedItem: selectedItem ?? null
228
- });
229
- }
230
- }
231
257
  const handleFocus = evt => {
232
258
  setIsFocused(evt.type === 'focus' ? true : false);
233
259
  };
234
260
  const mergedRef = mergeRefs(toggleButtonProps.ref, ref);
235
261
  const [currTimer, setCurrTimer] = useState();
236
-
237
- // eslint-disable-next-line prefer-const
238
- let [isTyping, setIsTyping] = useState(false);
239
- const readOnlyEventHandlers = readOnly ? {
240
- onClick: evt => {
241
- // NOTE: does not prevent click
242
- evt.preventDefault();
243
- // focus on the element as per readonly input behavior
244
- mergedRef?.current?.focus();
245
- },
246
- onKeyDown: evt => {
247
- const selectAccessKeys = ['ArrowDown', 'ArrowUp', ' ', 'Enter'];
248
- // This prevents the select from opening for the above keys
249
- if (selectAccessKeys.includes(evt.key)) {
250
- evt.preventDefault();
251
- }
262
+ const [isTyping, setIsTyping] = useState(false);
263
+ const onKeyDownHandler = useCallback(evt => {
264
+ if (evt.code !== 'Space' || !['ArrowDown', 'ArrowUp', ' ', 'Enter'].includes(evt.key)) {
265
+ setIsTyping(true);
252
266
  }
253
- } : {
254
- onKeyDown: evt => {
255
- if (evt.code !== 'Space' || !['ArrowDown', 'ArrowUp', ' ', 'Enter'].includes(evt.key)) {
256
- setIsTyping(true);
267
+ if (isTyping && evt.code === 'Space' || !['ArrowDown', 'ArrowUp', ' ', 'Enter'].includes(evt.key)) {
268
+ if (currTimer) {
269
+ clearTimeout(currTimer);
257
270
  }
258
- if (isTyping && evt.code === 'Space' || !['ArrowDown', 'ArrowUp', ' ', 'Enter'].includes(evt.key)) {
259
- if (currTimer) {
260
- clearTimeout(currTimer);
271
+ setCurrTimer(setTimeout(() => {
272
+ setIsTyping(false);
273
+ }, 3000));
274
+ }
275
+ if (toggleButtonProps.onKeyDown) {
276
+ toggleButtonProps.onKeyDown(evt);
277
+ }
278
+ }, [isTyping, currTimer, toggleButtonProps]);
279
+ const readOnlyEventHandlers = useMemo(() => {
280
+ if (readOnly) {
281
+ return {
282
+ onClick: evt => {
283
+ // NOTE: does not prevent click
284
+ evt.preventDefault();
285
+ // focus on the element as per readonly input behavior
286
+ mergedRef?.current?.focus();
287
+ },
288
+ onKeyDown: evt => {
289
+ const selectAccessKeys = ['ArrowDown', 'ArrowUp', ' ', 'Enter'];
290
+ // This prevents the select from opening for the above keys
291
+ if (selectAccessKeys.includes(evt.key)) {
292
+ evt.preventDefault();
293
+ }
261
294
  }
262
- setCurrTimer(setTimeout(() => {
263
- setIsTyping(false);
264
- }, 3000));
265
- }
266
- if (toggleButtonProps.onKeyDown) {
267
- toggleButtonProps.onKeyDown(evt);
268
- }
295
+ };
296
+ } else {
297
+ return {
298
+ onKeyDown: onKeyDownHandler
299
+ };
269
300
  }
270
- };
301
+ }, [readOnly, onKeyDownHandler]);
271
302
  const menuProps = useMemo(() => getMenuProps({
272
303
  ref: enableFloatingStyles || autoAlign ? refs.setFloating : null
273
- }), [autoAlign, getMenuProps, refs.setFloating]);
304
+ }), [autoAlign, getMenuProps, refs.setFloating, enableFloatingStyles]);
274
305
 
275
- // Slug is always size `mini`
276
- let normalizedSlug;
277
- if (slug && slug['type']?.displayName === 'AILabel') {
278
- normalizedSlug = /*#__PURE__*/React__default.cloneElement(slug, {
279
- size: 'mini'
280
- });
281
- }
306
+ // AILabel is always size `mini`
307
+ const normalizedDecorator = useMemo(() => {
308
+ let element = slug ?? decorator;
309
+ if (element && element['type']?.displayName === 'AILabel') {
310
+ return /*#__PURE__*/React__default.cloneElement(element, {
311
+ size: 'mini'
312
+ });
313
+ }
314
+ return /*#__PURE__*/React__default.isValidElement(element) ? element : null;
315
+ }, [slug, decorator]);
282
316
  return /*#__PURE__*/React__default.createElement("div", _extends({
283
317
  className: wrapperClasses
284
318
  }, other), titleText && /*#__PURE__*/React__default.createElement("label", _extends({
@@ -317,7 +351,9 @@ const Dropdown = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
317
351
  }, selectedItem ? renderSelectedItem ? renderSelectedItem(selectedItem) : itemToString(selectedItem) : label), /*#__PURE__*/React__default.createElement(ListBox.MenuIcon, {
318
352
  isOpen: isOpen,
319
353
  translateWithId: translateWithId
320
- })), normalizedSlug, /*#__PURE__*/React__default.createElement(ListBox.Menu, menuProps, isOpen && items.map((item, index) => {
354
+ })), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React__default.createElement("div", {
355
+ className: `${prefix}--list-box__inner-wrapper--decorator`
356
+ }, normalizedDecorator) : '', /*#__PURE__*/React__default.createElement(ListBox.Menu, menuProps, isOpen && items.map((item, index) => {
321
357
  const isObject = item !== null && typeof item === 'object';
322
358
  const itemProps = getItemProps({
323
359
  item,
@@ -360,6 +396,10 @@ Dropdown.propTypes = {
360
396
  * Provide a custom className to be applied on the cds--dropdown node
361
397
  */
362
398
  className: PropTypes.string,
399
+ /**
400
+ * **Experimental**: Provide a `decorator` component to be rendered inside the `Dropdown` component
401
+ */
402
+ decorator: PropTypes.node,
363
403
  /**
364
404
  * Specify the direction of the dropdown. Can be either top or bottom.
365
405
  */
@@ -453,7 +493,7 @@ Dropdown.propTypes = {
453
493
  /**
454
494
  * **Experimental**: Provide a `Slug` component to be rendered inside the `Dropdown` component
455
495
  */
456
- slug: PropTypes.node,
496
+ slug: deprecate(PropTypes.node, 'The `slug` prop for `Dropdown` has ' + 'been deprecated in favor of the new `decorator` prop. It will be removed in the next major release.'),
457
497
  /**
458
498
  * Provide the title text that will be read by a screen reader when
459
499
  * visiting this control
@@ -120,8 +120,7 @@ function useChangedValue(value, compare, callback) {
120
120
  */
121
121
  function useFeatureFlag(flag) {
122
122
  const scope = useContext(FeatureFlagContext);
123
- //updated to return false for undefined flags
124
- return scope.enabled(flag) ?? false;
123
+ return scope.enabled(flag);
125
124
  }
126
125
 
127
126
  /**
@@ -8,11 +8,14 @@ import React, { ReactNode } from 'react';
8
8
  import { ButtonSize } from '../Button';
9
9
  export declare const IconButtonKinds: readonly ["primary", "secondary", "ghost", "tertiary"];
10
10
  export type IconButtonKind = (typeof IconButtonKinds)[number];
11
+ export type DeprecatedIconButtonAlignment = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'left-bottom' | 'left-top' | 'right-bottom' | 'right-top';
12
+ export type NewIconButtonAlignment = 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'left-end' | 'left-start' | 'right-end' | 'right-start';
13
+ export type IconButtonAlignment = DeprecatedIconButtonAlignment | NewIconButtonAlignment;
11
14
  interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
12
15
  /**
13
16
  * Specify how the trigger should align with the tooltip
14
17
  */
15
- align?: 'top' | 'top-left' | 'top-start' | 'top-right' | 'top-end' | 'bottom' | 'bottom-left' | 'bottom-start' | 'bottom-right' | 'bottom-end' | 'left' | 'right';
18
+ align?: IconButtonAlignment;
16
19
  /**
17
20
  * **Experimental**: Will attempt to automatically align the tooltip
18
21
  */
@@ -13,8 +13,22 @@ import '../Tooltip/DefinitionTooltip.js';
13
13
  import { Tooltip } from '../Tooltip/Tooltip.js';
14
14
  import { usePrefix } from '../../internal/usePrefix.js';
15
15
  import ButtonBase from '../Button/ButtonBase.js';
16
+ import deprecateValuesWithin from '../../prop-types/deprecateValuesWithin.js';
16
17
 
17
18
  const IconButtonKinds = ['primary', 'secondary', 'ghost', 'tertiary'];
19
+ const propMappingFunction = deprecatedValue => {
20
+ const mapping = {
21
+ 'top-left': 'top-start',
22
+ 'top-right': 'top-end',
23
+ 'bottom-left': 'bottom-start',
24
+ 'bottom-right': 'bottom-end',
25
+ 'left-bottom': 'left-end',
26
+ 'left-top': 'left-start',
27
+ 'right-bottom': 'right-end',
28
+ 'right-top': 'right-start'
29
+ };
30
+ return mapping[deprecatedValue];
31
+ };
18
32
  const IconButton = /*#__PURE__*/React__default.forwardRef(function IconButton(_ref, ref) {
19
33
  let {
20
34
  align,
@@ -60,7 +74,32 @@ IconButton.propTypes = {
60
74
  /**
61
75
  * Specify how the trigger should align with the tooltip
62
76
  */
63
- align: PropTypes.oneOf(['top', 'top-left', 'top-start', 'top-right', 'top-end', 'bottom', 'bottom-left', 'bottom-start', 'bottom-right', 'bottom-end', 'left', 'right']),
77
+ align: deprecateValuesWithin(PropTypes.oneOf(['top', 'top-left',
78
+ // deprecated use top-start instead
79
+ 'top-right',
80
+ // deprecated use top-end instead
81
+
82
+ 'bottom', 'bottom-left',
83
+ // deprecated use bottom-start instead
84
+ 'bottom-right',
85
+ // deprecated use bottom-end instead
86
+
87
+ 'left', 'left-bottom',
88
+ // deprecated use left-end instead
89
+ 'left-top',
90
+ // deprecated use left-start instead
91
+
92
+ 'right', 'right-bottom',
93
+ // deprecated use right-end instead
94
+ 'right-top',
95
+ // deprecated use right-start instead
96
+
97
+ // new values to match floating-ui
98
+ 'top-start', 'top-end', 'bottom-start', 'bottom-end', 'left-end', 'left-start', 'right-end', 'right-start']),
99
+ //allowed prop values
100
+ ['top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end'],
101
+ //optional mapper function
102
+ propMappingFunction),
64
103
  /**
65
104
  * **Experimental**: Will attempt to automatically align the tooltip
66
105
  */
@@ -0,0 +1,50 @@
1
+ import React from 'react';
2
+ export interface InlineCheckboxProps {
3
+ 'aria-label': string;
4
+ /**
5
+ * Deprecated, please use `aria-label` instead.
6
+ * Specify the label for the control
7
+ */
8
+ ariaLabel?: string;
9
+ /**
10
+ * Specify whether the underlying control is checked,
11
+ * or not
12
+ * @default false
13
+ * */
14
+ checked?: boolean;
15
+ /**
16
+ * Specify whether the underlying input control should be disabled
17
+ * @default false
18
+ */
19
+ disabled?: boolean;
20
+ /**
21
+ * Provide an `id` for the underlying input control
22
+ */
23
+ id: string;
24
+ /**
25
+ * Specify whether the control is in an indeterminate state
26
+ */
27
+ indeterminate?: boolean;
28
+ /**
29
+ * Provide a `name` for the underlying input control
30
+ */
31
+ name: string;
32
+ /**
33
+ * Provide an optional hook that is called each time the input is updated
34
+ */
35
+ onChange?: (checked: boolean, id: string, event: React.ChangeEvent<HTMLInputElement>) => void;
36
+ /**
37
+ * Provide a handler that is invoked when a user clicks on the control
38
+ */
39
+ onClick?: (event: React.MouseEvent<HTMLInputElement>) => void;
40
+ /**
41
+ * Provide a handler that is invoked on the key down event for the control
42
+ */
43
+ onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
44
+ /**
45
+ * Provide an optional tooltip for the InlineCheckbox
46
+ */
47
+ title?: string;
48
+ }
49
+ declare const InlineCheckbox: React.ForwardRefExoticComponent<InlineCheckboxProps & React.RefAttributes<HTMLInputElement>>;
50
+ export default InlineCheckbox;