@carbon/react 1.42.1 → 1.43.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 (59) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +2542 -1275
  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 +16 -2
  5. package/es/components/ComposedModal/ModalFooter.d.ts +18 -0
  6. package/es/components/ComposedModal/ModalFooter.js +48 -16
  7. package/es/components/DatePickerInput/DatePickerInput.d.ts +4 -0
  8. package/es/components/DatePickerInput/DatePickerInput.js +16 -2
  9. package/es/components/Dropdown/Dropdown.d.ts +5 -0
  10. package/es/components/Dropdown/Dropdown.js +16 -2
  11. package/es/components/InlineLoading/index.js +9 -0
  12. package/es/components/Modal/Modal.d.ts +17 -0
  13. package/es/components/Modal/Modal.js +38 -3
  14. package/es/components/MultiSelect/FilterableMultiSelect.js +17 -3
  15. package/es/components/MultiSelect/MultiSelect.d.ts +5 -0
  16. package/es/components/MultiSelect/MultiSelect.js +17 -3
  17. package/es/components/NumberInput/NumberInput.d.ts +5 -0
  18. package/es/components/NumberInput/NumberInput.js +29 -4
  19. package/es/components/Select/Select.d.ts +6 -1
  20. package/es/components/Select/Select.js +16 -2
  21. package/es/components/Slug/index.js +187 -0
  22. package/es/components/TextArea/TextArea.d.ts +4 -0
  23. package/es/components/TextArea/TextArea.js +47 -31
  24. package/es/components/TextInput/TextInput.d.ts +5 -0
  25. package/es/components/TextInput/TextInput.js +16 -2
  26. package/es/components/UIShell/SideNavHeader.d.ts +29 -0
  27. package/es/components/UIShell/SideNavHeader.js +3 -3
  28. package/es/index.d.ts +1 -0
  29. package/es/index.js +1 -0
  30. package/lib/components/Breadcrumb/BreadcrumbItem.js +1 -2
  31. package/lib/components/ComboBox/ComboBox.d.ts +5 -0
  32. package/lib/components/ComboBox/ComboBox.js +16 -2
  33. package/lib/components/ComposedModal/ModalFooter.d.ts +18 -0
  34. package/lib/components/ComposedModal/ModalFooter.js +48 -16
  35. package/lib/components/DatePickerInput/DatePickerInput.d.ts +4 -0
  36. package/lib/components/DatePickerInput/DatePickerInput.js +16 -2
  37. package/lib/components/Dropdown/Dropdown.d.ts +5 -0
  38. package/lib/components/Dropdown/Dropdown.js +16 -2
  39. package/lib/components/InlineLoading/index.js +17 -0
  40. package/lib/components/Modal/Modal.d.ts +17 -0
  41. package/lib/components/Modal/Modal.js +38 -3
  42. package/lib/components/MultiSelect/FilterableMultiSelect.js +17 -3
  43. package/lib/components/MultiSelect/MultiSelect.d.ts +5 -0
  44. package/lib/components/MultiSelect/MultiSelect.js +17 -3
  45. package/lib/components/NumberInput/NumberInput.d.ts +5 -0
  46. package/lib/components/NumberInput/NumberInput.js +28 -3
  47. package/lib/components/Select/Select.d.ts +6 -1
  48. package/lib/components/Select/Select.js +16 -2
  49. package/lib/components/Slug/index.js +199 -0
  50. package/lib/components/TextArea/TextArea.d.ts +4 -0
  51. package/lib/components/TextArea/TextArea.js +47 -31
  52. package/lib/components/TextInput/TextInput.d.ts +5 -0
  53. package/lib/components/TextInput/TextInput.js +16 -2
  54. package/lib/components/UIShell/SideNavHeader.d.ts +29 -0
  55. package/lib/components/UIShell/SideNavHeader.js +3 -3
  56. package/lib/index.d.ts +1 -0
  57. package/lib/index.js +45 -41
  58. package/package.json +6 -6
  59. package/scss/utilities/_ai-gradient.scss +9 -0
package/es/index.js CHANGED
@@ -133,6 +133,7 @@ export { Layer, useLayer } from './components/Layer/index.js';
133
133
  export { Layout as unstable_Layout } from './components/Layout/index.js';
134
134
  export { OverflowMenuV2 as unstable_OverflowMenuV2 } from './components/OverflowMenuV2/index.js';
135
135
  export { Popover, PopoverContent } from './components/Popover/index.js';
136
+ export { Slug as unstable__Slug, SlugActions as unstable__SlugActions, SlugContent as unstable__SlugContent } from './components/Slug/index.js';
136
137
  export { HStack, VStack } from './components/Stack/index.js';
137
138
  export { DefinitionTooltip } from './components/Tooltip/DefinitionTooltip.js';
138
139
  export { Tooltip } from './components/Tooltip/Tooltip.js';
@@ -79,8 +79,7 @@ const BreadcrumbItem = /*#__PURE__*/React__default["default"].forwardRef(functio
79
79
  });
80
80
  BreadcrumbItem.displayName = 'BreadcrumbItem';
81
81
  BreadcrumbItem.propTypes = {
82
- // @ts-expect-error - v12 TODO: BREAKING: This should match AriaAttributes['aria-current']
83
- 'aria-current': PropTypes__default["default"].oneOfType([PropTypes__default["default"].string, PropTypes__default["default"].bool]),
82
+ 'aria-current': PropTypes__default["default"].oneOfType([PropTypes__default["default"].bool, PropTypes__default["default"].oneOf(['false', 'true', 'page', 'step', 'location', 'date', 'time'])]),
84
83
  /**
85
84
  * Pass in content that will be inside of the BreadcrumbItem
86
85
  */
@@ -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.
@@ -123,6 +123,7 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
123
123
  warn,
124
124
  warnText,
125
125
  allowCustomValue = false,
126
+ slug,
126
127
  ...rest
127
128
  } = props;
128
129
  const prefix = usePrefix.usePrefix();
@@ -254,7 +255,8 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
254
255
  });
255
256
  const wrapperClasses = cx__default["default"](`${prefix}--list-box__wrapper`, [containerClassName, {
256
257
  [`${prefix}--list-box__wrapper--fluid--invalid`]: isFluid && invalid,
257
- [`${prefix}--list-box__wrapper--fluid--focus`]: isFluid && isFocused
258
+ [`${prefix}--list-box__wrapper--fluid--focus`]: isFluid && isFocused,
259
+ [`${prefix}--list-box__wrapper--slug`]: slug
258
260
  }]);
259
261
  const inputClasses = cx__default["default"](`${prefix}--text-input`, {
260
262
  [`${prefix}--text-input--empty`]: !inputValue,
@@ -263,6 +265,14 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
263
265
 
264
266
  // needs to be Capitalized for react to render it correctly
265
267
  const ItemToElement = itemToElement;
268
+
269
+ // Slug is always size `mini`
270
+ let normalizedSlug;
271
+ if (slug) {
272
+ normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
273
+ size: 'mini'
274
+ });
275
+ }
266
276
  return /*#__PURE__*/React__default["default"].createElement(Downshift__default["default"], _rollupPluginBabelHelpers["extends"]({}, downshiftProps, {
267
277
  onChange: handleOnChange,
268
278
  onInputValueChange: handleOnInputValueChange,
@@ -413,7 +423,7 @@ const ComboBox = /*#__PURE__*/React.forwardRef((props, ref) => {
413
423
  }), /*#__PURE__*/React__default["default"].createElement(ListBoxTrigger["default"], _rollupPluginBabelHelpers["extends"]({}, buttonProps, {
414
424
  isOpen: isOpen,
415
425
  translateWithId: translateWithId
416
- }))), /*#__PURE__*/React__default["default"].createElement(index["default"].Menu, getMenuProps({
426
+ }))), normalizedSlug, /*#__PURE__*/React__default["default"].createElement(index["default"].Menu, getMenuProps({
417
427
  'aria-label': deprecatedAriaLabel || ariaLabel
418
428
  }), isOpen ? filterItems(items, itemToString, inputValue).map((item, index$1) => {
419
429
  const isObject = item !== null && typeof item === 'object';
@@ -563,6 +573,10 @@ ComboBox.propTypes = {
563
573
  * Specify the size of the ListBox. Currently supports either `sm`, `md` or `lg` as an option.
564
574
  */
565
575
  size: ListBoxPropTypes.ListBoxSize,
576
+ /**
577
+ * Provide a `Slug` component to be rendered inside the `ComboBox` component
578
+ */
579
+ slug: PropTypes__default["default"].node,
566
580
  /**
567
581
  * Provide text to be used in a `<label>` element that is tied to the
568
582
  * combobox via ARIA attributes.
@@ -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 {};
@@ -18,6 +18,7 @@ var ButtonSet = require('../ButtonSet/ButtonSet.js');
18
18
  var cx = require('classnames');
19
19
  var usePrefix = require('../../internal/usePrefix.js');
20
20
  var noopFn = require('../../internal/noopFn.js');
21
+ var InlineLoading = require('../InlineLoading/InlineLoading.js');
21
22
 
22
23
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
23
24
 
@@ -31,7 +32,8 @@ function SecondaryButtonSet(_ref) {
31
32
  secondaryButtonText,
32
33
  secondaryClassName,
33
34
  closeModal,
34
- onRequestClose
35
+ onRequestClose,
36
+ disabled
35
37
  } = _ref;
36
38
  function handleRequestClose(evt) {
37
39
  closeModal(evt);
@@ -53,6 +55,7 @@ function SecondaryButtonSet(_ref) {
53
55
  }
54
56
  if (secondaryButtonText) {
55
57
  return /*#__PURE__*/React__default["default"].createElement(Button["default"], {
58
+ disabled: disabled,
56
59
  className: secondaryClassName,
57
60
  onClick: handleRequestClose,
58
61
  kind: "secondary"
@@ -62,6 +65,7 @@ function SecondaryButtonSet(_ref) {
62
65
  }
63
66
  SecondaryButtonSet.propTypes = {
64
67
  closeModal: PropTypes__default["default"].func,
68
+ disabled: PropTypes__default["default"].bool,
65
69
  onRequestClose: PropTypes__default["default"].func,
66
70
  secondaryButtonText: PropTypes__default["default"].string,
67
71
  secondaryButtons: (props, propName, componentName) => {
@@ -96,32 +100,43 @@ const ModalFooter = /*#__PURE__*/React__default["default"].forwardRef(function M
96
100
  secondaryButtonText,
97
101
  secondaryButtons,
98
102
  secondaryClassName,
103
+ loadingStatus = 'inactive',
104
+ loadingDescription,
105
+ loadingIconDescription,
106
+ onLoadingSuccess = noopFn.noopFn,
99
107
  ...rest
100
108
  } = _ref3;
101
109
  const prefix = usePrefix.usePrefix();
102
110
  const footerClass = cx__default["default"](`${prefix}--modal-footer`, customClassName, Array.isArray(secondaryButtons) && secondaryButtons.length === 2 ? `${prefix}--modal-footer--three-button` : null);
111
+ const primaryButtonClass = cx__default["default"](primaryClassName, loadingStatus !== 'inactive' ? `${prefix}--btn--loading` : null);
112
+ const loadingActive = loadingStatus !== 'inactive';
103
113
  const secondaryButtonProps = {
104
114
  closeModal,
105
115
  secondaryButtons,
106
116
  secondaryButtonText,
107
117
  secondaryClassName,
108
- onRequestClose
118
+ onRequestClose,
119
+ disabled: loadingActive
109
120
  };
110
- return (
111
- /*#__PURE__*/
121
+ return /*#__PURE__*/React__default["default"].createElement(ButtonSet["default"], _rollupPluginBabelHelpers["extends"]({
122
+ className: footerClass
123
+ }, rest, {
112
124
  // @ts-expect-error: Invalid derived types, will be fine once explicit types are added
113
- React__default["default"].createElement(ButtonSet["default"], _rollupPluginBabelHelpers["extends"]({
114
- className: footerClass
115
- }, rest, {
116
- ref: ref
117
- }), /*#__PURE__*/React__default["default"].createElement(SecondaryButtonSet, secondaryButtonProps), primaryButtonText && /*#__PURE__*/React__default["default"].createElement(Button["default"], {
118
- onClick: onRequestSubmit,
119
- className: primaryClassName,
120
- disabled: primaryButtonDisabled,
121
- kind: danger ? 'danger' : 'primary',
122
- ref: inputref
123
- }, primaryButtonText), children)
124
- );
125
+ ref: ref,
126
+ "aria-busy": loadingActive
127
+ }), /*#__PURE__*/React__default["default"].createElement(SecondaryButtonSet, secondaryButtonProps), primaryButtonText && /*#__PURE__*/React__default["default"].createElement(Button["default"], {
128
+ onClick: onRequestSubmit,
129
+ className: primaryButtonClass,
130
+ disabled: loadingActive || primaryButtonDisabled,
131
+ kind: danger ? 'danger' : 'primary',
132
+ ref: inputref
133
+ }, loadingStatus === 'inactive' ? primaryButtonText : /*#__PURE__*/React__default["default"].createElement(InlineLoading["default"], {
134
+ status: loadingStatus,
135
+ description: loadingDescription,
136
+ iconDescription: loadingIconDescription,
137
+ className: `${prefix}--inline-loading--btn`,
138
+ onSuccess: onLoadingSuccess
139
+ })), children);
125
140
  });
126
141
  ModalFooter.propTypes = {
127
142
  /**
@@ -148,6 +163,23 @@ ModalFooter.propTypes = {
148
163
  inputref: PropTypes__default["default"].oneOfType([PropTypes__default["default"].func, PropTypes__default["default"].shape({
149
164
  current: PropTypes__default["default"].any
150
165
  })]),
166
+ /**
167
+ * Specify the description for the loading text
168
+ */
169
+ loadingDescription: PropTypes__default["default"].string,
170
+ /**
171
+ * Specify the description for the loading text
172
+ */
173
+ loadingIconDescription: PropTypes__default["default"].string,
174
+ /**
175
+ * loading status
176
+ */
177
+ loadingStatus: PropTypes__default["default"].oneOf(['inactive', 'active', 'finished', 'error']),
178
+ /**
179
+ * Provide an optional handler to be invoked when loading is
180
+ * successful
181
+ */
182
+ onLoadingSuccess: PropTypes__default["default"].func,
151
183
  /**
152
184
  * Specify an optional function for when the modal is requesting to be
153
185
  * closed
@@ -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
  */
@@ -42,6 +42,7 @@ const DatePickerInput = /*#__PURE__*/React__default["default"].forwardRef(functi
42
42
  pattern = '\\d{1,2}\\/\\d{1,2}\\/\\d{4}',
43
43
  placeholder,
44
44
  size = 'md',
45
+ slug,
45
46
  type = 'text',
46
47
  warn,
47
48
  warnText,
@@ -70,7 +71,8 @@ const DatePickerInput = /*#__PURE__*/React__default["default"].forwardRef(functi
70
71
  };
71
72
  const wrapperClasses = cx__default["default"](`${prefix}--date-picker-input__wrapper`, {
72
73
  [`${prefix}--date-picker-input__wrapper--invalid`]: invalid,
73
- [`${prefix}--date-picker-input__wrapper--warn`]: warn
74
+ [`${prefix}--date-picker-input__wrapper--warn`]: warn,
75
+ [`${prefix}--date-picker-input__wrapper--slug`]: slug
74
76
  });
75
77
  const labelClasses = cx__default["default"](`${prefix}--label`, {
76
78
  [`${prefix}--visually-hidden`]: hideLabel,
@@ -103,6 +105,14 @@ const DatePickerInput = /*#__PURE__*/React__default["default"].forwardRef(functi
103
105
  inputProps['data-invalid'] = true;
104
106
  }
105
107
  const input = /*#__PURE__*/React__default["default"].createElement("input", inputProps);
108
+
109
+ // Slug is always size `mini`
110
+ let normalizedSlug;
111
+ if (slug) {
112
+ normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
113
+ size: 'mini'
114
+ });
115
+ }
106
116
  return /*#__PURE__*/React__default["default"].createElement("div", {
107
117
  className: containerClasses
108
118
  }, labelText && /*#__PURE__*/React__default["default"].createElement(Text.Text, {
@@ -111,7 +121,7 @@ const DatePickerInput = /*#__PURE__*/React__default["default"].forwardRef(functi
111
121
  className: labelClasses
112
122
  }, labelText), /*#__PURE__*/React__default["default"].createElement("div", {
113
123
  className: wrapperClasses
114
- }, /*#__PURE__*/React__default["default"].createElement("span", null, input, isFluid && /*#__PURE__*/React__default["default"].createElement(DatePickerIcon, {
124
+ }, /*#__PURE__*/React__default["default"].createElement("span", null, input, normalizedSlug, isFluid && /*#__PURE__*/React__default["default"].createElement(DatePickerIcon, {
115
125
  datePickerType: datePickerType
116
126
  }), /*#__PURE__*/React__default["default"].createElement(DatePickerIcon, {
117
127
  datePickerType: datePickerType,
@@ -205,6 +215,10 @@ DatePickerInput.propTypes = {
205
215
  * Specify the size of the Date Picker Input. Currently supports either `sm`, `md`, or `lg` as an option.
206
216
  */
207
217
  size: PropTypes__default["default"].oneOf(['sm', 'md', 'lg']),
218
+ /**
219
+ * Provide a `Slug` component to be rendered inside the `DatePickerInput` component
220
+ */
221
+ slug: PropTypes__default["default"].node,
208
222
  /**
209
223
  * Specify the type of the `<input>`
210
224
  */
@@ -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
@@ -79,6 +79,7 @@ const Dropdown = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) =
79
79
  selectedItem: controlledSelectedItem,
80
80
  downshiftProps,
81
81
  readOnly,
82
+ slug,
82
83
  ...other
83
84
  } = _ref;
84
85
  const prefix = usePrefix.usePrefix();
@@ -169,7 +170,8 @@ const Dropdown = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) =
169
170
  [`${prefix}--dropdown__wrapper--inline--invalid`]: inline && invalid,
170
171
  [`${prefix}--list-box__wrapper--inline--invalid`]: inline && invalid,
171
172
  [`${prefix}--list-box__wrapper--fluid--invalid`]: isFluid && invalid,
172
- [`${prefix}--list-box__wrapper--fluid--focus`]: isFluid && isFocused && !isOpen
173
+ [`${prefix}--list-box__wrapper--fluid--focus`]: isFluid && isFocused && !isOpen,
174
+ [`${prefix}--list-box__wrapper--slug`]: slug
173
175
  });
174
176
  const helperId = !helperText ? undefined : `dropdown-helper-text-${dropdownInstanceId}`;
175
177
 
@@ -233,6 +235,14 @@ const Dropdown = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) =
233
235
  }
234
236
  };
235
237
  const menuProps = getMenuProps();
238
+
239
+ // Slug is always size `mini`
240
+ let normalizedSlug;
241
+ if (slug) {
242
+ normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
243
+ size: 'mini'
244
+ });
245
+ }
236
246
  return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({
237
247
  className: wrapperClasses
238
248
  }, other), titleText && /*#__PURE__*/React__default["default"].createElement("label", _rollupPluginBabelHelpers["extends"]({
@@ -271,7 +281,7 @@ const Dropdown = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref) =
271
281
  }, selectedItem ? renderSelectedItem ? renderSelectedItem(selectedItem) : itemToString(selectedItem) : label), /*#__PURE__*/React__default["default"].createElement(index["default"].MenuIcon, {
272
282
  isOpen: isOpen,
273
283
  translateWithId: translateWithId
274
- })), /*#__PURE__*/React__default["default"].createElement(index["default"].Menu, menuProps, isOpen && items.map((item, index$1) => {
284
+ })), normalizedSlug, /*#__PURE__*/React__default["default"].createElement(index["default"].Menu, menuProps, isOpen && items.map((item, index$1) => {
275
285
  const isObject = item !== null && typeof item === 'object';
276
286
  const itemProps = getItemProps({
277
287
  item,
@@ -392,6 +402,10 @@ Dropdown.propTypes = {
392
402
  * Specify the size of the ListBox. Currently supports either `sm`, `md` or `lg` as an option.
393
403
  */
394
404
  size: ListBoxPropTypes.ListBoxSize,
405
+ /**
406
+ * Provide a `Slug` component to be rendered inside the `Dropdown` component
407
+ */
408
+ slug: PropTypes__default["default"].node,
395
409
  /**
396
410
  * Provide the title text that will be read by a screen reader when
397
411
  * visiting this control
@@ -0,0 +1,17 @@
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
+ 'use strict';
9
+
10
+ Object.defineProperty(exports, '__esModule', { value: true });
11
+
12
+ var InlineLoading = require('./InlineLoading.js');
13
+
14
+
15
+
16
+ exports.InlineLoading = InlineLoading["default"];
17
+ exports["default"] = InlineLoading["default"];
@@ -54,6 +54,18 @@ export interface ModalProps extends ReactAttr<HTMLDivElement> {
54
54
  * Provide a ref to return focus to once the modal is closed.
55
55
  */
56
56
  launcherButtonRef?: any;
57
+ /**
58
+ * Specify the description for the loading text
59
+ */
60
+ loadingDescription?: string;
61
+ /**
62
+ * Specify the description for the loading text
63
+ */
64
+ loadingIconDescription?: string;
65
+ /**
66
+ * Specify loading status
67
+ */
68
+ loadingStatus?: string;
57
69
  /**
58
70
  * Specify a label to be read by screen readers on the modal root node
59
71
  */
@@ -71,6 +83,11 @@ export interface ModalProps extends ReactAttr<HTMLDivElement> {
71
83
  * @deprecated this property is unused
72
84
  */
73
85
  onKeyDown?: React.KeyboardEventHandler<HTMLElement>;
86
+ /**
87
+ * Specify an optional handler to be invoked when loading is
88
+ * successful
89
+ */
90
+ onLoadingSuccess?: React.ReactEventHandler<HTMLElement>;
74
91
  /**
75
92
  * Specify a handler for closing modal.
76
93
  * The handler should care of closing modal, e.g. changing `open` prop.
@@ -18,6 +18,7 @@ var toggleClass = require('../../tools/toggleClass.js');
18
18
  var Button = require('../Button/Button.js');
19
19
  require('../Button/Button.Skeleton.js');
20
20
  var ButtonSet = require('../ButtonSet/ButtonSet.js');
21
+ var InlineLoading = require('../InlineLoading/InlineLoading.js');
21
22
  var requiredIfGivenPropIsTruthy = require('../../prop-types/requiredIfGivenPropIsTruthy.js');
22
23
  var wrapFocus = require('../../internal/wrapFocus.js');
23
24
  var setupGetInstanceId = require('../../tools/setupGetInstanceId.js');
@@ -64,6 +65,10 @@ const Modal = /*#__PURE__*/React__default["default"].forwardRef(function Modal(_
64
65
  preventCloseOnClickOutside = false,
65
66
  isFullWidth,
66
67
  launcherButtonRef,
68
+ loadingStatus = 'inactive',
69
+ loadingDescription,
70
+ loadingIconDescription,
71
+ onLoadingSuccess = noopFn.noopFn,
67
72
  ...rest
68
73
  } = _ref;
69
74
  const prefix = usePrefix.usePrefix();
@@ -77,6 +82,10 @@ const Modal = /*#__PURE__*/React__default["default"].forwardRef(function Modal(_
77
82
  const modalHeadingId = `${prefix}--modal-header__heading--${modalInstanceId}`;
78
83
  const modalBodyId = `${prefix}--modal-body--${modalInstanceId}`;
79
84
  const modalCloseButtonClass = `${prefix}--modal-close`;
85
+ const primaryButtonClass = cx__default["default"]({
86
+ [`${prefix}--btn--loading`]: loadingStatus !== 'inactive'
87
+ });
88
+ const loadingActive = loadingStatus !== 'inactive';
80
89
  function isCloseButton(element) {
81
90
  return !onSecondarySubmit && element === secondaryButton.current || element.classList.contains(modalCloseButtonClass);
82
91
  }
@@ -229,7 +238,8 @@ const Modal = /*#__PURE__*/React__default["default"].forwardRef(function Modal(_
229
238
  }, hasScrollingContentProps), children), hasScrollingContent && /*#__PURE__*/React__default["default"].createElement("div", {
230
239
  className: `${prefix}--modal-content--overflow-indicator`
231
240
  }), !passiveModal && /*#__PURE__*/React__default["default"].createElement(ButtonSet["default"], {
232
- className: footerClasses
241
+ className: footerClasses,
242
+ "aria-busy": loadingActive
233
243
  }, Array.isArray(secondaryButtons) && secondaryButtons.length <= 2 ? secondaryButtons.map((_ref3, i) => {
234
244
  let {
235
245
  buttonText,
@@ -241,15 +251,23 @@ const Modal = /*#__PURE__*/React__default["default"].forwardRef(function Modal(_
241
251
  onClick: onButtonClick
242
252
  }, buttonText);
243
253
  }) : secondaryButtonText && /*#__PURE__*/React__default["default"].createElement(Button["default"], {
254
+ disabled: loadingActive,
244
255
  kind: "secondary",
245
256
  onClick: onSecondaryButtonClick,
246
257
  ref: secondaryButton
247
258
  }, secondaryButtonText), /*#__PURE__*/React__default["default"].createElement(Button["default"], {
259
+ className: primaryButtonClass,
248
260
  kind: danger ? 'danger' : 'primary',
249
- disabled: primaryButtonDisabled,
261
+ disabled: loadingActive || primaryButtonDisabled,
250
262
  onClick: onRequestSubmit,
251
263
  ref: button
252
- }, primaryButtonText)));
264
+ }, loadingStatus === 'inactive' ? primaryButtonText : /*#__PURE__*/React__default["default"].createElement(InlineLoading["default"], {
265
+ status: loadingStatus,
266
+ description: loadingDescription,
267
+ iconDescription: loadingIconDescription,
268
+ className: `${prefix}--inline-loading--btn`,
269
+ onSuccess: onLoadingSuccess
270
+ }))));
253
271
  return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({}, rest, {
254
272
  onKeyDown: handleKeyDown,
255
273
  onMouseDown: handleMousedown,
@@ -313,6 +331,18 @@ Modal.propTypes = {
313
331
  launcherButtonRef: PropTypes__default["default"].oneOfType([PropTypes__default["default"].func, PropTypes__default["default"].shape({
314
332
  current: PropTypes__default["default"].any
315
333
  })]),
334
+ /**
335
+ * Specify the description for the loading text
336
+ */
337
+ loadingDescription: PropTypes__default["default"].string,
338
+ /**
339
+ * Specify the description for the loading text
340
+ */
341
+ loadingIconDescription: PropTypes__default["default"].string,
342
+ /**
343
+ * loading status
344
+ */
345
+ loadingStatus: PropTypes__default["default"].oneOf(['inactive', 'active', 'finished', 'error']),
316
346
  /**
317
347
  * Specify a label to be read by screen readers on the modal root node
318
348
  */
@@ -329,6 +359,11 @@ Modal.propTypes = {
329
359
  * Specify a handler for keypresses.
330
360
  */
331
361
  onKeyDown: PropTypes__default["default"].func,
362
+ /**
363
+ * Provide an optional handler to be invoked when loading is
364
+ * successful
365
+ */
366
+ onLoadingSuccess: PropTypes__default["default"].func,
332
367
  /**
333
368
  * Specify a handler for closing modal.
334
369
  * The handler should care of closing modal, e.g. changing `open` prop.
@@ -77,7 +77,8 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
77
77
  translateWithId,
78
78
  useTitleInItem,
79
79
  warn,
80
- warnText
80
+ warnText,
81
+ slug
81
82
  } = _ref;
82
83
  const {
83
84
  isFluid
@@ -106,7 +107,8 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
106
107
  [`${prefix}--list-box__wrapper--inline--invalid`]: inline && invalid,
107
108
  [`${prefix}--list-box--up`]: direction === 'top',
108
109
  [`${prefix}--list-box__wrapper--fluid--invalid`]: isFluid && invalid,
109
- [`${prefix}--list-box__wrapper--fluid--focus`]: isFluid && isFocused
110
+ [`${prefix}--list-box__wrapper--fluid--focus`]: isFluid && isFocused,
111
+ [`${prefix}--list-box__wrapper--slug`]: slug
110
112
  });
111
113
  const helperId = !helperText ? undefined : `filterablemultiselect-helper-text-${filterableMultiSelectInstanceId}`;
112
114
  const labelId = `${id}-label`;
@@ -200,6 +202,14 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
200
202
  textInput.current.focus();
201
203
  }
202
204
  }
205
+
206
+ // Slug is always size `mini`
207
+ let normalizedSlug;
208
+ if (slug) {
209
+ normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
210
+ size: 'mini'
211
+ });
212
+ }
203
213
  return /*#__PURE__*/React__default["default"].createElement(Selection["default"], {
204
214
  disabled: disabled,
205
215
  onChange: handleOnChange,
@@ -393,7 +403,7 @@ const FilterableMultiSelect = /*#__PURE__*/React__default["default"].forwardRef(
393
403
  }), /*#__PURE__*/React__default["default"].createElement(ListBoxTrigger["default"], _rollupPluginBabelHelpers["extends"]({}, buttonProps, {
394
404
  isOpen: isOpen,
395
405
  translateWithId: translateWithId
396
- }))), isOpen ? /*#__PURE__*/React__default["default"].createElement(index["default"].Menu, menuProps, sortItems(filterItems(items, {
406
+ }))), normalizedSlug, isOpen ? /*#__PURE__*/React__default["default"].createElement(index["default"].Menu, menuProps, sortItems(filterItems(items, {
397
407
  itemToString: itemToString$1,
398
408
  inputValue
399
409
  }), {
@@ -546,6 +556,10 @@ FilterableMultiSelect.propTypes = {
546
556
  * Specify the size of the ListBox. Currently supports either `sm`, `md` or `lg` as an option.
547
557
  */
548
558
  size: ListBoxPropTypes.ListBoxSize,
559
+ /**
560
+ * Provide a `Slug` component to be rendered inside the `FilterableMultiSelect` component
561
+ */
562
+ slug: PropTypes__default["default"].node,
549
563
  ...MultiSelectPropTypes.sortingPropTypes,
550
564
  /**
551
565
  * Callback function for translating ListBoxMenuIcon SVG title
@@ -5,6 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import { UseSelectProps } from 'downshift';
8
+ import { ReactNodeLike } from 'prop-types';
8
9
  import React from 'react';
9
10
  import { ListBoxSize, ListBoxType } from '../ListBox';
10
11
  import { ListBoxProps } from '../ListBox/ListBox';
@@ -162,6 +163,10 @@ export interface MultiSelectProps<ItemType> extends MultiSelectSortingProps<Item
162
163
  * Specify the size of the ListBox. Currently supports either `sm`, `md` or `lg` as an option.
163
164
  */
164
165
  size?: ListBoxSize;
166
+ /**
167
+ * Provide a `Slug` component to be rendered inside the `MultiSelect` component
168
+ */
169
+ slug?: ReactNodeLike;
165
170
  /**
166
171
  * Provide text to be used in a `<label>` element that is tied to the
167
172
  * multiselect via ARIA attributes.
@@ -98,7 +98,8 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
98
98
  direction = 'bottom',
99
99
  selectedItems: selected,
100
100
  readOnly,
101
- locale = 'en'
101
+ locale = 'en',
102
+ slug
102
103
  } = _ref;
103
104
  const prefix = usePrefix.usePrefix();
104
105
  const {
@@ -192,7 +193,8 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
192
193
  [`${prefix}--multi-select__wrapper--inline--invalid`]: inline && invalid,
193
194
  [`${prefix}--list-box__wrapper--inline--invalid`]: inline && invalid,
194
195
  [`${prefix}--list-box__wrapper--fluid--invalid`]: isFluid && invalid,
195
- [`${prefix}--list-box__wrapper--fluid--focus`]: !isOpen && isFluid && isFocused
196
+ [`${prefix}--list-box__wrapper--fluid--focus`]: !isOpen && isFluid && isFocused,
197
+ [`${prefix}--list-box__wrapper--slug`]: slug
196
198
  });
197
199
  const titleClasses = cx__default["default"](`${prefix}--label`, {
198
200
  [`${prefix}--label--disabled`]: disabled,
@@ -304,6 +306,14 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
304
306
  }
305
307
  }
306
308
  } : {};
309
+
310
+ // Slug is always size `mini`
311
+ let normalizedSlug;
312
+ if (slug) {
313
+ normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
314
+ size: 'mini'
315
+ });
316
+ }
307
317
  return /*#__PURE__*/React__default["default"].createElement("div", {
308
318
  className: wrapperClasses
309
319
  }, /*#__PURE__*/React__default["default"].createElement("label", _rollupPluginBabelHelpers["extends"]({
@@ -352,7 +362,7 @@ const MultiSelect = /*#__PURE__*/React__default["default"].forwardRef((_ref, ref
352
362
  }, label), /*#__PURE__*/React__default["default"].createElement(index["default"].MenuIcon, {
353
363
  isOpen: isOpen,
354
364
  translateWithId: translateWithId
355
- }))), /*#__PURE__*/React__default["default"].createElement(index["default"].Menu, getMenuProps(), isOpen &&
365
+ })), normalizedSlug), /*#__PURE__*/React__default["default"].createElement(index["default"].Menu, getMenuProps(), isOpen &&
356
366
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
357
367
  sortItems(items, sortOptions).map((item, index$1) => {
358
368
  const isChecked = selectedItems.filter(selected => isEqual__default["default"](selected, item)).length > 0;
@@ -507,6 +517,10 @@ MultiSelect.propTypes = {
507
517
  * Specify the size of the ListBox. Currently supports either `sm`, `md` or `lg` as an option.
508
518
  */
509
519
  size: ListBoxPropTypes.ListBoxSize,
520
+ /**
521
+ * Provide a `Slug` component to be rendered inside the `MultiSelect` component
522
+ */
523
+ slug: PropTypes__default["default"].node,
510
524
  /**
511
525
  * Provide a method that sorts all options in the control. Overriding this
512
526
  * prop means that you also have to handle the sort logic for selected versus