@carbon/react 1.42.1 → 1.44.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 (97) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +2843 -1416
  2. package/es/components/Breadcrumb/BreadcrumbItem.js +1 -2
  3. package/es/components/ComboBox/ComboBox.d.ts +5 -0
  4. package/es/components/ComboBox/ComboBox.js +28 -2
  5. package/es/components/ComboButton/index.js +2 -1
  6. package/es/components/ComposedModal/ComposedModal.d.ts +3 -3
  7. package/es/components/ComposedModal/ComposedModal.js +3 -3
  8. package/es/components/ComposedModal/ModalFooter.d.ts +18 -0
  9. package/es/components/ComposedModal/ModalFooter.js +48 -16
  10. package/es/components/ContextMenu/useContextMenu.js +2 -1
  11. package/es/components/DataTableSkeleton/DataTableSkeleton.js +1 -1
  12. package/es/components/DatePickerInput/DatePickerInput.d.ts +4 -0
  13. package/es/components/DatePickerInput/DatePickerInput.js +16 -2
  14. package/es/components/Dropdown/Dropdown.d.ts +5 -0
  15. package/es/components/Dropdown/Dropdown.js +20 -3
  16. package/es/components/InlineLoading/index.js +9 -0
  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 +3 -1
  23. package/es/components/Modal/Modal.d.ts +17 -0
  24. package/es/components/Modal/Modal.js +38 -3
  25. package/es/components/MultiSelect/FilterableMultiSelect.js +17 -3
  26. package/es/components/MultiSelect/MultiSelect.d.ts +5 -0
  27. package/es/components/MultiSelect/MultiSelect.js +17 -3
  28. package/es/components/NumberInput/NumberInput.d.ts +5 -0
  29. package/es/components/NumberInput/NumberInput.js +29 -4
  30. package/es/components/Select/Select.d.ts +6 -1
  31. package/es/components/Select/Select.js +16 -2
  32. package/es/components/Slug/index.js +187 -0
  33. package/es/components/TextArea/TextArea.d.ts +4 -0
  34. package/es/components/TextArea/TextArea.js +47 -31
  35. package/es/components/TextInput/TextInput.d.ts +5 -0
  36. package/es/components/TextInput/TextInput.js +16 -2
  37. package/es/components/UIShell/SideNav.js +1 -1
  38. package/es/components/UIShell/SideNavHeader.d.ts +29 -0
  39. package/es/components/UIShell/SideNavHeader.js +3 -3
  40. package/es/components/UIShell/Switcher.d.ts +38 -0
  41. package/es/components/UIShell/Switcher.js +14 -13
  42. package/es/components/UIShell/SwitcherDivider.d.ts +9 -0
  43. package/es/components/UIShell/SwitcherDivider.js +4 -5
  44. package/es/components/UIShell/SwitcherItem.d.ts +49 -0
  45. package/es/components/UIShell/SwitcherItem.js +13 -17
  46. package/es/index.d.ts +1 -0
  47. package/es/index.js +1 -0
  48. package/es/prop-types/tools/getDisplayName.js +34 -0
  49. package/lib/components/Breadcrumb/BreadcrumbItem.js +1 -2
  50. package/lib/components/ComboBox/ComboBox.d.ts +5 -0
  51. package/lib/components/ComboBox/ComboBox.js +28 -2
  52. package/lib/components/ComboButton/index.js +2 -1
  53. package/lib/components/ComposedModal/ComposedModal.d.ts +3 -3
  54. package/lib/components/ComposedModal/ComposedModal.js +3 -3
  55. package/lib/components/ComposedModal/ModalFooter.d.ts +18 -0
  56. package/lib/components/ComposedModal/ModalFooter.js +48 -16
  57. package/lib/components/ContextMenu/useContextMenu.js +2 -1
  58. package/lib/components/DataTableSkeleton/DataTableSkeleton.js +1 -1
  59. package/lib/components/DatePickerInput/DatePickerInput.d.ts +4 -0
  60. package/lib/components/DatePickerInput/DatePickerInput.js +16 -2
  61. package/lib/components/Dropdown/Dropdown.d.ts +5 -0
  62. package/lib/components/Dropdown/Dropdown.js +20 -3
  63. package/lib/components/InlineLoading/index.js +17 -0
  64. package/lib/components/Link/Link.d.ts +5 -0
  65. package/lib/components/Link/Link.js +9 -2
  66. package/lib/components/Menu/Menu.js +14 -0
  67. package/lib/components/Menu/MenuContext.js +1 -0
  68. package/lib/components/Menu/MenuItem.js +19 -4
  69. package/lib/components/MenuButton/index.js +3 -1
  70. package/lib/components/Modal/Modal.d.ts +17 -0
  71. package/lib/components/Modal/Modal.js +38 -3
  72. package/lib/components/MultiSelect/FilterableMultiSelect.js +17 -3
  73. package/lib/components/MultiSelect/MultiSelect.d.ts +5 -0
  74. package/lib/components/MultiSelect/MultiSelect.js +17 -3
  75. package/lib/components/NumberInput/NumberInput.d.ts +5 -0
  76. package/lib/components/NumberInput/NumberInput.js +28 -3
  77. package/lib/components/Select/Select.d.ts +6 -1
  78. package/lib/components/Select/Select.js +16 -2
  79. package/lib/components/Slug/index.js +199 -0
  80. package/lib/components/TextArea/TextArea.d.ts +4 -0
  81. package/lib/components/TextArea/TextArea.js +47 -31
  82. package/lib/components/TextInput/TextInput.d.ts +5 -0
  83. package/lib/components/TextInput/TextInput.js +16 -2
  84. package/lib/components/UIShell/SideNav.js +1 -1
  85. package/lib/components/UIShell/SideNavHeader.d.ts +29 -0
  86. package/lib/components/UIShell/SideNavHeader.js +3 -3
  87. package/lib/components/UIShell/Switcher.d.ts +38 -0
  88. package/lib/components/UIShell/Switcher.js +13 -12
  89. package/lib/components/UIShell/SwitcherDivider.d.ts +9 -0
  90. package/lib/components/UIShell/SwitcherDivider.js +4 -5
  91. package/lib/components/UIShell/SwitcherItem.d.ts +49 -0
  92. package/lib/components/UIShell/SwitcherItem.js +12 -16
  93. package/lib/index.d.ts +1 -0
  94. package/lib/index.js +45 -41
  95. package/lib/prop-types/tools/getDisplayName.js +38 -0
  96. package/package.json +6 -6
  97. package/scss/utilities/_ai-gradient.scss +9 -0
@@ -69,8 +69,7 @@ const BreadcrumbItem = /*#__PURE__*/React__default.forwardRef(function Breadcrum
69
69
  });
70
70
  BreadcrumbItem.displayName = 'BreadcrumbItem';
71
71
  BreadcrumbItem.propTypes = {
72
- // @ts-expect-error - v12 TODO: BREAKING: This should match AriaAttributes['aria-current']
73
- 'aria-current': PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
72
+ 'aria-current': PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['false', 'true', 'page', 'step', 'location', 'date', 'time'])]),
74
73
  /**
75
74
  * Pass in content that will be inside of the BreadcrumbItem
76
75
  */
@@ -5,6 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import Downshift from 'downshift';
8
+ import { ReactNodeLike } from 'prop-types';
8
9
  import { type ComponentProps, type ReactNode, type ComponentType, type ReactElement, type RefAttributes, type PropsWithChildren, type PropsWithoutRef, type InputHTMLAttributes, type MouseEvent } from 'react';
9
10
  import { ListBoxSize } from '../ListBox';
10
11
  type ExcludedAttributes = 'id' | 'onChange' | 'onClick' | 'type' | 'size';
@@ -135,6 +136,10 @@ export interface ComboBoxProps<ItemType> extends Omit<InputHTMLAttributes<HTMLIn
135
136
  * Specify the size of the ListBox. Currently supports either `sm`, `md` or `lg` as an option.
136
137
  */
137
138
  size?: ListBoxSize;
139
+ /**
140
+ * Provide a `Slug` component to be rendered inside the `ComboBox` component
141
+ */
142
+ slug?: ReactNodeLike;
138
143
  /**
139
144
  * Provide text to be used in a `<label>` element that is tied to the
140
145
  * combobox via ARIA attributes.
@@ -112,6 +112,7 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
112
112
  warn,
113
113
  warnText,
114
114
  allowCustomValue = false,
115
+ slug,
115
116
  ...rest
116
117
  } = props;
117
118
  const prefix = usePrefix();
@@ -243,7 +244,8 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
243
244
  });
244
245
  const wrapperClasses = cx(`${prefix}--list-box__wrapper`, [containerClassName, {
245
246
  [`${prefix}--list-box__wrapper--fluid--invalid`]: isFluid && invalid,
246
- [`${prefix}--list-box__wrapper--fluid--focus`]: isFluid && isFocused
247
+ [`${prefix}--list-box__wrapper--fluid--focus`]: isFluid && isFocused,
248
+ [`${prefix}--list-box__wrapper--slug`]: slug
247
249
  }]);
248
250
  const inputClasses = cx(`${prefix}--text-input`, {
249
251
  [`${prefix}--text-input--empty`]: !inputValue,
@@ -252,6 +254,14 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
252
254
 
253
255
  // needs to be Capitalized for react to render it correctly
254
256
  const ItemToElement = itemToElement;
257
+
258
+ // Slug is always size `mini`
259
+ let normalizedSlug;
260
+ if (slug) {
261
+ normalizedSlug = /*#__PURE__*/React__default.cloneElement(slug, {
262
+ size: 'mini'
263
+ });
264
+ }
255
265
  return /*#__PURE__*/React__default.createElement(Downshift, _extends({}, downshiftProps, {
256
266
  onChange: handleOnChange,
257
267
  onInputValueChange: handleOnInputValueChange,
@@ -341,6 +351,18 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
341
351
  if (match(event, End) && event.code !== 'Numpad1') {
342
352
  event.target.setSelectionRange(event.target.value.length, event.target.value.length);
343
353
  }
354
+ if (event.altKey && event.key == 'ArrowDown') {
355
+ event.preventDownshiftDefault = true;
356
+ if (!isOpen) {
357
+ toggleMenu();
358
+ }
359
+ }
360
+ if (event.altKey && event.key == 'ArrowUp') {
361
+ event.preventDownshiftDefault = true;
362
+ if (isOpen) {
363
+ toggleMenu();
364
+ }
365
+ }
344
366
  }
345
367
  });
346
368
  const handleFocus = evt => {
@@ -402,7 +424,7 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
402
424
  }), /*#__PURE__*/React__default.createElement(ListBoxTrigger, _extends({}, buttonProps, {
403
425
  isOpen: isOpen,
404
426
  translateWithId: translateWithId
405
- }))), /*#__PURE__*/React__default.createElement(ListBox.Menu, getMenuProps({
427
+ }))), normalizedSlug, /*#__PURE__*/React__default.createElement(ListBox.Menu, getMenuProps({
406
428
  'aria-label': deprecatedAriaLabel || ariaLabel
407
429
  }), isOpen ? filterItems(items, itemToString, inputValue).map((item, index) => {
408
430
  const isObject = item !== null && typeof item === 'object';
@@ -552,6 +574,10 @@ ComboBox.propTypes = {
552
574
  * Specify the size of the ListBox. Currently supports either `sm`, `md` or `lg` as an option.
553
575
  */
554
576
  size: ListBoxSize,
577
+ /**
578
+ * Provide a `Slug` component to be rendered inside the `ComboBox` component
579
+ */
580
+ slug: PropTypes.node,
555
581
  /**
556
582
  * Provide text to be used in a `<label>` element that is tied to the
557
583
  * combobox via ARIA attributes.
@@ -68,7 +68,7 @@ const ComboButton = /*#__PURE__*/React__default.forwardRef(function ComboButton(
68
68
  }
69
69
  }
70
70
  function handleOpen() {
71
- menuRef.current.style.width = `${width}px`;
71
+ menuRef.current.style.inlineSize = `${width}px`;
72
72
  }
73
73
  const containerClasses = cx(`${prefix}--combo-button__container`, `${prefix}--combo-button__container--${size}`, {
74
74
  [`${prefix}--combo-button__container--open`]: open
@@ -100,6 +100,7 @@ const ComboButton = /*#__PURE__*/React__default.forwardRef(function ComboButton(
100
100
  ref: menuRef,
101
101
  id: id,
102
102
  label: t('carbon.combo-button.additional-actions'),
103
+ mode: "basic",
103
104
  size: size,
104
105
  open: open,
105
106
  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
  /**
@@ -56,7 +56,7 @@ ModalBody.propTypes = {
56
56
  className: PropTypes.string,
57
57
  /**
58
58
  * Provide whether the modal content has a form element.
59
- * If `true` is used here, non-form child content should have `bx--modal-content__regular-content` class.
59
+ * If `true` is used here, non-form child content should have `cds--modal-content__regular-content` class.
60
60
  */
61
61
  hasForm: PropTypes.bool,
62
62
  /**
@@ -231,11 +231,11 @@ const ComposedModal = /*#__PURE__*/React__default.forwardRef(function ComposedMo
231
231
  });
232
232
  ComposedModal.propTypes = {
233
233
  /**
234
- * Specify the aria-label for bx--modal-container
234
+ * Specify the aria-label for cds--modal-container
235
235
  */
236
236
  ['aria-label']: PropTypes.string,
237
237
  /**
238
- * Specify the aria-labelledby for bx--modal-container
238
+ * Specify the aria-labelledby for cds--modal-container
239
239
  */
240
240
  ['aria-labelledby']: PropTypes.string,
241
241
  /**
@@ -5,6 +5,7 @@ interface SecondaryButtonProps {
5
5
  }
6
6
  export interface SecondaryButtonSetProps {
7
7
  closeModal(evt: MouseEvent): void;
8
+ disabled?: boolean;
8
9
  onRequestClose(evt: MouseEvent): void;
9
10
  secondaryButtonText?: string;
10
11
  secondaryButtons?: [SecondaryButtonProps, SecondaryButtonProps];
@@ -66,6 +67,23 @@ export interface ModalFooterProps {
66
67
  * Specify a custom className to be applied to the secondary button
67
68
  */
68
69
  secondaryClassName?: string;
70
+ /**
71
+ * loading status
72
+ */
73
+ loadingStatus?: string;
74
+ /**
75
+ * Specify the description for the loading text
76
+ */
77
+ loadingDescription?: string;
78
+ /**
79
+ * Specify the description for the loading text
80
+ */
81
+ loadingIconDescription?: string;
82
+ /**
83
+ * Provide an optional handler to be invoked when loading is
84
+ * successful
85
+ */
86
+ onLoadingSuccess?(): void;
69
87
  }
70
88
  export declare const ModalFooter: React.ForwardRefExoticComponent<ModalFooterProps & React.RefAttributes<HTMLElement>>;
71
89
  export {};
@@ -14,6 +14,7 @@ import ButtonSet from '../ButtonSet/ButtonSet.js';
14
14
  import cx from 'classnames';
15
15
  import { usePrefix } from '../../internal/usePrefix.js';
16
16
  import { noopFn } from '../../internal/noopFn.js';
17
+ import InlineLoading from '../InlineLoading/InlineLoading.js';
17
18
 
18
19
  function SecondaryButtonSet(_ref) {
19
20
  let {
@@ -21,7 +22,8 @@ function SecondaryButtonSet(_ref) {
21
22
  secondaryButtonText,
22
23
  secondaryClassName,
23
24
  closeModal,
24
- onRequestClose
25
+ onRequestClose,
26
+ disabled
25
27
  } = _ref;
26
28
  function handleRequestClose(evt) {
27
29
  closeModal(evt);
@@ -43,6 +45,7 @@ function SecondaryButtonSet(_ref) {
43
45
  }
44
46
  if (secondaryButtonText) {
45
47
  return /*#__PURE__*/React__default.createElement(Button, {
48
+ disabled: disabled,
46
49
  className: secondaryClassName,
47
50
  onClick: handleRequestClose,
48
51
  kind: "secondary"
@@ -52,6 +55,7 @@ function SecondaryButtonSet(_ref) {
52
55
  }
53
56
  SecondaryButtonSet.propTypes = {
54
57
  closeModal: PropTypes.func,
58
+ disabled: PropTypes.bool,
55
59
  onRequestClose: PropTypes.func,
56
60
  secondaryButtonText: PropTypes.string,
57
61
  secondaryButtons: (props, propName, componentName) => {
@@ -86,32 +90,43 @@ const ModalFooter = /*#__PURE__*/React__default.forwardRef(function ModalFooter(
86
90
  secondaryButtonText,
87
91
  secondaryButtons,
88
92
  secondaryClassName,
93
+ loadingStatus = 'inactive',
94
+ loadingDescription,
95
+ loadingIconDescription,
96
+ onLoadingSuccess = noopFn,
89
97
  ...rest
90
98
  } = _ref3;
91
99
  const prefix = usePrefix();
92
100
  const footerClass = cx(`${prefix}--modal-footer`, customClassName, Array.isArray(secondaryButtons) && secondaryButtons.length === 2 ? `${prefix}--modal-footer--three-button` : null);
101
+ const primaryButtonClass = cx(primaryClassName, loadingStatus !== 'inactive' ? `${prefix}--btn--loading` : null);
102
+ const loadingActive = loadingStatus !== 'inactive';
93
103
  const secondaryButtonProps = {
94
104
  closeModal,
95
105
  secondaryButtons,
96
106
  secondaryButtonText,
97
107
  secondaryClassName,
98
- onRequestClose
108
+ onRequestClose,
109
+ disabled: loadingActive
99
110
  };
100
- return (
101
- /*#__PURE__*/
111
+ return /*#__PURE__*/React__default.createElement(ButtonSet, _extends({
112
+ className: footerClass
113
+ }, rest, {
102
114
  // @ts-expect-error: Invalid derived types, will be fine once explicit types are added
103
- React__default.createElement(ButtonSet, _extends({
104
- className: footerClass
105
- }, rest, {
106
- ref: ref
107
- }), /*#__PURE__*/React__default.createElement(SecondaryButtonSet, secondaryButtonProps), primaryButtonText && /*#__PURE__*/React__default.createElement(Button, {
108
- onClick: onRequestSubmit,
109
- className: primaryClassName,
110
- disabled: primaryButtonDisabled,
111
- kind: danger ? 'danger' : 'primary',
112
- ref: inputref
113
- }, primaryButtonText), children)
114
- );
115
+ ref: ref,
116
+ "aria-busy": loadingActive
117
+ }), /*#__PURE__*/React__default.createElement(SecondaryButtonSet, secondaryButtonProps), primaryButtonText && /*#__PURE__*/React__default.createElement(Button, {
118
+ onClick: onRequestSubmit,
119
+ className: primaryButtonClass,
120
+ disabled: loadingActive || primaryButtonDisabled,
121
+ kind: danger ? 'danger' : 'primary',
122
+ ref: inputref
123
+ }, loadingStatus === 'inactive' ? primaryButtonText : /*#__PURE__*/React__default.createElement(InlineLoading, {
124
+ status: loadingStatus,
125
+ description: loadingDescription,
126
+ iconDescription: loadingIconDescription,
127
+ className: `${prefix}--inline-loading--btn`,
128
+ onSuccess: onLoadingSuccess
129
+ })), children);
115
130
  });
116
131
  ModalFooter.propTypes = {
117
132
  /**
@@ -138,6 +153,23 @@ ModalFooter.propTypes = {
138
153
  inputref: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
139
154
  current: PropTypes.any
140
155
  })]),
156
+ /**
157
+ * Specify the description for the loading text
158
+ */
159
+ loadingDescription: PropTypes.string,
160
+ /**
161
+ * Specify the description for the loading text
162
+ */
163
+ loadingIconDescription: PropTypes.string,
164
+ /**
165
+ * loading status
166
+ */
167
+ loadingStatus: PropTypes.oneOf(['inactive', 'active', 'finished', 'error']),
168
+ /**
169
+ * Provide an optional handler to be invoked when loading is
170
+ * successful
171
+ */
172
+ onLoadingSuccess: PropTypes.func,
141
173
  /**
142
174
  * Specify an optional function for when the modal is requesting to be
143
175
  * closed
@@ -40,7 +40,8 @@ function useContextMenu() {
40
40
  open,
41
41
  x: position[0],
42
42
  y: position[1],
43
- onClose
43
+ onClose,
44
+ mode: 'full'
44
45
  };
45
46
  }
46
47
 
@@ -63,7 +63,7 @@ const DataTableSkeleton = _ref => {
63
63
  }, rest), /*#__PURE__*/React__default.createElement("thead", null, /*#__PURE__*/React__default.createElement("tr", null, columnsArray.map(i => /*#__PURE__*/React__default.createElement("th", {
64
64
  key: i
65
65
  }, headers ? /*#__PURE__*/React__default.createElement("div", {
66
- className: "bx--table-header-label"
66
+ className: "cds--table-header-label"
67
67
  }, headers[i]?.header) : _span2 || (_span2 = /*#__PURE__*/React__default.createElement("span", null)))))), /*#__PURE__*/React__default.createElement("tbody", null, rows)));
68
68
  };
69
69
  DataTableSkeleton.propTypes = {
@@ -76,6 +76,10 @@ interface DatePickerInputProps extends Omit<ReactAttr<HTMLInputElement>, Exclude
76
76
  * Specify the size of the Date Picker Input. Currently supports either `sm`, `md`, or `lg` as an option.
77
77
  */
78
78
  size?: 'sm' | 'md' | 'lg';
79
+ /**
80
+ * Provide a `Slug` component to be rendered inside the `DatePickerInput` component
81
+ */
82
+ slug?: ReactNodeLike;
79
83
  /**
80
84
  * Specify the type of the `<input>`
81
85
  */
@@ -32,6 +32,7 @@ const DatePickerInput = /*#__PURE__*/React__default.forwardRef(function DatePick
32
32
  pattern = '\\d{1,2}\\/\\d{1,2}\\/\\d{4}',
33
33
  placeholder,
34
34
  size = 'md',
35
+ slug,
35
36
  type = 'text',
36
37
  warn,
37
38
  warnText,
@@ -60,7 +61,8 @@ const DatePickerInput = /*#__PURE__*/React__default.forwardRef(function DatePick
60
61
  };
61
62
  const wrapperClasses = cx(`${prefix}--date-picker-input__wrapper`, {
62
63
  [`${prefix}--date-picker-input__wrapper--invalid`]: invalid,
63
- [`${prefix}--date-picker-input__wrapper--warn`]: warn
64
+ [`${prefix}--date-picker-input__wrapper--warn`]: warn,
65
+ [`${prefix}--date-picker-input__wrapper--slug`]: slug
64
66
  });
65
67
  const labelClasses = cx(`${prefix}--label`, {
66
68
  [`${prefix}--visually-hidden`]: hideLabel,
@@ -93,6 +95,14 @@ const DatePickerInput = /*#__PURE__*/React__default.forwardRef(function DatePick
93
95
  inputProps['data-invalid'] = true;
94
96
  }
95
97
  const input = /*#__PURE__*/React__default.createElement("input", inputProps);
98
+
99
+ // Slug is always size `mini`
100
+ let normalizedSlug;
101
+ if (slug) {
102
+ normalizedSlug = /*#__PURE__*/React__default.cloneElement(slug, {
103
+ size: 'mini'
104
+ });
105
+ }
96
106
  return /*#__PURE__*/React__default.createElement("div", {
97
107
  className: containerClasses
98
108
  }, labelText && /*#__PURE__*/React__default.createElement(Text, {
@@ -101,7 +111,7 @@ const DatePickerInput = /*#__PURE__*/React__default.forwardRef(function DatePick
101
111
  className: labelClasses
102
112
  }, labelText), /*#__PURE__*/React__default.createElement("div", {
103
113
  className: wrapperClasses
104
- }, /*#__PURE__*/React__default.createElement("span", null, input, isFluid && /*#__PURE__*/React__default.createElement(DatePickerIcon, {
114
+ }, /*#__PURE__*/React__default.createElement("span", null, input, normalizedSlug, isFluid && /*#__PURE__*/React__default.createElement(DatePickerIcon, {
105
115
  datePickerType: datePickerType
106
116
  }), /*#__PURE__*/React__default.createElement(DatePickerIcon, {
107
117
  datePickerType: datePickerType,
@@ -195,6 +205,10 @@ DatePickerInput.propTypes = {
195
205
  * Specify the size of the Date Picker Input. Currently supports either `sm`, `md`, or `lg` as an option.
196
206
  */
197
207
  size: PropTypes.oneOf(['sm', 'md', 'lg']),
208
+ /**
209
+ * Provide a `Slug` component to be rendered inside the `DatePickerInput` component
210
+ */
211
+ slug: PropTypes.node,
198
212
  /**
199
213
  * Specify the type of the `<input>`
200
214
  */
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import React, { ReactNode } from 'react';
8
8
  import { UseSelectProps } from 'downshift';
9
+ import { ReactNodeLike } from 'prop-types';
9
10
  import { ListBoxSize, ListBoxType } from '../ListBox';
10
11
  import { ReactAttr } from '../../types/common';
11
12
  type ExcludedAttributes = 'id' | 'onChange';
@@ -110,6 +111,10 @@ export interface DropdownProps<ItemType> extends Omit<ReactAttr<HTMLDivElement>,
110
111
  * Specify the size of the ListBox. Currently supports either `sm`, `md` or `lg` as an option.
111
112
  */
112
113
  size?: ListBoxSize;
114
+ /**
115
+ * Provide a `Slug` component to be rendered inside the `Dropdown` component
116
+ */
117
+ slug?: ReactNodeLike;
113
118
  /**
114
119
  * Provide the title text that will be read by a screen reader when
115
120
  * visiting this control
@@ -69,6 +69,7 @@ const Dropdown = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
69
69
  selectedItem: controlledSelectedItem,
70
70
  downshiftProps,
71
71
  readOnly,
72
+ slug,
72
73
  ...other
73
74
  } = _ref;
74
75
  const prefix = usePrefix();
@@ -159,7 +160,8 @@ const Dropdown = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
159
160
  [`${prefix}--dropdown__wrapper--inline--invalid`]: inline && invalid,
160
161
  [`${prefix}--list-box__wrapper--inline--invalid`]: inline && invalid,
161
162
  [`${prefix}--list-box__wrapper--fluid--invalid`]: isFluid && invalid,
162
- [`${prefix}--list-box__wrapper--fluid--focus`]: isFluid && isFocused && !isOpen
163
+ [`${prefix}--list-box__wrapper--fluid--focus`]: isFluid && isFocused && !isOpen,
164
+ [`${prefix}--list-box__wrapper--slug`]: slug
163
165
  });
164
166
  const helperId = !helperText ? undefined : `dropdown-helper-text-${dropdownInstanceId}`;
165
167
 
@@ -223,6 +225,14 @@ const Dropdown = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
223
225
  }
224
226
  };
225
227
  const menuProps = getMenuProps();
228
+
229
+ // Slug is always size `mini`
230
+ let normalizedSlug;
231
+ if (slug) {
232
+ normalizedSlug = /*#__PURE__*/React__default.cloneElement(slug, {
233
+ size: 'mini'
234
+ });
235
+ }
226
236
  return /*#__PURE__*/React__default.createElement("div", _extends({
227
237
  className: wrapperClasses
228
238
  }, other), titleText && /*#__PURE__*/React__default.createElement("label", _extends({
@@ -261,12 +271,15 @@ const Dropdown = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
261
271
  }, selectedItem ? renderSelectedItem ? renderSelectedItem(selectedItem) : itemToString(selectedItem) : label), /*#__PURE__*/React__default.createElement(ListBox.MenuIcon, {
262
272
  isOpen: isOpen,
263
273
  translateWithId: translateWithId
264
- })), /*#__PURE__*/React__default.createElement(ListBox.Menu, menuProps, isOpen && items.map((item, index) => {
274
+ })), normalizedSlug, /*#__PURE__*/React__default.createElement(ListBox.Menu, menuProps, isOpen && items.map((item, index) => {
265
275
  const isObject = item !== null && typeof item === 'object';
266
276
  const itemProps = getItemProps({
267
277
  item,
268
278
  index
269
279
  });
280
+ if (item !== null && typeof item === 'object' && Object.prototype.hasOwnProperty.call(item, 'id')) {
281
+ itemProps.id = item['id'];
282
+ }
270
283
  const title = isObject && 'text' in item && itemToElement ? item.text : itemToString(item);
271
284
  return /*#__PURE__*/React__default.createElement(ListBox.MenuItem, _extends({
272
285
  key: itemProps.id,
@@ -294,7 +307,7 @@ Dropdown.propTypes = {
294
307
  */
295
308
  ariaLabel: deprecate(PropTypes.string, 'This prop syntax has been deprecated. Please use the new `aria-label`.'),
296
309
  /**
297
- * Provide a custom className to be applied on the bx--dropdown node
310
+ * Provide a custom className to be applied on the cds--dropdown node
298
311
  */
299
312
  className: PropTypes.string,
300
313
  /**
@@ -382,6 +395,10 @@ Dropdown.propTypes = {
382
395
  * Specify the size of the ListBox. Currently supports either `sm`, `md` or `lg` as an option.
383
396
  */
384
397
  size: ListBoxSize,
398
+ /**
399
+ * Provide a `Slug` component to be rendered inside the `Dropdown` component
400
+ */
401
+ slug: PropTypes.node,
385
402
  /**
386
403
  * Provide the title text that will be read by a screen reader when
387
404
  * visiting this control
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2023
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import InlineLoading from './InlineLoading.js';
9
+ export { default as InlineLoading, default } from './InlineLoading.js';
@@ -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
@@ -13,6 +13,7 @@ import { usePrefix } from '../../internal/usePrefix.js';
13
13
 
14
14
  const Link = /*#__PURE__*/React__default.forwardRef(function Link(_ref, ref) {
15
15
  let {
16
+ as: BaseComponent,
16
17
  children,
17
18
  className: customClassName,
18
19
  href,
@@ -33,7 +34,7 @@ const Link = /*#__PURE__*/React__default.forwardRef(function Link(_ref, ref) {
33
34
  });
34
35
  const rel = target === '_blank' ? 'noopener' : undefined;
35
36
  const linkProps = {
36
- className,
37
+ className: BaseComponent ? undefined : className,
37
38
  rel,
38
39
  target
39
40
  };
@@ -46,7 +47,8 @@ const Link = /*#__PURE__*/React__default.forwardRef(function Link(_ref, ref) {
46
47
  linkProps.role = 'link';
47
48
  linkProps['aria-disabled'] = true;
48
49
  }
49
- return /*#__PURE__*/React__default.createElement("a", _extends({
50
+ const BaseComponentAsAny = BaseComponent ?? 'a';
51
+ return /*#__PURE__*/React__default.createElement(BaseComponentAsAny, _extends({
50
52
  ref: ref
51
53
  }, linkProps, rest), children, !inline && Icon && /*#__PURE__*/React__default.createElement("div", {
52
54
  className: `${prefix}--link__icon`
@@ -54,6 +56,11 @@ const Link = /*#__PURE__*/React__default.forwardRef(function Link(_ref, ref) {
54
56
  });
55
57
  Link.displayName = 'Link';
56
58
  Link.propTypes = {
59
+ /**
60
+ * Provide a custom element or component to render the top-level node for the
61
+ * component.
62
+ */
63
+ as: PropTypes.string,
57
64
  /**
58
65
  * Provide the content for the Link
59
66
  */
@@ -12,6 +12,7 @@ import React__default, { useRef, useContext, useReducer, useMemo, useState, useE
12
12
  import { createPortal } from 'react-dom';
13
13
  import { useMergedRefs } from '../../internal/useMergedRefs.js';
14
14
  import { usePrefix } from '../../internal/usePrefix.js';
15
+ import { warning } from '../../internal/warning.js';
15
16
  import { MenuContext, menuReducer } from './MenuContext.js';
16
17
  import { useLayoutDirection } from '../LayoutDirection/useLayoutDirection.js';
17
18
  import { match } from '../../internal/keyboard/match.js';
@@ -24,6 +25,7 @@ const Menu = /*#__PURE__*/React__default.forwardRef(function Menu(_ref, forwardR
24
25
  children,
25
26
  className,
26
27
  label,
28
+ mode = 'full',
27
29
  onClose,
28
30
  onOpen,
29
31
  open,
@@ -37,10 +39,14 @@ const Menu = /*#__PURE__*/React__default.forwardRef(function Menu(_ref, forwardR
37
39
  const focusReturn = useRef(null);
38
40
  const context = useContext(MenuContext);
39
41
  const isRoot = context.state.isRoot;
42
+ if (context.state.mode === 'basic' && !isRoot) {
43
+ process.env.NODE_ENV !== "production" ? warning(false, 'Nested menus are not supported when the menu is in "basic" mode.') : void 0;
44
+ }
40
45
  const menuSize = isRoot ? size : context.state.size;
41
46
  const [childState, childDispatch] = useReducer(menuReducer, {
42
47
  ...context.state,
43
48
  isRoot: false,
49
+ mode,
44
50
  size,
45
51
  requestCloseRoot: isRoot ? handleClose : context.state.requestCloseRoot
46
52
  });
@@ -245,6 +251,14 @@ Menu.propTypes = {
245
251
  * A label describing the Menu.
246
252
  */
247
253
  label: PropTypes.string,
254
+ /**
255
+ * The mode of this menu. Defaults to full.
256
+ * `full` supports nesting and selectable menu items, but no icons.
257
+ * `basic` supports icons but no nesting or selectable menu items.
258
+ *
259
+ * **This prop is not intended for use and will be set by the respective implementation (like useContextMenu, MenuButton, and ComboButton).**
260
+ */
261
+ mode: PropTypes.oneOf(['full', 'basic']),
248
262
  /**
249
263
  * Provide an optional function to be called when the Menu should be closed.
250
264
  */
@@ -9,6 +9,7 @@ import React__default from 'react';
9
9
 
10
10
  const menuDefaultState = {
11
11
  isRoot: true,
12
+ mode: 'full',
12
13
  hasIcons: false,
13
14
  size: null,
14
15
  items: [],