@carbon/react 1.70.0 → 1.71.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 (160) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +972 -947
  2. package/es/components/AILabel/index.js +15 -15
  3. package/es/components/Checkbox/Checkbox.d.ts +5 -0
  4. package/es/components/Checkbox/Checkbox.js +16 -7
  5. package/es/components/CheckboxGroup/CheckboxGroup.d.ts +5 -0
  6. package/es/components/CheckboxGroup/CheckboxGroup.js +16 -7
  7. package/es/components/CodeSnippet/CodeSnippet.d.ts +5 -2
  8. package/es/components/CodeSnippet/CodeSnippet.js +40 -1
  9. package/es/components/ComboBox/ComboBox.d.ts +1 -1
  10. package/es/components/ComboBox/ComboBox.js +19 -22
  11. package/es/components/ComboButton/index.js +40 -1
  12. package/es/components/ComposedModal/ComposedModal.d.ts +5 -0
  13. package/es/components/ComposedModal/ComposedModal.js +16 -10
  14. package/es/components/ContentSwitcher/ContentSwitcher.d.ts +2 -2
  15. package/es/components/ContentSwitcher/ContentSwitcher.js +1 -1
  16. package/es/components/Copy/Copy.d.ts +5 -2
  17. package/es/components/Copy/Copy.js +40 -1
  18. package/es/components/CopyButton/CopyButton.d.ts +5 -2
  19. package/es/components/CopyButton/CopyButton.js +40 -1
  20. package/es/components/DataTable/TableSelectRow.js +14 -6
  21. package/es/components/DataTable/TableToolbarSearch.js +1 -1
  22. package/es/components/DataTable/stories/examples/TableToolbarFilter.d.ts +1 -1
  23. package/es/components/DatePicker/plugins/fixEventsPlugin.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/FluidNumberInput/FluidNumberInput.d.ts +4 -0
  30. package/es/components/FluidSelect/FluidSelect.d.ts +4 -0
  31. package/es/components/FluidSelect/FluidSelect.js +5 -1
  32. package/es/components/FluidTextArea/FluidTextArea.d.ts +4 -0
  33. package/es/components/FluidTextArea/FluidTextArea.js +5 -1
  34. package/es/components/FluidTextInput/FluidPasswordInput.d.ts +4 -0
  35. package/es/components/FluidTextInput/FluidPasswordInput.js +5 -1
  36. package/es/components/FluidTextInput/FluidTextInput.d.ts +4 -0
  37. package/es/components/FluidTextInput/FluidTextInput.js +5 -1
  38. package/es/components/FluidTimePicker/FluidTimePicker.d.ts +4 -0
  39. package/es/components/FluidTimePicker/FluidTimePicker.js +23 -7
  40. package/es/components/IconButton/index.d.ts +4 -1
  41. package/es/components/IconButton/index.js +40 -1
  42. package/es/components/InlineCheckbox/InlineCheckbox.d.ts +50 -0
  43. package/es/components/InlineCheckbox/InlineCheckbox.js +3 -6
  44. package/es/components/InlineCheckbox/index.d.ts +9 -0
  45. package/es/components/LayoutDirection/LayoutDirection.d.ts +44 -0
  46. package/es/components/LayoutDirection/LayoutDirectionContext.d.ts +10 -0
  47. package/es/components/LayoutDirection/useLayoutDirection.d.ts +12 -0
  48. package/es/components/Menu/MenuItem.js +0 -3
  49. package/es/components/Modal/Modal.d.ts +5 -0
  50. package/es/components/Modal/Modal.js +16 -10
  51. package/es/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
  52. package/es/components/MultiSelect/FilterableMultiSelect.js +1 -2
  53. package/es/components/MultiSelect/MultiSelect.js +1 -1
  54. package/es/components/Notification/Notification.d.ts +9 -2
  55. package/es/components/Notification/Notification.js +16 -2
  56. package/es/components/NumberInput/NumberInput.d.ts +5 -0
  57. package/es/components/NumberInput/NumberInput.js +17 -9
  58. package/es/components/OverflowMenu/next/index.js +40 -1
  59. package/es/components/Pagination/Pagination.js +1 -1
  60. package/es/components/PaginationNav/PaginationNav.d.ts +1 -1
  61. package/es/components/PaginationNav/PaginationNav.js +22 -5
  62. package/es/components/RadioButton/RadioButton.d.ts +5 -0
  63. package/es/components/RadioButton/RadioButton.js +16 -7
  64. package/es/components/RadioButtonGroup/RadioButtonGroup.d.ts +5 -0
  65. package/es/components/RadioButtonGroup/RadioButtonGroup.js +16 -7
  66. package/es/components/RadioTile/RadioTile.d.ts +5 -0
  67. package/es/components/RadioTile/RadioTile.js +17 -8
  68. package/es/components/Tabs/Tabs.js +46 -29
  69. package/es/components/Tag/DismissibleTag.d.ts +11 -2
  70. package/es/components/Tag/DismissibleTag.js +13 -5
  71. package/es/components/Tag/Tag.d.ts +5 -0
  72. package/es/components/Tag/Tag.js +14 -7
  73. package/es/components/TextArea/TextArea.d.ts +5 -0
  74. package/es/components/TextArea/TextArea.js +15 -7
  75. package/es/components/TextInput/TextInput.d.ts +5 -0
  76. package/es/components/TextInput/TextInput.js +15 -7
  77. package/es/components/Tile/Tile.d.ts +21 -1
  78. package/es/components/Tile/Tile.js +68 -48
  79. package/es/components/UIShell/SideNavMenuItem.d.ts +5 -1
  80. package/es/components/UIShell/SideNavMenuItem.js +7 -2
  81. package/lib/components/AILabel/index.js +15 -15
  82. package/lib/components/Checkbox/Checkbox.d.ts +5 -0
  83. package/lib/components/Checkbox/Checkbox.js +16 -7
  84. package/lib/components/CheckboxGroup/CheckboxGroup.d.ts +5 -0
  85. package/lib/components/CheckboxGroup/CheckboxGroup.js +16 -7
  86. package/lib/components/CodeSnippet/CodeSnippet.d.ts +5 -2
  87. package/lib/components/CodeSnippet/CodeSnippet.js +40 -1
  88. package/lib/components/ComboBox/ComboBox.d.ts +1 -1
  89. package/lib/components/ComboBox/ComboBox.js +19 -22
  90. package/lib/components/ComboButton/index.js +40 -1
  91. package/lib/components/ComposedModal/ComposedModal.d.ts +5 -0
  92. package/lib/components/ComposedModal/ComposedModal.js +16 -10
  93. package/lib/components/ContentSwitcher/ContentSwitcher.d.ts +2 -2
  94. package/lib/components/ContentSwitcher/ContentSwitcher.js +1 -1
  95. package/lib/components/Copy/Copy.d.ts +5 -2
  96. package/lib/components/Copy/Copy.js +40 -1
  97. package/lib/components/CopyButton/CopyButton.d.ts +5 -2
  98. package/lib/components/CopyButton/CopyButton.js +40 -1
  99. package/lib/components/DataTable/TableSelectRow.js +14 -6
  100. package/lib/components/DataTable/TableToolbarSearch.js +1 -1
  101. package/lib/components/DataTable/stories/examples/TableToolbarFilter.d.ts +1 -1
  102. package/lib/components/DatePicker/plugins/fixEventsPlugin.js +2 -2
  103. package/lib/components/DatePickerInput/DatePickerInput.d.ts +6 -1
  104. package/lib/components/DatePickerInput/DatePickerInput.js +16 -10
  105. package/lib/components/Dropdown/Dropdown.d.ts +5 -0
  106. package/lib/components/Dropdown/Dropdown.js +131 -91
  107. package/lib/components/FeatureFlags/index.js +1 -2
  108. package/lib/components/FluidNumberInput/FluidNumberInput.d.ts +4 -0
  109. package/lib/components/FluidSelect/FluidSelect.d.ts +4 -0
  110. package/lib/components/FluidSelect/FluidSelect.js +5 -1
  111. package/lib/components/FluidTextArea/FluidTextArea.d.ts +4 -0
  112. package/lib/components/FluidTextArea/FluidTextArea.js +5 -1
  113. package/lib/components/FluidTextInput/FluidPasswordInput.d.ts +4 -0
  114. package/lib/components/FluidTextInput/FluidPasswordInput.js +5 -1
  115. package/lib/components/FluidTextInput/FluidTextInput.d.ts +4 -0
  116. package/lib/components/FluidTextInput/FluidTextInput.js +5 -1
  117. package/lib/components/FluidTimePicker/FluidTimePicker.d.ts +4 -0
  118. package/lib/components/FluidTimePicker/FluidTimePicker.js +23 -7
  119. package/lib/components/IconButton/index.d.ts +4 -1
  120. package/lib/components/IconButton/index.js +40 -1
  121. package/lib/components/InlineCheckbox/InlineCheckbox.d.ts +50 -0
  122. package/lib/components/InlineCheckbox/InlineCheckbox.js +3 -6
  123. package/lib/components/InlineCheckbox/index.d.ts +9 -0
  124. package/lib/components/LayoutDirection/LayoutDirection.d.ts +44 -0
  125. package/lib/components/LayoutDirection/LayoutDirectionContext.d.ts +10 -0
  126. package/lib/components/LayoutDirection/useLayoutDirection.d.ts +12 -0
  127. package/lib/components/Menu/MenuItem.js +0 -3
  128. package/lib/components/Modal/Modal.d.ts +5 -0
  129. package/lib/components/Modal/Modal.js +16 -10
  130. package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
  131. package/lib/components/MultiSelect/FilterableMultiSelect.js +1 -2
  132. package/lib/components/MultiSelect/MultiSelect.js +1 -1
  133. package/lib/components/Notification/Notification.d.ts +9 -2
  134. package/lib/components/Notification/Notification.js +16 -2
  135. package/lib/components/NumberInput/NumberInput.d.ts +5 -0
  136. package/lib/components/NumberInput/NumberInput.js +17 -9
  137. package/lib/components/OverflowMenu/next/index.js +40 -1
  138. package/lib/components/Pagination/Pagination.js +1 -1
  139. package/lib/components/PaginationNav/PaginationNav.d.ts +1 -1
  140. package/lib/components/PaginationNav/PaginationNav.js +22 -5
  141. package/lib/components/RadioButton/RadioButton.d.ts +5 -0
  142. package/lib/components/RadioButton/RadioButton.js +16 -7
  143. package/lib/components/RadioButtonGroup/RadioButtonGroup.d.ts +5 -0
  144. package/lib/components/RadioButtonGroup/RadioButtonGroup.js +16 -7
  145. package/lib/components/RadioTile/RadioTile.d.ts +5 -0
  146. package/lib/components/RadioTile/RadioTile.js +17 -8
  147. package/lib/components/Tabs/Tabs.js +46 -29
  148. package/lib/components/Tag/DismissibleTag.d.ts +11 -2
  149. package/lib/components/Tag/DismissibleTag.js +13 -5
  150. package/lib/components/Tag/Tag.d.ts +5 -0
  151. package/lib/components/Tag/Tag.js +14 -7
  152. package/lib/components/TextArea/TextArea.d.ts +5 -0
  153. package/lib/components/TextArea/TextArea.js +15 -7
  154. package/lib/components/TextInput/TextInput.d.ts +5 -0
  155. package/lib/components/TextInput/TextInput.js +15 -7
  156. package/lib/components/Tile/Tile.d.ts +21 -1
  157. package/lib/components/Tile/Tile.js +67 -47
  158. package/lib/components/UIShell/SideNavMenuItem.d.ts +5 -1
  159. package/lib/components/UIShell/SideNavMenuItem.js +7 -2
  160. package/package.json +5 -5
@@ -37,6 +37,7 @@ const NumberInput = /*#__PURE__*/React__default.forwardRef(function NumberInput(
37
37
  const {
38
38
  allowEmpty = false,
39
39
  className: customClassName,
40
+ decorator,
40
41
  disabled = false,
41
42
  disableWheel: disableWheelProp = false,
42
43
  defaultValue = 0,
@@ -112,7 +113,8 @@ const NumberInput = /*#__PURE__*/React__default.forwardRef(function NumberInput(
112
113
  const [incrementNumLabel, decrementNumLabel] = [t('increment.number'), t('decrement.number')];
113
114
  const wrapperClasses = cx(`${prefix}--number__input-wrapper`, {
114
115
  [`${prefix}--number__input-wrapper--warning`]: normalizedProps.warn,
115
- [`${prefix}--number__input-wrapper--slug`]: slug
116
+ [`${prefix}--number__input-wrapper--slug`]: slug,
117
+ [`${prefix}--number__input-wrapper--decorator`]: decorator
116
118
  });
117
119
  const iconClasses = cx({
118
120
  [`${prefix}--number__invalid`]: normalizedProps.invalid || normalizedProps.warn,
@@ -186,18 +188,18 @@ const NumberInput = /*#__PURE__*/React__default.forwardRef(function NumberInput(
186
188
  }
187
189
  }
188
190
 
189
- // Slug is always size `mini`
190
- let normalizedSlug;
191
- if (slug && slug['type']?.displayName === 'AILabel') {
192
- normalizedSlug = /*#__PURE__*/React__default.cloneElement(slug, {
191
+ // AILabel always size `mini`
192
+ let normalizedDecorator = /*#__PURE__*/React__default.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
193
+ if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
194
+ normalizedDecorator = /*#__PURE__*/React__default.cloneElement(normalizedDecorator, {
193
195
  size: 'mini'
194
196
  });
195
197
  }
196
198
 
197
199
  // Need to update the internal value when the revert button is clicked
198
200
  let isRevertActive;
199
- if (slug && slug['type']?.displayName === 'AILabel') {
200
- isRevertActive = normalizedSlug.props.revertActive;
201
+ if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
202
+ isRevertActive = normalizedDecorator.props.revertActive;
201
203
  }
202
204
  useEffect(() => {
203
205
  if (!isRevertActive && slug && defaultValue) {
@@ -252,7 +254,9 @@ const NumberInput = /*#__PURE__*/React__default.forwardRef(function NumberInput(
252
254
  step: step,
253
255
  type: "number",
254
256
  value: value
255
- })), normalizedSlug, Icon ? /*#__PURE__*/React__default.createElement(Icon, {
257
+ })), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React__default.createElement("div", {
258
+ className: `${prefix}--number__input-inner-wrapper--decorator`
259
+ }, normalizedDecorator) : '', Icon ? /*#__PURE__*/React__default.createElement(Icon, {
256
260
  className: iconClasses
257
261
  }) : null, !hideSteppers && /*#__PURE__*/React__default.createElement("div", {
258
262
  className: `${prefix}--number__controls`
@@ -297,6 +301,10 @@ NumberInput.propTypes = {
297
301
  * Specify an optional className to be applied to the wrapper node
298
302
  */
299
303
  className: PropTypes.string,
304
+ /**
305
+ * **Experimental**: Provide a `decorator` component to be rendered inside the `NumberInput` component
306
+ */
307
+ decorator: PropTypes.node,
300
308
  /**
301
309
  * Optional starting value for uncontrolled state
302
310
  */
@@ -379,7 +387,7 @@ NumberInput.propTypes = {
379
387
  /**
380
388
  * **Experimental**: Provide a `Slug` component to be rendered inside the `NumberInput` component
381
389
  */
382
- slug: PropTypes.node,
390
+ slug: deprecate(PropTypes.node, 'The `slug` prop for `NumberInput` is no longer needed and has ' + 'been deprecated in v11 in favor of the new `decorator` prop. It will be moved in the next major release.'),
383
391
  /**
384
392
  * Specify how much the values should increase/decrease upon clicking on up/down button
385
393
  */
@@ -19,8 +19,22 @@ import mergeRefs from '../../../tools/mergeRefs.js';
19
19
  import { useId } from '../../../internal/useId.js';
20
20
  import { usePrefix } from '../../../internal/usePrefix.js';
21
21
  import { useAttachedMenu } from '../../../internal/useAttachedMenu.js';
22
+ import deprecateValuesWithin from '../../../prop-types/deprecateValuesWithin.js';
22
23
 
23
24
  const defaultSize = 'md';
25
+ const propMappingFunction = deprecatedValue => {
26
+ const mapping = {
27
+ 'top-left': 'top-start',
28
+ 'top-right': 'top-end',
29
+ 'bottom-left': 'bottom-start',
30
+ 'bottom-right': 'bottom-end',
31
+ 'left-bottom': 'left-end',
32
+ 'left-top': 'left-start',
33
+ 'right-bottom': 'right-end',
34
+ 'right-top': 'right-start'
35
+ };
36
+ return mapping[deprecatedValue];
37
+ };
24
38
  const OverflowMenu = /*#__PURE__*/React__default.forwardRef(function OverflowMenu(_ref, forwardRef) {
25
39
  let {
26
40
  autoAlign = false,
@@ -162,7 +176,32 @@ OverflowMenu.propTypes = {
162
176
  /**
163
177
  * Specify how the trigger tooltip should be aligned.
164
178
  */
165
- tooltipAlignment: PropTypes.oneOf(['top', 'top-left', 'top-right', 'bottom', 'bottom-left', 'bottom-right', 'left', 'right']),
179
+ tooltipAlignment: deprecateValuesWithin(PropTypes.oneOf(['top', 'top-left',
180
+ // deprecated use top-start instead
181
+ 'top-right',
182
+ // deprecated use top-end instead
183
+
184
+ 'bottom', 'bottom-left',
185
+ // deprecated use bottom-start instead
186
+ 'bottom-right',
187
+ // deprecated use bottom-end instead
188
+
189
+ 'left', 'left-bottom',
190
+ // deprecated use left-end instead
191
+ 'left-top',
192
+ // deprecated use left-start instead
193
+
194
+ 'right', 'right-bottom',
195
+ // deprecated use right-end instead
196
+ 'right-top',
197
+ // deprecated use right-start instead
198
+
199
+ // new values to match floating-ui
200
+ 'top-start', 'top-end', 'bottom-start', 'bottom-end', 'left-end', 'left-start', 'right-end', 'right-start']),
201
+ //allowed prop values
202
+ ['top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end'],
203
+ //optional mapper function
204
+ propMappingFunction),
166
205
  /**
167
206
  * Specify a DOM node where the Menu should be rendered in. Defaults to document.body.
168
207
  */
@@ -245,7 +245,7 @@ const Pagination = /*#__PURE__*/React__default.forwardRef(function Pagination(_r
245
245
  onClick: decrementPage,
246
246
  ref: backBtnRef
247
247
  }, _CaretLeft || (_CaretLeft = /*#__PURE__*/React__default.createElement(CaretLeft, null))), /*#__PURE__*/React__default.createElement(IconButton, {
248
- align: "top-right",
248
+ align: "top-end",
249
249
  disabled: forwardButtonDisabled || isLastPage,
250
250
  kind: "ghost",
251
251
  className: forwardButtonClasses,
@@ -28,7 +28,7 @@ interface PaginationNavProps extends Omit<React.HTMLAttributes<HTMLElement>, 'on
28
28
  */
29
29
  disableOverflow?: boolean;
30
30
  /**
31
- * The number of items to be shown.
31
+ * The number of items to be shown (minimum of 4 unless props.items < 4).
32
32
  */
33
33
  itemsShown?: number;
34
34
  /**
@@ -12,6 +12,8 @@ import cx from 'classnames';
12
12
  import { CaretRight, CaretLeft, OverflowMenuHorizontal } from '@carbon/icons-react';
13
13
  import { IconButton } from '../IconButton/index.js';
14
14
  import { usePrefix } from '../../internal/usePrefix.js';
15
+ import { breakpoints } from '@carbon/layout';
16
+ import { useMatchMedia } from '../../internal/useMatchMedia.js';
15
17
 
16
18
  var _CaretRight, _CaretLeft, _option;
17
19
  const translationIds = {
@@ -179,8 +181,22 @@ const PaginationNav = /*#__PURE__*/React__default.forwardRef(function Pagination
179
181
  translateWithId: t = translateWithId,
180
182
  ...rest
181
183
  } = _ref4;
184
+ const smMediaQuery = `(max-width: ${breakpoints.sm.width})`;
185
+ const isSm = useMatchMedia(smMediaQuery);
186
+ let numberOfPages;
187
+ switch (size) {
188
+ case 'md':
189
+ numberOfPages = itemsShown === 4 ? itemsShown : 5;
190
+ break;
191
+ case 'sm':
192
+ numberOfPages = Math.max(4, Math.min(itemsShown, 7));
193
+ break;
194
+ default:
195
+ numberOfPages = 4;
196
+ break;
197
+ }
182
198
  const [currentPage, setCurrentPage] = useState(page);
183
- const [itemsDisplayedOnPage, setItemsDisplayedOnPage] = useState(itemsShown >= 4 ? itemsShown : 4);
199
+ const [itemsDisplayedOnPage, setItemsDisplayedOnPage] = useState(itemsShown >= 4 && !isSm ? itemsShown : numberOfPages);
184
200
  const [cuts, setCuts] = useState(calculateCuts(currentPage, totalItems, itemsDisplayedOnPage));
185
201
  const prevPage = usePrevious(currentPage);
186
202
  const prefix = usePrefix();
@@ -225,9 +241,10 @@ const PaginationNav = /*#__PURE__*/React__default.forwardRef(function Pagination
225
241
 
226
242
  // re-calculate cuts if props.totalItems or props.itemsShown change
227
243
  useEffect(() => {
228
- setItemsDisplayedOnPage(itemsShown >= 4 ? itemsShown : 4);
229
- setCuts(calculateCuts(currentPage, totalItems, itemsShown));
230
- }, [totalItems, itemsShown]); // eslint-disable-line react-hooks/exhaustive-deps
244
+ const itemsToBeShown = itemsShown >= 4 && !isSm ? itemsShown : numberOfPages;
245
+ setItemsDisplayedOnPage(Math.max(itemsToBeShown, 4));
246
+ setCuts(calculateCuts(currentPage, totalItems, Math.max(itemsToBeShown, 4)));
247
+ }, [totalItems, itemsShown, isSm, size]); // eslint-disable-line react-hooks/exhaustive-deps
231
248
 
232
249
  // update cuts if necessary whenever currentPage changes
233
250
  useEffect(() => {
@@ -386,7 +403,7 @@ PaginationNav.propTypes = {
386
403
  // eslint-disable-line react/prop-types
387
404
 
388
405
  /**
389
- * The number of items to be shown.
406
+ * The number of items to be shown (minimum of 4 unless props.items < 4).
390
407
  */
391
408
  itemsShown: PropTypes.number,
392
409
  /**
@@ -15,6 +15,10 @@ export interface RadioButtonProps extends Omit<React.InputHTMLAttributes<HTMLInp
15
15
  * Provide an optional className to be applied to the containing node
16
16
  */
17
17
  className?: string;
18
+ /**
19
+ * **Experimental**: Provide a `decorator` component to be rendered inside the `RadioButton` component
20
+ */
21
+ decorator?: ReactNode;
18
22
  /**
19
23
  * Specify whether the `<RadioButton>` should be checked by default
20
24
  */
@@ -55,6 +59,7 @@ export interface RadioButtonProps extends Omit<React.InputHTMLAttributes<HTMLInp
55
59
  */
56
60
  onClick?: (evt: React.MouseEvent<HTMLInputElement>) => void;
57
61
  /**
62
+ * @deprecated please use decorator instead.
58
63
  * **Experimental**: Provide a `Slug` component to be rendered inside the `RadioButton` component
59
64
  */
60
65
  slug?: ReactNode;
@@ -10,6 +10,7 @@ import PropTypes from 'prop-types';
10
10
  import React__default, { useRef } from 'react';
11
11
  import cx from 'classnames';
12
12
  import '../Text/index.js';
13
+ import deprecate from '../../prop-types/deprecate.js';
13
14
  import { usePrefix } from '../../internal/usePrefix.js';
14
15
  import { useId } from '../../internal/useId.js';
15
16
  import mergeRefs from '../../tools/mergeRefs.js';
@@ -18,6 +19,7 @@ import { Text } from '../Text/Text.js';
18
19
  const RadioButton = /*#__PURE__*/React__default.forwardRef((props, ref) => {
19
20
  const {
20
21
  className,
22
+ decorator,
21
23
  disabled,
22
24
  hideLabel,
23
25
  id,
@@ -41,13 +43,14 @@ const RadioButton = /*#__PURE__*/React__default.forwardRef((props, ref) => {
41
43
  });
42
44
  const wrapperClasses = cx(className, `${prefix}--radio-button-wrapper`, {
43
45
  [`${prefix}--radio-button-wrapper--label-${labelPosition}`]: labelPosition !== 'right',
44
- [`${prefix}--radio-button-wrapper--slug`]: slug
46
+ [`${prefix}--radio-button-wrapper--slug`]: slug,
47
+ [`${prefix}--radio-button-wrapper--decorator`]: decorator
45
48
  });
46
49
  const inputRef = useRef(null);
47
- let normalizedSlug;
48
- if (slug && /*#__PURE__*/React__default.isValidElement(slug)) {
49
- const size = slug.props?.['kind'] === 'inline' ? 'md' : 'mini';
50
- normalizedSlug = /*#__PURE__*/React__default.cloneElement(slug, {
50
+ let normalizedDecorator = /*#__PURE__*/React__default.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
51
+ if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
52
+ const size = normalizedDecorator.props?.['kind'] === 'inline' ? 'md' : 'mini';
53
+ normalizedDecorator = /*#__PURE__*/React__default.cloneElement(normalizedDecorator, {
51
54
  size
52
55
  });
53
56
  }
@@ -70,7 +73,9 @@ const RadioButton = /*#__PURE__*/React__default.forwardRef((props, ref) => {
70
73
  className: `${prefix}--radio-button__appearance`
71
74
  }), labelText && /*#__PURE__*/React__default.createElement(Text, {
72
75
  className: innerLabelClasses
73
- }, labelText, normalizedSlug)));
76
+ }, labelText, slug ? normalizedDecorator : decorator ? /*#__PURE__*/React__default.createElement("div", {
77
+ className: `${prefix}--radio-button-wrapper-inner--decorator`
78
+ }, normalizedDecorator) : '')));
74
79
  });
75
80
  RadioButton.displayName = 'RadioButton';
76
81
  RadioButton.propTypes = {
@@ -82,6 +87,10 @@ RadioButton.propTypes = {
82
87
  * Provide an optional className to be applied to the containing node
83
88
  */
84
89
  className: PropTypes.string,
90
+ /**
91
+ * **Experimental**: Provide a decorator component to be rendered inside the `RadioButton` component
92
+ */
93
+ decorator: PropTypes.node,
85
94
  /**
86
95
  * Specify whether the `<RadioButton>` should be checked by default
87
96
  */
@@ -128,7 +137,7 @@ RadioButton.propTypes = {
128
137
  /**
129
138
  * **Experimental**: Provide a `Slug` component to be rendered inside the `RadioButton` component
130
139
  */
131
- slug: PropTypes.node,
140
+ slug: deprecate(PropTypes.node, 'The `slug` prop has been deprecated and will be removed in the next major version. Use the decorator prop instead.'),
132
141
  /**
133
142
  * Specify the value of the `<RadioButton>`
134
143
  */
@@ -17,6 +17,10 @@ export interface RadioButtonGroupProps extends Omit<React.InputHTMLAttributes<HT
17
17
  * Provide an optional className to be applied to the container node
18
18
  */
19
19
  className?: string;
20
+ /**
21
+ * **Experimental**: Provide a decorator component to be rendered inside the `RadioButtonGroup` component
22
+ */
23
+ decorator?: ReactNode;
20
24
  /**
21
25
  * Specify the `<RadioButton>` to be selected by default
22
26
  */
@@ -64,6 +68,7 @@ export interface RadioButtonGroupProps extends Omit<React.InputHTMLAttributes<HT
64
68
  */
65
69
  readOnly?: boolean;
66
70
  /**
71
+ * @deprecated please use decorator instead.
67
72
  * **Experimental**: Provide a `Slug` component to be rendered inside the `RadioButtonGroup` component
68
73
  */
69
74
  slug?: ReactNode;
@@ -12,6 +12,7 @@ import cx from 'classnames';
12
12
  import { Legend } from '../Text/index.js';
13
13
  import { usePrefix } from '../../internal/usePrefix.js';
14
14
  import { WarningFilled, WarningAltFilled } from '@carbon/icons-react';
15
+ import deprecate from '../../prop-types/deprecate.js';
15
16
  import mergeRefs from '../../tools/mergeRefs.js';
16
17
  import { useId } from '../../internal/useId.js';
17
18
 
@@ -19,6 +20,7 @@ const RadioButtonGroup = /*#__PURE__*/React__default.forwardRef((props, ref) =>
19
20
  const {
20
21
  children,
21
22
  className,
23
+ decorator,
22
24
  defaultSelected,
23
25
  disabled,
24
26
  helperText,
@@ -87,7 +89,8 @@ const RadioButtonGroup = /*#__PURE__*/React__default.forwardRef((props, ref) =>
87
89
  [`${prefix}--radio-button-group--readonly`]: readOnly,
88
90
  [`${prefix}--radio-button-group--invalid`]: !readOnly && invalid,
89
91
  [`${prefix}--radio-button-group--warning`]: showWarning,
90
- [`${prefix}--radio-button-group--slug`]: slug
92
+ [`${prefix}--radio-button-group--slug`]: slug,
93
+ [`${prefix}--radio-button-group--decorator`]: decorator
91
94
  });
92
95
  const helperClasses = cx(`${prefix}--form__helper-text`, {
93
96
  [`${prefix}--form__helper-text--disabled`]: disabled
@@ -99,10 +102,10 @@ const RadioButtonGroup = /*#__PURE__*/React__default.forwardRef((props, ref) =>
99
102
  }, helperText) : null;
100
103
  const divRef = useRef(null);
101
104
 
102
- // Slug is always size `mini`
103
- let normalizedSlug;
104
- if (slug && slug['type']?.displayName === 'AILabel') {
105
- normalizedSlug = /*#__PURE__*/React__default.cloneElement(slug, {
105
+ // AILabel is always size `mini`
106
+ let normalizedDecorator = /*#__PURE__*/React__default.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
107
+ if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
108
+ normalizedDecorator = /*#__PURE__*/React__default.cloneElement(normalizedDecorator, {
106
109
  size: 'mini',
107
110
  kind: 'default'
108
111
  });
@@ -117,7 +120,9 @@ const RadioButtonGroup = /*#__PURE__*/React__default.forwardRef((props, ref) =>
117
120
  "aria-describedby": showHelper && helperText ? helperId : undefined
118
121
  }, rest), legendText && /*#__PURE__*/React__default.createElement(Legend, {
119
122
  className: `${prefix}--label`
120
- }, legendText, normalizedSlug), getRadioButtons()), /*#__PURE__*/React__default.createElement("div", {
123
+ }, legendText, slug ? normalizedDecorator : decorator ? /*#__PURE__*/React__default.createElement("div", {
124
+ className: `${prefix}--radio-button-group-inner--decorator`
125
+ }, normalizedDecorator) : ''), getRadioButtons()), /*#__PURE__*/React__default.createElement("div", {
121
126
  className: `${prefix}--radio-button__validation-msg`
122
127
  }, !readOnly && invalid && /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(WarningFilled, {
123
128
  className: `${prefix}--radio-button__invalid-icon`
@@ -138,6 +143,10 @@ RadioButtonGroup.propTypes = {
138
143
  * Provide an optional className to be applied to the container node
139
144
  */
140
145
  className: PropTypes.string,
146
+ /**
147
+ * **Experimental**: Provide a decorator component to be rendered inside the `RadioButtonGroup` component
148
+ */
149
+ decorator: PropTypes.node,
141
150
  /**
142
151
  * Specify the `<RadioButton>` to be selected by default
143
152
  */
@@ -191,7 +200,7 @@ RadioButtonGroup.propTypes = {
191
200
  /**
192
201
  * **Experimental**: Provide a `Slug` component to be rendered inside the `RadioButtonGroup` component
193
202
  */
194
- slug: PropTypes.node,
203
+ slug: deprecate(PropTypes.node, 'The `slug` prop has been deprecated and will be removed in the next major version. Use the decorator prop instead.'),
195
204
  /**
196
205
  * Specify the value that is currently selected in the group
197
206
  */
@@ -18,6 +18,10 @@ export interface RadioTileProps {
18
18
  * Provide an optional `className` to be applied to the underlying `<label>`.
19
19
  */
20
20
  className?: string;
21
+ /**
22
+ * **Experimental**: Provide a `decorator` component to be rendered inside the `RadioTile` component
23
+ */
24
+ decorator?: React.ReactNode;
21
25
  /**
22
26
  * Specify whether the `RadioTile` should be disabled.
23
27
  */
@@ -48,6 +52,7 @@ export interface RadioTileProps {
48
52
  */
49
53
  onChange?: (value: string | number, name: string | undefined, event: React.ChangeEvent<HTMLInputElement> | React.KeyboardEvent<HTMLInputElement>) => void;
50
54
  /**
55
+ * @deprecated please use `decorator` instead.
51
56
  * **Experimental**: Provide a `Slug` component to be rendered inside the `SelectableTile` component
52
57
  */
53
58
  slug?: React.ReactNode;
@@ -25,6 +25,7 @@ const RadioTile = /*#__PURE__*/React__default.forwardRef(function RadioTile(_ref
25
25
  let {
26
26
  children,
27
27
  className: customClassName,
28
+ decorator,
28
29
  disabled,
29
30
  light,
30
31
  checked,
@@ -45,7 +46,9 @@ const RadioTile = /*#__PURE__*/React__default.forwardRef(function RadioTile(_ref
45
46
  [`${prefix}--tile--light`]: light,
46
47
  [`${prefix}--tile--disabled`]: disabled,
47
48
  [`${prefix}--tile--slug`]: slug,
48
- [`${prefix}--tile--slug-rounded`]: slug && hasRoundedCorners
49
+ [`${prefix}--tile--slug-rounded`]: slug && hasRoundedCorners,
50
+ [`${prefix}--tile--decorator`]: decorator,
51
+ [`${prefix}--tile--decorator-rounded`]: decorator && hasRoundedCorners
49
52
  });
50
53
  const v12TileRadioIcons = useFeatureFlag('enable-v12-tile-radio-icons');
51
54
  function icon() {
@@ -69,10 +72,10 @@ const RadioTile = /*#__PURE__*/React__default.forwardRef(function RadioTile(_ref
69
72
  }
70
73
  }
71
74
 
72
- // Slug is always size `xs`
73
- let normalizedSlug;
74
- if (slug && slug['type']?.displayName === 'AILabel') {
75
- normalizedSlug = /*#__PURE__*/React__default.cloneElement(slug, {
75
+ // AILabel is always size `xs`
76
+ let normalizedDecorator = /*#__PURE__*/React__default.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
77
+ if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
78
+ normalizedDecorator = /*#__PURE__*/React__default.cloneElement(normalizedDecorator, {
76
79
  size: 'xs'
77
80
  });
78
81
  }
@@ -96,7 +99,9 @@ const RadioTile = /*#__PURE__*/React__default.forwardRef(function RadioTile(_ref
96
99
  className: `${prefix}--tile__checkmark`
97
100
  }, icon()), /*#__PURE__*/React__default.createElement(Text, {
98
101
  className: `${prefix}--tile-content`
99
- }, children), normalizedSlug));
102
+ }, children), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React__default.createElement("div", {
103
+ className: `${prefix}--tile--inner-decorator`
104
+ }, normalizedDecorator) : ''));
100
105
  });
101
106
  RadioTile.displayName = 'RadioTile';
102
107
  RadioTile.propTypes = {
@@ -112,6 +117,10 @@ RadioTile.propTypes = {
112
117
  * Provide an optional `className` to be applied to the underlying `<label>`.
113
118
  */
114
119
  className: PropTypes.string,
120
+ /**
121
+ * **Experimental**: Provide a `decorator` component to be rendered inside the `RadioTile` component
122
+ */
123
+ decorator: PropTypes.node,
115
124
  /**
116
125
  * Specify whether the `RadioTile` should be disabled.
117
126
  */
@@ -144,9 +153,9 @@ RadioTile.propTypes = {
144
153
  */
145
154
  required: PropTypes.bool,
146
155
  /**
147
- * **Experimental**: Provide a `Slug` component to be rendered inside the `SelectableTile` component
156
+ * **Experimental**: Provide a `Slug` component to be rendered inside the `RadioTile` component
148
157
  */
149
- slug: PropTypes.node,
158
+ slug: deprecate(PropTypes.node, 'The `slug` prop for `RadioTile` has ' + 'been deprecated in favor of the new `decorator` prop. It will be removed in the next major release.'),
150
159
  /**
151
160
  * Specify the tab index of the underlying `<input>`.
152
161
  */
@@ -346,6 +346,41 @@ function TabList(_ref4) {
346
346
  setActiveIndex(selectedIndex);
347
347
  }
348
348
  }
349
+
350
+ /**
351
+ * Scroll the tab into view if it is not already visible
352
+ * @param tab - The tab to scroll into view
353
+ * @returns {void}
354
+ */
355
+ function scrollTabIntoView(tab) {
356
+ if (!isScrollable || !ref.current) {
357
+ return;
358
+ }
359
+ if (tab) {
360
+ // The width of the "scroll buttons"
361
+ const {
362
+ width: tabWidth
363
+ } = tab.getBoundingClientRect();
364
+
365
+ // The start and end position of the selected tab
366
+ const start = tab.offsetLeft;
367
+ const end = tab.offsetLeft + tabWidth;
368
+
369
+ // The start and end of the visible area for the tabs
370
+ const visibleStart = ref.current.scrollLeft + buttonWidth;
371
+ const visibleEnd = ref.current.scrollLeft + ref.current.clientWidth - buttonWidth;
372
+
373
+ // The beginning of the tab is clipped and not visible
374
+ if (start < visibleStart) {
375
+ setScrollLeft(start - buttonWidth);
376
+ }
377
+
378
+ // The end of the tab is clipped and not visible
379
+ if (end > visibleEnd) {
380
+ setScrollLeft(end + buttonWidth - ref.current.clientWidth);
381
+ }
382
+ }
383
+ }
349
384
  useEffectOnce(() => {
350
385
  const tab = tabs.current[selectedIndex];
351
386
  if (scrollIntoView && tab) {
@@ -377,12 +412,12 @@ function TabList(_ref4) {
377
412
  });
378
413
  useIsomorphicEffect(() => {
379
414
  if (ref.current) {
380
- //adding 1 in calculation for firefox support
415
+ // adding 1 in calculation for firefox support
381
416
  setIsScrollable(ref.current.scrollWidth > ref.current.clientWidth + 1);
382
417
  }
383
418
  function handler() {
384
419
  if (ref.current) {
385
- //adding 1 in calculation for firefox support
420
+ // adding 1 in calculation for firefox support
386
421
  setIsScrollable(ref.current.scrollWidth > ref.current.clientWidth + 1);
387
422
  }
388
423
  }
@@ -400,36 +435,18 @@ function TabList(_ref4) {
400
435
  ref.current.scrollLeft = scrollLeft;
401
436
  }
402
437
  }, [scrollLeft]);
438
+
439
+ // scroll manual tabs when active index changes (focus outline movement)
403
440
  useIsomorphicEffect(() => {
404
- if (!isScrollable || !ref.current) {
405
- return;
406
- }
407
441
  const tab = activation === 'manual' ? tabs.current[activeIndex] : tabs.current[selectedIndex];
408
- if (tab) {
409
- // The width of the "scroll buttons"
410
-
411
- // The start and end position of the selected tab
412
- const {
413
- width: tabWidth
414
- } = tab.getBoundingClientRect();
415
- const start = tab.offsetLeft;
416
- const end = tab.offsetLeft + tabWidth;
417
-
418
- // The start and end of the visible area for the tabs
419
- const visibleStart = ref.current.scrollLeft + buttonWidth;
420
- const visibleEnd = ref.current.scrollLeft + ref.current.clientWidth - buttonWidth;
421
-
422
- // The beginning of the tab is clipped and not visible
423
- if (start < visibleStart) {
424
- setScrollLeft(start - buttonWidth);
425
- }
442
+ scrollTabIntoView(tab);
443
+ }, [activation, activeIndex]);
426
444
 
427
- // The end of the tab is clipped and not visible
428
- if (end > visibleEnd) {
429
- setScrollLeft(end + buttonWidth - ref.current.clientWidth);
430
- }
431
- }
432
- }, [activation, activeIndex, selectedIndex, isScrollable, children]);
445
+ // scroll tabs when selected index changes
446
+ useIsomorphicEffect(() => {
447
+ const tab = tabs.current[selectedIndex];
448
+ scrollTabIntoView(tab);
449
+ }, [selectedIndex, isScrollable, children]);
433
450
  usePressable(previousButton, {
434
451
  onPress(_ref6) {
435
452
  let {
@@ -13,6 +13,10 @@ export interface DismissibleTagBaseProps {
13
13
  * Provide a custom className that is applied to the containing <span>
14
14
  */
15
15
  className?: string;
16
+ /**
17
+ * **Experimental:** Provide a `decorator` component to be rendered inside the `DismissibleTag` component
18
+ */
19
+ decorator?: ReactNode;
16
20
  /**
17
21
  * Specify if the `DismissibleTag` is disabled
18
22
  */
@@ -36,6 +40,7 @@ export interface DismissibleTagBaseProps {
36
40
  */
37
41
  size?: keyof typeof SIZES;
38
42
  /**
43
+ * @deprecated please use `decorator` instead.
39
44
  * **Experimental:** Provide a `Slug` component to be rendered inside the `DismissibleTag` component
40
45
  */
41
46
  slug?: ReactNode;
@@ -58,12 +63,16 @@ export interface DismissibleTagBaseProps {
58
63
  }
59
64
  export type DismissibleTagProps<T extends React.ElementType> = PolymorphicProps<T, DismissibleTagBaseProps>;
60
65
  declare const DismissibleTag: {
61
- <T extends React.ElementType<any, keyof React.JSX.IntrinsicElements>>({ className, disabled, id, renderIcon, title, onClose, slug, size, text, tagTitle, type, ...other }: DismissibleTagProps<T>): import("react/jsx-runtime").JSX.Element;
66
+ <T extends React.ElementType<any, keyof React.JSX.IntrinsicElements>>({ className, decorator, disabled, id, renderIcon, title, onClose, slug, size, text, tagTitle, type, ...other }: DismissibleTagProps<T>): import("react/jsx-runtime").JSX.Element;
62
67
  propTypes: {
63
68
  /**
64
69
  * Provide a custom className that is applied to the containing <span>
65
70
  */
66
71
  className: PropTypes.Requireable<string>;
72
+ /**
73
+ * **Experimental:** Provide a `decorator` component to be rendered inside the `DismissibleTag` component
74
+ */
75
+ decorator: PropTypes.Requireable<PropTypes.ReactNodeLike>;
67
76
  /**
68
77
  * Specify if the `DismissibleTag` is disabled
69
78
  */
@@ -89,7 +98,7 @@ declare const DismissibleTag: {
89
98
  /**
90
99
  * **Experimental:** Provide a `Slug` component to be rendered inside the `DismissibleTag` component
91
100
  */
92
- slug: PropTypes.Requireable<PropTypes.ReactNodeLike>;
101
+ slug: (props: any, propName: any, componentName: any, ...rest: any[]) => any;
93
102
  /**
94
103
  * Provide text to be rendered inside of a the tag.
95
104
  */