@carbon/react 1.43.0-rc.0 → 1.44.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 (82) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +1024 -905
  2. package/es/components/Accordion/AccordionItem.d.ts +1 -1
  3. package/es/components/Accordion/AccordionItem.js +19 -15
  4. package/es/components/Checkbox/Checkbox.d.ts +4 -0
  5. package/es/components/Checkbox/Checkbox.js +15 -2
  6. package/es/components/CheckboxGroup/CheckboxGroup.js +17 -2
  7. package/es/components/ComboBox/ComboBox.js +12 -0
  8. package/es/components/ComboButton/index.js +2 -1
  9. package/es/components/ComposedModal/ComposedModal.d.ts +3 -3
  10. package/es/components/ComposedModal/ComposedModal.js +3 -3
  11. package/es/components/ContextMenu/useContextMenu.js +2 -1
  12. package/es/components/DataTable/tools/sorting.js +1 -1
  13. package/es/components/DataTableSkeleton/DataTableSkeleton.js +1 -1
  14. package/es/components/Dropdown/Dropdown.js +4 -1
  15. package/es/components/FileUploader/FileUploader.js +5 -3
  16. package/es/components/Grid/Column.js +11 -1
  17. package/es/components/Link/Link.d.ts +5 -0
  18. package/es/components/Link/Link.js +9 -2
  19. package/es/components/Menu/Menu.js +14 -0
  20. package/es/components/Menu/MenuContext.js +1 -0
  21. package/es/components/Menu/MenuItem.js +19 -4
  22. package/es/components/MenuButton/index.js +10 -2
  23. package/es/components/RadioButton/RadioButton.d.ts +4 -0
  24. package/es/components/RadioButton/RadioButton.js +15 -2
  25. package/es/components/RadioButtonGroup/RadioButtonGroup.d.ts +4 -0
  26. package/es/components/RadioButtonGroup/RadioButtonGroup.js +17 -2
  27. package/es/components/Select/Select.d.ts +1 -1
  28. package/es/components/Slug/index.js +2 -2
  29. package/es/components/Tile/Tile.d.ts +37 -0
  30. package/es/components/Tile/Tile.js +110 -13
  31. package/es/components/UIShell/Content.d.ts +296 -0
  32. package/es/components/UIShell/Content.js +1 -2
  33. package/es/components/UIShell/SideNav.d.ts +1 -1
  34. package/es/components/UIShell/SideNav.js +1 -1
  35. package/es/components/UIShell/Switcher.d.ts +38 -0
  36. package/es/components/UIShell/Switcher.js +14 -13
  37. package/es/components/UIShell/SwitcherDivider.d.ts +9 -0
  38. package/es/components/UIShell/SwitcherDivider.js +4 -5
  39. package/es/components/UIShell/SwitcherItem.d.ts +49 -0
  40. package/es/components/UIShell/SwitcherItem.js +13 -17
  41. package/es/prop-types/tools/getDisplayName.js +34 -0
  42. package/lib/components/Accordion/AccordionItem.d.ts +1 -1
  43. package/lib/components/Accordion/AccordionItem.js +18 -14
  44. package/lib/components/Checkbox/Checkbox.d.ts +4 -0
  45. package/lib/components/Checkbox/Checkbox.js +15 -2
  46. package/lib/components/CheckboxGroup/CheckboxGroup.js +17 -2
  47. package/lib/components/ComboBox/ComboBox.js +12 -0
  48. package/lib/components/ComboButton/index.js +2 -1
  49. package/lib/components/ComposedModal/ComposedModal.d.ts +3 -3
  50. package/lib/components/ComposedModal/ComposedModal.js +3 -3
  51. package/lib/components/ContextMenu/useContextMenu.js +2 -1
  52. package/lib/components/DataTable/tools/sorting.js +1 -1
  53. package/lib/components/DataTableSkeleton/DataTableSkeleton.js +1 -1
  54. package/lib/components/Dropdown/Dropdown.js +4 -1
  55. package/lib/components/FileUploader/FileUploader.js +5 -3
  56. package/lib/components/Grid/Column.js +11 -1
  57. package/lib/components/Link/Link.d.ts +5 -0
  58. package/lib/components/Link/Link.js +9 -2
  59. package/lib/components/Menu/Menu.js +14 -0
  60. package/lib/components/Menu/MenuContext.js +1 -0
  61. package/lib/components/Menu/MenuItem.js +19 -4
  62. package/lib/components/MenuButton/index.js +10 -2
  63. package/lib/components/RadioButton/RadioButton.d.ts +4 -0
  64. package/lib/components/RadioButton/RadioButton.js +15 -2
  65. package/lib/components/RadioButtonGroup/RadioButtonGroup.d.ts +4 -0
  66. package/lib/components/RadioButtonGroup/RadioButtonGroup.js +17 -2
  67. package/lib/components/Select/Select.d.ts +1 -1
  68. package/lib/components/Slug/index.js +2 -2
  69. package/lib/components/Tile/Tile.d.ts +37 -0
  70. package/lib/components/Tile/Tile.js +110 -13
  71. package/lib/components/UIShell/Content.d.ts +296 -0
  72. package/lib/components/UIShell/Content.js +1 -2
  73. package/lib/components/UIShell/SideNav.d.ts +1 -1
  74. package/lib/components/UIShell/SideNav.js +1 -1
  75. package/lib/components/UIShell/Switcher.d.ts +38 -0
  76. package/lib/components/UIShell/Switcher.js +13 -12
  77. package/lib/components/UIShell/SwitcherDivider.d.ts +9 -0
  78. package/lib/components/UIShell/SwitcherDivider.js +4 -5
  79. package/lib/components/UIShell/SwitcherItem.d.ts +49 -0
  80. package/lib/components/UIShell/SwitcherItem.js +12 -16
  81. package/lib/prop-types/tools/getDisplayName.js +38 -0
  82. package/package.json +5 -5
@@ -47,7 +47,7 @@ interface AccordionItemProps {
47
47
  * The callback function to run on the `onAnimationEnd`
48
48
  * event for the list item.
49
49
  */
50
- handleAnimationEnd?: AnimationEventHandler<HTMLLIElement>;
50
+ handleAnimationEnd?: AnimationEventHandler<HTMLElement>;
51
51
  }
52
52
  interface AccordionToggleProps {
53
53
  'aria-controls'?: AriaAttributes['aria-controls'];
@@ -47,8 +47,6 @@ function AccordionItem(_ref) {
47
47
  ...rest
48
48
  } = _ref;
49
49
  const [isOpen, setIsOpen] = React.useState(open);
50
- const [prevIsOpen, setPrevIsOpen] = React.useState(open);
51
- const [animation, setAnimation] = React.useState('');
52
50
  const accordionState = React.useContext(AccordionProvider.AccordionContext);
53
51
  const disabledIsControlled = typeof controlledDisabled === 'boolean';
54
52
  const disabled = disabledIsControlled ? controlledDisabled : accordionState.disabled;
@@ -57,23 +55,28 @@ function AccordionItem(_ref) {
57
55
  const className = cx__default["default"]({
58
56
  [`${prefix}--accordion__item`]: true,
59
57
  [`${prefix}--accordion__item--active`]: isOpen,
60
- [`${prefix}--accordion__item--${animation}`]: animation,
61
58
  [`${prefix}--accordion__item--disabled`]: disabled,
62
59
  [customClassName]: !!customClassName
63
60
  });
64
61
  const Toggle = renderToggle || renderExpando; // remove renderExpando in next major release
65
62
 
66
- if (open !== prevIsOpen) {
67
- setAnimation(isOpen ? 'collapsing' : 'expanding');
68
- setIsOpen(open);
69
- setPrevIsOpen(open);
70
- }
63
+ const content = React.useRef(null);
71
64
 
72
65
  // When the AccordionItem heading is clicked, toggle the open state of the
73
66
  // panel
74
67
  function onClick(event) {
68
+ // type guard for ref
69
+ if (!content.current) {
70
+ return;
71
+ }
72
+ if (isOpen) {
73
+ // accordion closes
74
+ content.current.style.maxBlockSize = '';
75
+ } else {
76
+ // accordion opens
77
+ content.current.style.maxBlockSize = content.current.scrollHeight + 15 + 'px';
78
+ }
75
79
  const nextValue = !isOpen;
76
- setAnimation(isOpen ? 'collapsing' : 'expanding');
77
80
  setIsOpen(nextValue);
78
81
  if (onHeadingClick) {
79
82
  // TODO: normalize signature, potentially:
@@ -95,13 +98,10 @@ function AccordionItem(_ref) {
95
98
  if (handleAnimationEnd) {
96
99
  handleAnimationEnd(event);
97
100
  }
98
- setAnimation('');
99
101
  }
100
102
  return /*#__PURE__*/React__default["default"].createElement("li", _rollupPluginBabelHelpers["extends"]({
101
103
  className: className
102
- }, rest, {
103
- onAnimationEnd: onAnimationEnd
104
- }), /*#__PURE__*/React__default["default"].createElement(Toggle, {
104
+ }, rest), /*#__PURE__*/React__default["default"].createElement(Toggle, {
105
105
  disabled: disabled,
106
106
  "aria-controls": id,
107
107
  "aria-expanded": isOpen,
@@ -115,9 +115,13 @@ function AccordionItem(_ref) {
115
115
  as: "div",
116
116
  className: `${prefix}--accordion__title`
117
117
  }, title)), /*#__PURE__*/React__default["default"].createElement("div", {
118
+ ref: content,
119
+ className: `${prefix}--accordion__wrapper`,
120
+ onTransitionEnd: onAnimationEnd
121
+ }, /*#__PURE__*/React__default["default"].createElement("div", {
118
122
  id: id,
119
123
  className: `${prefix}--accordion__content`
120
- }, children));
124
+ }, children)));
121
125
  }
122
126
  AccordionItem.propTypes = {
123
127
  /**
@@ -45,6 +45,10 @@ export interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputE
45
45
  * Provide the text that is displayed when the Checkbox is in an invalid state
46
46
  */
47
47
  invalidText?: React.ReactNode;
48
+ /**
49
+ * Provide a `Slug` component to be rendered inside the `Checkbox` component
50
+ */
51
+ slug?: ReactNodeLike;
48
52
  /**
49
53
  * Specify whether the Checkbox is currently invalid
50
54
  */
@@ -43,6 +43,7 @@ const Checkbox = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) =
43
43
  title = '',
44
44
  warn,
45
45
  warnText,
46
+ slug,
46
47
  ...other
47
48
  } = _ref;
48
49
  const prefix = usePrefix.usePrefix();
@@ -57,11 +58,19 @@ const Checkbox = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) =
57
58
  const wrapperClasses = cx__default["default"](`${prefix}--form-item`, `${prefix}--checkbox-wrapper`, className, {
58
59
  [`${prefix}--checkbox-wrapper--readonly`]: readOnly,
59
60
  [`${prefix}--checkbox-wrapper--invalid`]: !readOnly && invalid,
60
- [`${prefix}--checkbox-wrapper--warning`]: showWarning
61
+ [`${prefix}--checkbox-wrapper--warning`]: showWarning,
62
+ [`${prefix}--checkbox-wrapper--slug`]: slug
61
63
  });
62
64
  const innerLabelClasses = cx__default["default"](`${prefix}--checkbox-label-text`, {
63
65
  [`${prefix}--visually-hidden`]: hideLabel
64
66
  });
67
+ let normalizedSlug;
68
+ if (slug && /*#__PURE__*/React__default["default"].isValidElement(slug)) {
69
+ const size = slug.props?.['kind'] === 'inline' ? 'md' : 'mini';
70
+ normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
71
+ size
72
+ });
73
+ }
65
74
  return /*#__PURE__*/React__default["default"].createElement("div", {
66
75
  className: wrapperClasses
67
76
  }, /*#__PURE__*/React__default["default"].createElement("input", _rollupPluginBabelHelpers["extends"]({}, other, {
@@ -107,7 +116,7 @@ const Checkbox = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) =
107
116
  title: title
108
117
  }, /*#__PURE__*/React__default["default"].createElement(Text.Text, {
109
118
  className: innerLabelClasses
110
- }, labelText)), /*#__PURE__*/React__default["default"].createElement("div", {
119
+ }, labelText, normalizedSlug)), /*#__PURE__*/React__default["default"].createElement("div", {
111
120
  className: `${prefix}--checkbox__validation-msg`
112
121
  }, !readOnly && invalid && /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(iconsReact.WarningFilled, {
113
122
  className: `${prefix}--checkbox__invalid-icon`
@@ -175,6 +184,10 @@ Checkbox.propTypes = {
175
184
  * Specify whether the Checkbox is read-only
176
185
  */
177
186
  readOnly: PropTypes__default["default"].bool,
187
+ /**
188
+ * Provide a `Slug` component to be rendered inside the `Checkbox` component
189
+ */
190
+ slug: PropTypes__default["default"].node,
178
191
  /**
179
192
  * Specify a title for the <label> node for the Checkbox
180
193
  */
@@ -36,6 +36,7 @@ function CheckboxGroup(_ref) {
36
36
  readOnly,
37
37
  warn,
38
38
  warnText,
39
+ slug,
39
40
  ...rest
40
41
  } = _ref;
41
42
  const prefix = usePrefix.usePrefix();
@@ -50,8 +51,18 @@ function CheckboxGroup(_ref) {
50
51
  const fieldsetClasses = cx__default["default"](`${prefix}--checkbox-group`, className, {
51
52
  [`${prefix}--checkbox-group--readonly`]: readOnly,
52
53
  [`${prefix}--checkbox-group--invalid`]: !readOnly && invalid,
53
- [`${prefix}--checkbox-group--warning`]: showWarning
54
+ [`${prefix}--checkbox-group--warning`]: showWarning,
55
+ [`${prefix}--checkbox-group--slug`]: slug
54
56
  });
57
+
58
+ // Slug is always size `mini`
59
+ let normalizedSlug;
60
+ if (slug) {
61
+ normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
62
+ size: 'mini',
63
+ kind: 'default'
64
+ });
65
+ }
55
66
  return /*#__PURE__*/React__default["default"].createElement("fieldset", _rollupPluginBabelHelpers["extends"]({
56
67
  className: fieldsetClasses,
57
68
  "data-invalid": invalid ? true : undefined,
@@ -61,7 +72,7 @@ function CheckboxGroup(_ref) {
61
72
  }, rest), /*#__PURE__*/React__default["default"].createElement("legend", {
62
73
  className: `${prefix}--label`,
63
74
  id: legendId || rest['aria-labelledby']
64
- }, legendText), children, /*#__PURE__*/React__default["default"].createElement("div", {
75
+ }, legendText, normalizedSlug), children, /*#__PURE__*/React__default["default"].createElement("div", {
65
76
  className: `${prefix}--checkbox-group__validation-msg`
66
77
  }, !readOnly && invalid && /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(iconsReact.WarningFilled, {
67
78
  className: `${prefix}--checkbox__invalid-icon`
@@ -107,6 +118,10 @@ CheckboxGroup.propTypes = {
107
118
  * Whether the CheckboxGroup should be read-only
108
119
  */
109
120
  readOnly: PropTypes__default["default"].bool,
121
+ /**
122
+ * Provide a `Slug` component to be rendered inside the `CheckboxGroup` component
123
+ */
124
+ slug: PropTypes__default["default"].node,
110
125
  /**
111
126
  * Specify whether the form group is currently in warning state
112
127
  */
@@ -362,6 +362,18 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
362
362
  if (match.match(event, keys.End) && event.code !== 'Numpad1') {
363
363
  event.target.setSelectionRange(event.target.value.length, event.target.value.length);
364
364
  }
365
+ if (event.altKey && event.key == 'ArrowDown') {
366
+ event.preventDownshiftDefault = true;
367
+ if (!isOpen) {
368
+ toggleMenu();
369
+ }
370
+ }
371
+ if (event.altKey && event.key == 'ArrowUp') {
372
+ event.preventDownshiftDefault = true;
373
+ if (isOpen) {
374
+ toggleMenu();
375
+ }
376
+ }
365
377
  }
366
378
  });
367
379
  const handleFocus = evt => {
@@ -78,7 +78,7 @@ const ComboButton = /*#__PURE__*/React__default["default"].forwardRef(function C
78
78
  }
79
79
  }
80
80
  function handleOpen() {
81
- menuRef.current.style.width = `${width}px`;
81
+ menuRef.current.style.inlineSize = `${width}px`;
82
82
  }
83
83
  const containerClasses = cx__default["default"](`${prefix}--combo-button__container`, `${prefix}--combo-button__container--${size}`, {
84
84
  [`${prefix}--combo-button__container--open`]: open
@@ -110,6 +110,7 @@ const ComboButton = /*#__PURE__*/React__default["default"].forwardRef(function C
110
110
  ref: menuRef,
111
111
  id: id,
112
112
  label: t('carbon.combo-button.additional-actions'),
113
+ mode: "basic",
113
114
  size: size,
114
115
  open: open,
115
116
  onClose: handleClose,
@@ -4,7 +4,7 @@ export interface ModalBodyProps extends HTMLAttributes<HTMLDivElement> {
4
4
  children?: ReactNode;
5
5
  /**
6
6
  * Provide whether the modal content has a form element.
7
- * If `true` is used here, non-form child content should have `bx--modal-content__regular-content` class.
7
+ * If `true` is used here, non-form child content should have `cds--modal-content__regular-content` class.
8
8
  */
9
9
  hasForm?: boolean;
10
10
  /**
@@ -15,11 +15,11 @@ export interface ModalBodyProps extends HTMLAttributes<HTMLDivElement> {
15
15
  export declare const ModalBody: React.ForwardRefExoticComponent<ModalBodyProps & React.RefAttributes<HTMLDivElement>>;
16
16
  export interface ComposedModalProps extends HTMLAttributes<HTMLDivElement> {
17
17
  /**
18
- * Specify the aria-label for bx--modal-container
18
+ * Specify the aria-label for cds--modal-container
19
19
  */
20
20
  'aria-label'?: string;
21
21
  /**
22
- * Specify the aria-labelledby for bx--modal-container
22
+ * Specify the aria-labelledby for cds--modal-container
23
23
  */
24
24
  'aria-labelledby'?: string;
25
25
  /**
@@ -66,7 +66,7 @@ ModalBody.propTypes = {
66
66
  className: PropTypes__default["default"].string,
67
67
  /**
68
68
  * Provide whether the modal content has a form element.
69
- * If `true` is used here, non-form child content should have `bx--modal-content__regular-content` class.
69
+ * If `true` is used here, non-form child content should have `cds--modal-content__regular-content` class.
70
70
  */
71
71
  hasForm: PropTypes__default["default"].bool,
72
72
  /**
@@ -241,11 +241,11 @@ const ComposedModal = /*#__PURE__*/React__default["default"].forwardRef(function
241
241
  });
242
242
  ComposedModal.propTypes = {
243
243
  /**
244
- * Specify the aria-label for bx--modal-container
244
+ * Specify the aria-label for cds--modal-container
245
245
  */
246
246
  ['aria-label']: PropTypes__default["default"].string,
247
247
  /**
248
- * Specify the aria-labelledby for bx--modal-container
248
+ * Specify the aria-labelledby for cds--modal-container
249
249
  */
250
250
  ['aria-labelledby']: PropTypes__default["default"].string,
251
251
  /**
@@ -44,7 +44,8 @@ function useContextMenu() {
44
44
  open,
45
45
  x: position[0],
46
46
  y: position[1],
47
- onClose
47
+ onClose,
48
+ mode: 'full'
48
49
  };
49
50
  }
50
51
 
@@ -37,7 +37,7 @@ const compare = function (a, b) {
37
37
 
38
38
  // if column has React elements, this should sort by the child string if there is one
39
39
  if (typeof a === 'object' && typeof b === 'object') {
40
- if (typeof a.props.children === 'string' && typeof b.props.children === 'string') {
40
+ if (typeof a.props?.children === 'string' && typeof b.props?.children === 'string') {
41
41
  return compareStrings(a.props.children, b.props.children, locale);
42
42
  }
43
43
  }
@@ -73,7 +73,7 @@ const DataTableSkeleton = _ref => {
73
73
  }, rest), /*#__PURE__*/React__default["default"].createElement("thead", null, /*#__PURE__*/React__default["default"].createElement("tr", null, columnsArray.map(i => /*#__PURE__*/React__default["default"].createElement("th", {
74
74
  key: i
75
75
  }, headers ? /*#__PURE__*/React__default["default"].createElement("div", {
76
- className: "bx--table-header-label"
76
+ className: "cds--table-header-label"
77
77
  }, headers[i]?.header) : _span2 || (_span2 = /*#__PURE__*/React__default["default"].createElement("span", null)))))), /*#__PURE__*/React__default["default"].createElement("tbody", null, rows)));
78
78
  };
79
79
  DataTableSkeleton.propTypes = {
@@ -287,6 +287,9 @@ const Dropdown = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) =
287
287
  item,
288
288
  index: index$1
289
289
  });
290
+ if (item !== null && typeof item === 'object' && Object.prototype.hasOwnProperty.call(item, 'id')) {
291
+ itemProps.id = item['id'];
292
+ }
290
293
  const title = isObject && 'text' in item && itemToElement ? item.text : itemToString(item);
291
294
  return /*#__PURE__*/React__default["default"].createElement(index["default"].MenuItem, _rollupPluginBabelHelpers["extends"]({
292
295
  key: itemProps.id,
@@ -314,7 +317,7 @@ Dropdown.propTypes = {
314
317
  */
315
318
  ariaLabel: deprecate["default"](PropTypes__default["default"].string, 'This prop syntax has been deprecated. Please use the new `aria-label`.'),
316
319
  /**
317
- * Provide a custom className to be applied on the bx--dropdown node
320
+ * Provide a custom className to be applied on the cds--dropdown node
318
321
  */
319
322
  className: PropTypes__default["default"].string,
320
323
  /**
@@ -116,11 +116,12 @@ class FileUploader extends React__default["default"].Component {
116
116
  return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({
117
117
  className: classes
118
118
  }, other), !labelTitle ? null : /*#__PURE__*/React__default["default"].createElement(Text.Text, {
119
- as: "p",
119
+ as: "h3",
120
120
  className: getHelperLabelClasses(`${prefix}--file--label`)
121
121
  }, labelTitle), /*#__PURE__*/React__default["default"].createElement(Text.Text, {
122
122
  as: "p",
123
- className: getHelperLabelClasses(`${prefix}--label-description`)
123
+ className: getHelperLabelClasses(`${prefix}--label-description`),
124
+ id: "description"
124
125
  }, labelDescription), /*#__PURE__*/React__default["default"].createElement(FileUploaderButton["default"], {
125
126
  innerRef: this.uploaderButton,
126
127
  disabled: disabled,
@@ -131,7 +132,8 @@ class FileUploader extends React__default["default"].Component {
131
132
  disableLabelChanges: true,
132
133
  accept: accept,
133
134
  name: name,
134
- size: size
135
+ size: size,
136
+ "aria-describedby": "description"
135
137
  }), /*#__PURE__*/React__default["default"].createElement("div", {
136
138
  className: `${prefix}--file-container`
137
139
  }, this.state.filenames.length === 0 ? null : this.state.filenames.map((name, index) => /*#__PURE__*/React__default["default"].createElement("span", _rollupPluginBabelHelpers["extends"]({
@@ -131,6 +131,11 @@ Column.propTypes = {
131
131
  * @see https://www.carbondesignsystem.com/guidelines/layout#breakpoints
132
132
  */
133
133
  sm: spanPropType,
134
+ /**
135
+ * Specify constant column span, start, or end values that will not change
136
+ * based on breakpoint
137
+ */
138
+ span: PropTypes__default["default"].oneOfType([PropTypes__default["default"].number, percentSpanType]),
134
139
  /**
135
140
  * Specify column span for the `xlg` breakpoint (Default breakpoint up to
136
141
  * 1584px) This breakpoint supports 16 columns by default.
@@ -340,8 +345,13 @@ function getClassNameForFlexGridBreakpoints(breakpoints, prefix) {
340
345
  */
341
346
  function getClassNameForSpan(value, prefix) {
342
347
  const classNames = [];
343
- if (typeof value === 'number' || typeof value === 'string') {
348
+ if (typeof value === 'number') {
344
349
  classNames.push(`${prefix}--col-span-${value}`);
350
+ }
351
+ // If value is a string, the user has specified a percent
352
+ // they'd like this column to span.
353
+ else if (typeof value === 'string') {
354
+ classNames.push(`${prefix}--col-span-${value.slice(0, -1)}`);
345
355
  } else if (typeof value === 'object') {
346
356
  const {
347
357
  span,
@@ -6,6 +6,11 @@
6
6
  */
7
7
  import React, { AnchorHTMLAttributes, AriaAttributes, ComponentType, HTMLAttributeAnchorTarget } from 'react';
8
8
  export interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
9
+ /**
10
+ * Provide a custom element or component to render the top-level node for the
11
+ * component.
12
+ */
13
+ as?: string | undefined;
9
14
  /**
10
15
  * @description Indicates the element that represents the
11
16
  * current item within a container or set of related
@@ -23,6 +23,7 @@ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
23
23
 
24
24
  const Link = /*#__PURE__*/React__default["default"].forwardRef(function Link(_ref, ref) {
25
25
  let {
26
+ as: BaseComponent,
26
27
  children,
27
28
  className: customClassName,
28
29
  href,
@@ -43,7 +44,7 @@ const Link = /*#__PURE__*/React__default["default"].forwardRef(function Link(_re
43
44
  });
44
45
  const rel = target === '_blank' ? 'noopener' : undefined;
45
46
  const linkProps = {
46
- className,
47
+ className: BaseComponent ? undefined : className,
47
48
  rel,
48
49
  target
49
50
  };
@@ -56,7 +57,8 @@ const Link = /*#__PURE__*/React__default["default"].forwardRef(function Link(_re
56
57
  linkProps.role = 'link';
57
58
  linkProps['aria-disabled'] = true;
58
59
  }
59
- return /*#__PURE__*/React__default["default"].createElement("a", _rollupPluginBabelHelpers["extends"]({
60
+ const BaseComponentAsAny = BaseComponent ?? 'a';
61
+ return /*#__PURE__*/React__default["default"].createElement(BaseComponentAsAny, _rollupPluginBabelHelpers["extends"]({
60
62
  ref: ref
61
63
  }, linkProps, rest), children, !inline && Icon && /*#__PURE__*/React__default["default"].createElement("div", {
62
64
  className: `${prefix}--link__icon`
@@ -64,6 +66,11 @@ const Link = /*#__PURE__*/React__default["default"].forwardRef(function Link(_re
64
66
  });
65
67
  Link.displayName = 'Link';
66
68
  Link.propTypes = {
69
+ /**
70
+ * Provide a custom element or component to render the top-level node for the
71
+ * component.
72
+ */
73
+ as: PropTypes__default["default"].string,
67
74
  /**
68
75
  * Provide the content for the Link
69
76
  */
@@ -16,6 +16,7 @@ var React = require('react');
16
16
  var ReactDOM = require('react-dom');
17
17
  var useMergedRefs = require('../../internal/useMergedRefs.js');
18
18
  var usePrefix = require('../../internal/usePrefix.js');
19
+ var warning = require('../../internal/warning.js');
19
20
  var MenuContext = require('./MenuContext.js');
20
21
  var useLayoutDirection = require('../LayoutDirection/useLayoutDirection.js');
21
22
  var match = require('../../internal/keyboard/match.js');
@@ -34,6 +35,7 @@ const Menu = /*#__PURE__*/React__default["default"].forwardRef(function Menu(_re
34
35
  children,
35
36
  className,
36
37
  label,
38
+ mode = 'full',
37
39
  onClose,
38
40
  onOpen,
39
41
  open,
@@ -47,10 +49,14 @@ const Menu = /*#__PURE__*/React__default["default"].forwardRef(function Menu(_re
47
49
  const focusReturn = React.useRef(null);
48
50
  const context = React.useContext(MenuContext.MenuContext);
49
51
  const isRoot = context.state.isRoot;
52
+ if (context.state.mode === 'basic' && !isRoot) {
53
+ process.env.NODE_ENV !== "production" ? warning.warning(false, 'Nested menus are not supported when the menu is in "basic" mode.') : void 0;
54
+ }
50
55
  const menuSize = isRoot ? size : context.state.size;
51
56
  const [childState, childDispatch] = React.useReducer(MenuContext.menuReducer, {
52
57
  ...context.state,
53
58
  isRoot: false,
59
+ mode,
54
60
  size,
55
61
  requestCloseRoot: isRoot ? handleClose : context.state.requestCloseRoot
56
62
  });
@@ -255,6 +261,14 @@ Menu.propTypes = {
255
261
  * A label describing the Menu.
256
262
  */
257
263
  label: PropTypes__default["default"].string,
264
+ /**
265
+ * The mode of this menu. Defaults to full.
266
+ * `full` supports nesting and selectable menu items, but no icons.
267
+ * `basic` supports icons but no nesting or selectable menu items.
268
+ *
269
+ * **This prop is not intended for use and will be set by the respective implementation (like useContextMenu, MenuButton, and ComboButton).**
270
+ */
271
+ mode: PropTypes__default["default"].oneOf(['full', 'basic']),
258
272
  /**
259
273
  * Provide an optional function to be called when the Menu should be closed.
260
274
  */
@@ -17,6 +17,7 @@ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
17
17
 
18
18
  const menuDefaultState = {
19
19
  isRoot: true,
20
+ mode: 'full',
20
21
  hasIcons: false,
21
22
  size: null,
22
23
  items: [],
@@ -17,6 +17,7 @@ var iconsReact = require('@carbon/icons-react');
17
17
  var useControllableState = require('../../internal/useControllableState.js');
18
18
  var useMergedRefs = require('../../internal/useMergedRefs.js');
19
19
  var usePrefix = require('../../internal/usePrefix.js');
20
+ var warning = require('../../internal/warning.js');
20
21
  var Menu = require('./Menu.js');
21
22
  var MenuContext = require('./MenuContext.js');
22
23
  require('../Text/index.js');
@@ -153,6 +154,14 @@ const MenuItem = /*#__PURE__*/React__default["default"].forwardRef(function Menu
153
154
  setRtl(false);
154
155
  }
155
156
  }, [direction]);
157
+ const iconsAllowed = context.state.mode === 'basic' || rest.role === 'menuitemcheckbox' || rest.role === 'menuitemradio';
158
+ React.useEffect(() => {
159
+ if (iconsAllowed && IconElement && !context.state.hasIcons) {
160
+ context.dispatch({
161
+ type: 'enableIcons'
162
+ });
163
+ }
164
+ }, [iconsAllowed, IconElement, context.state.hasIcons, context]);
156
165
  return /*#__PURE__*/React__default["default"].createElement("li", _rollupPluginBabelHelpers["extends"]({
157
166
  role: "menuitem"
158
167
  }, rest, {
@@ -168,7 +177,7 @@ const MenuItem = /*#__PURE__*/React__default["default"].forwardRef(function Menu
168
177
  onKeyDown: handleKeyDown
169
178
  }), /*#__PURE__*/React__default["default"].createElement("div", {
170
179
  className: `${prefix}--menu-item__icon`
171
- }, IconElement && /*#__PURE__*/React__default["default"].createElement(IconElement, null)), /*#__PURE__*/React__default["default"].createElement(Text.Text, {
180
+ }, iconsAllowed && IconElement && /*#__PURE__*/React__default["default"].createElement(IconElement, null)), /*#__PURE__*/React__default["default"].createElement(Text.Text, {
172
181
  as: "div",
173
182
  className: `${prefix}--menu-item__label`
174
183
  }, label), shortcut && !hasChildren && /*#__PURE__*/React__default["default"].createElement("div", {
@@ -212,7 +221,7 @@ MenuItem.propTypes = {
212
221
  */
213
222
  onClick: PropTypes__default["default"].func,
214
223
  /**
215
- * This prop is not intended for use. The only supported icons are Checkmarks to depict single- and multi-selects. This prop is used by MenuItemSelectable and MenuItemRadioGroup automatically.
224
+ * Only applicable if the parent menu is in `basic` mode. Sets the menu item's icon.
216
225
  */
217
226
  renderIcon: PropTypes__default["default"].oneOfType([PropTypes__default["default"].func, PropTypes__default["default"].object]),
218
227
  /**
@@ -231,6 +240,9 @@ const MenuItemSelectable = /*#__PURE__*/React__default["default"].forwardRef(fun
231
240
  } = _ref2;
232
241
  const prefix = usePrefix.usePrefix();
233
242
  const context = React.useContext(MenuContext.MenuContext);
243
+ if (context.state.mode === 'basic') {
244
+ process.env.NODE_ENV !== "production" ? warning.warning(false, 'MenuItemSelectable is not supported when the menu is in "basic" mode.') : void 0;
245
+ }
234
246
  const [checked, setChecked] = useControllableState.useControllableState({
235
247
  value: selected,
236
248
  onChange,
@@ -256,7 +268,7 @@ const MenuItemSelectable = /*#__PURE__*/React__default["default"].forwardRef(fun
256
268
  className: classNames,
257
269
  role: "menuitemcheckbox",
258
270
  "aria-checked": checked,
259
- renderIcon: checked && iconsReact.Checkmark,
271
+ renderIcon: checked ? iconsReact.Checkmark : undefined,
260
272
  onClick: handleClick
261
273
  }));
262
274
  });
@@ -328,6 +340,9 @@ const MenuItemRadioGroup = /*#__PURE__*/React__default["default"].forwardRef(fun
328
340
  } = _ref4;
329
341
  const prefix = usePrefix.usePrefix();
330
342
  const context = React.useContext(MenuContext.MenuContext);
343
+ if (context.state.mode === 'basic') {
344
+ process.env.NODE_ENV !== "production" ? warning.warning(false, 'MenuItemRadioGroup is not supported when the menu is in "basic" mode.') : void 0;
345
+ }
331
346
  const [selection, setSelection] = useControllableState.useControllableState({
332
347
  value: selectedItem,
333
348
  onChange,
@@ -359,7 +374,7 @@ const MenuItemRadioGroup = /*#__PURE__*/React__default["default"].forwardRef(fun
359
374
  label: itemToString(item),
360
375
  role: "menuitemradio",
361
376
  "aria-checked": item === selection,
362
- renderIcon: item === selection && iconsReact.Checkmark,
377
+ renderIcon: item === selection ? iconsReact.Checkmark : undefined,
363
378
  onClick: e => {
364
379
  handleClick(item, e);
365
380
  }
@@ -39,6 +39,7 @@ const MenuButton = /*#__PURE__*/React__default["default"].forwardRef(function Me
39
39
  kind = defaultButtonKind,
40
40
  label,
41
41
  size = 'lg',
42
+ tabIndex = 0,
42
43
  ...rest
43
44
  } = _ref;
44
45
  const id = useId.useId('MenuButton');
@@ -67,6 +68,7 @@ const MenuButton = /*#__PURE__*/React__default["default"].forwardRef(function Me
67
68
  function handleOpen() {
68
69
  menuRef.current.style.inlineSize = `${width}px`;
69
70
  }
71
+ const containerClasses = cx__default["default"](`${prefix}--menu-button__container`, className);
70
72
  const triggerClasses = cx__default["default"](`${prefix}--menu-button__trigger`, {
71
73
  [`${prefix}--menu-button__trigger--open`]: open
72
74
  });
@@ -74,10 +76,11 @@ const MenuButton = /*#__PURE__*/React__default["default"].forwardRef(function Me
74
76
  return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({}, rest, {
75
77
  ref: ref,
76
78
  "aria-owns": open ? id : null,
77
- className: className
79
+ className: containerClasses
78
80
  }), /*#__PURE__*/React__default["default"].createElement(Button["default"], {
79
81
  className: triggerClasses,
80
82
  size: size,
83
+ tabIndex: tabIndex,
81
84
  kind: buttonKind,
82
85
  renderIcon: iconsReact.ChevronDown,
83
86
  disabled: disabled,
@@ -90,6 +93,7 @@ const MenuButton = /*#__PURE__*/React__default["default"].forwardRef(function Me
90
93
  ref: menuRef,
91
94
  id: id,
92
95
  label: label,
96
+ mode: "basic",
93
97
  size: size,
94
98
  open: open,
95
99
  onClose: handleClose,
@@ -122,7 +126,11 @@ MenuButton.propTypes = {
122
126
  /**
123
127
  * Specify the size of the button and menu.
124
128
  */
125
- size: PropTypes__default["default"].oneOf(['sm', 'md', 'lg'])
129
+ size: PropTypes__default["default"].oneOf(['sm', 'md', 'lg']),
130
+ /**
131
+ * Specify the tabIndex of the button.
132
+ */
133
+ tabIndex: PropTypes__default["default"].number
126
134
  };
127
135
 
128
136
  exports.MenuButton = MenuButton;
@@ -55,6 +55,10 @@ export interface RadioButtonProps extends Omit<React.InputHTMLAttributes<HTMLInp
55
55
  * Provide a handler that is invoked when a user clicks on the control
56
56
  */
57
57
  onClick?: (evt: React.MouseEvent<HTMLInputElement>) => void;
58
+ /**
59
+ * Provide a `Slug` component to be rendered inside the `RadioButton` component
60
+ */
61
+ slug?: ReactNodeLike;
58
62
  /**
59
63
  * Specify the value of the `<RadioButton>`
60
64
  */