@carbon/react 1.44.0 → 1.45.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 (134) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +820 -902
  2. package/es/components/Checkbox/Checkbox.d.ts +1 -1
  3. package/es/components/Checkbox/Checkbox.js +1 -1
  4. package/es/components/CheckboxGroup/CheckboxGroup.js +2 -2
  5. package/es/components/ComboBox/ComboBox.d.ts +1 -1
  6. package/es/components/ComboBox/ComboBox.js +2 -2
  7. package/es/components/ComboButton/index.js +1 -1
  8. package/es/components/ComposedModal/ModalFooter.d.ts +2 -1
  9. package/es/components/ContentSwitcher/ContentSwitcher.js +1 -1
  10. package/es/components/DataTable/DataTable.d.ts +2 -0
  11. package/es/components/DataTable/DataTable.js +3 -0
  12. package/es/components/DataTable/TableExpandRow.js +20 -3
  13. package/es/components/DataTable/TableHeader.d.ts +5 -0
  14. package/es/components/DataTable/TableHeader.js +30 -6
  15. package/es/components/DataTable/TableSlugRow.d.ts +31 -0
  16. package/es/components/DataTable/TableSlugRow.js +49 -0
  17. package/es/components/DataTable/index.d.ts +2 -1
  18. package/es/components/DataTable/index.js +3 -0
  19. package/es/components/DatePickerInput/DatePickerInput.d.ts +1 -1
  20. package/es/components/DatePickerInput/DatePickerInput.js +2 -2
  21. package/es/components/Dropdown/Dropdown.d.ts +1 -1
  22. package/es/components/Dropdown/Dropdown.js +2 -2
  23. package/es/components/InlineLoading/InlineLoading.d.ts +68 -0
  24. package/es/components/InlineLoading/InlineLoading.js +4 -4
  25. package/es/components/InlineLoading/index.d.ts +9 -0
  26. package/es/components/Layer/LayerContext.d.ts +8 -0
  27. package/es/components/Layer/LayerLevel.d.ts +5 -0
  28. package/es/components/Layer/LayerLevel.js +12 -0
  29. package/es/components/Layer/index.d.ts +38 -0
  30. package/es/components/Layer/index.js +9 -8
  31. package/es/components/Menu/MenuItem.js +2 -1
  32. package/es/components/MenuButton/index.js +1 -1
  33. package/es/components/Modal/Modal.d.ts +3 -2
  34. package/es/components/MultiSelect/FilterableMultiSelect.js +2 -2
  35. package/es/components/MultiSelect/MultiSelect.d.ts +1 -1
  36. package/es/components/MultiSelect/MultiSelect.js +5 -2
  37. package/es/components/Notification/Notification.js +1 -0
  38. package/es/components/NumberInput/NumberInput.d.ts +1 -1
  39. package/es/components/NumberInput/NumberInput.js +3 -3
  40. package/es/components/ProgressIndicator/ProgressIndicator.js +4 -0
  41. package/es/components/RadioButton/RadioButton.d.ts +1 -1
  42. package/es/components/RadioButton/RadioButton.js +1 -1
  43. package/es/components/RadioButtonGroup/RadioButtonGroup.d.ts +1 -1
  44. package/es/components/RadioButtonGroup/RadioButtonGroup.js +2 -2
  45. package/es/components/Select/Select.d.ts +1 -1
  46. package/es/components/Select/Select.js +2 -2
  47. package/es/components/Slider/Slider.Skeleton.js +17 -3
  48. package/es/components/Slider/Slider.js +132 -93
  49. package/es/components/Slider/SliderHandles.d.ts +4 -0
  50. package/es/components/Slider/SliderHandles.js +65 -0
  51. package/es/components/Slug/index.js +1 -0
  52. package/es/components/Tabs/Tabs.js +1 -1
  53. package/es/components/Tag/Tag.d.ts +18 -10
  54. package/es/components/Tag/Tag.js +23 -7
  55. package/es/components/TextArea/TextArea.d.ts +7 -3
  56. package/es/components/TextArea/TextArea.js +85 -18
  57. package/es/components/TextInput/TextInput.d.ts +1 -1
  58. package/es/components/TextInput/TextInput.js +2 -2
  59. package/es/components/Tile/Tile.d.ts +8 -8
  60. package/es/components/Tile/Tile.js +11 -7
  61. package/es/components/Tooltip/Tooltip.js +48 -2
  62. package/es/components/UIShell/HeaderPanel.d.ts +36 -0
  63. package/es/components/UIShell/HeaderPanel.js +6 -6
  64. package/es/components/UIShell/Switcher.js +1 -1
  65. package/es/index.js +2 -1
  66. package/es/internal/useAnnouncer.js +2 -1
  67. package/es/internal/useNoInteractiveChildren.js +2 -6
  68. package/lib/components/Checkbox/Checkbox.d.ts +1 -1
  69. package/lib/components/Checkbox/Checkbox.js +1 -1
  70. package/lib/components/CheckboxGroup/CheckboxGroup.js +2 -2
  71. package/lib/components/ComboBox/ComboBox.d.ts +1 -1
  72. package/lib/components/ComboBox/ComboBox.js +2 -2
  73. package/lib/components/ComboButton/index.js +1 -1
  74. package/lib/components/ComposedModal/ModalFooter.d.ts +2 -1
  75. package/lib/components/ContentSwitcher/ContentSwitcher.js +1 -1
  76. package/lib/components/DataTable/DataTable.d.ts +2 -0
  77. package/lib/components/DataTable/DataTable.js +3 -0
  78. package/lib/components/DataTable/TableExpandRow.js +20 -3
  79. package/lib/components/DataTable/TableHeader.d.ts +5 -0
  80. package/lib/components/DataTable/TableHeader.js +29 -5
  81. package/lib/components/DataTable/TableSlugRow.d.ts +31 -0
  82. package/lib/components/DataTable/TableSlugRow.js +59 -0
  83. package/lib/components/DataTable/index.d.ts +2 -1
  84. package/lib/components/DataTable/index.js +3 -0
  85. package/lib/components/DatePickerInput/DatePickerInput.d.ts +1 -1
  86. package/lib/components/DatePickerInput/DatePickerInput.js +2 -2
  87. package/lib/components/Dropdown/Dropdown.d.ts +1 -1
  88. package/lib/components/Dropdown/Dropdown.js +2 -2
  89. package/lib/components/InlineLoading/InlineLoading.d.ts +68 -0
  90. package/lib/components/InlineLoading/InlineLoading.js +4 -4
  91. package/lib/components/InlineLoading/index.d.ts +9 -0
  92. package/lib/components/Layer/LayerContext.d.ts +8 -0
  93. package/lib/components/Layer/LayerLevel.d.ts +5 -0
  94. package/lib/components/Layer/LayerLevel.js +18 -0
  95. package/lib/components/Layer/index.d.ts +38 -0
  96. package/lib/components/Layer/index.js +10 -9
  97. package/lib/components/Menu/MenuItem.js +2 -1
  98. package/lib/components/MenuButton/index.js +1 -1
  99. package/lib/components/Modal/Modal.d.ts +3 -2
  100. package/lib/components/MultiSelect/FilterableMultiSelect.js +2 -2
  101. package/lib/components/MultiSelect/MultiSelect.d.ts +1 -1
  102. package/lib/components/MultiSelect/MultiSelect.js +5 -2
  103. package/lib/components/Notification/Notification.js +1 -0
  104. package/lib/components/NumberInput/NumberInput.d.ts +1 -1
  105. package/lib/components/NumberInput/NumberInput.js +3 -3
  106. package/lib/components/ProgressIndicator/ProgressIndicator.js +4 -0
  107. package/lib/components/RadioButton/RadioButton.d.ts +1 -1
  108. package/lib/components/RadioButton/RadioButton.js +1 -1
  109. package/lib/components/RadioButtonGroup/RadioButtonGroup.d.ts +1 -1
  110. package/lib/components/RadioButtonGroup/RadioButtonGroup.js +2 -2
  111. package/lib/components/Select/Select.d.ts +1 -1
  112. package/lib/components/Select/Select.js +2 -2
  113. package/lib/components/Slider/Slider.Skeleton.js +17 -3
  114. package/lib/components/Slider/Slider.js +132 -93
  115. package/lib/components/Slider/SliderHandles.d.ts +4 -0
  116. package/lib/components/Slider/SliderHandles.js +76 -0
  117. package/lib/components/Slug/index.js +1 -0
  118. package/lib/components/Tabs/Tabs.js +1 -1
  119. package/lib/components/Tag/Tag.d.ts +18 -10
  120. package/lib/components/Tag/Tag.js +23 -7
  121. package/lib/components/TextArea/TextArea.d.ts +7 -3
  122. package/lib/components/TextArea/TextArea.js +84 -17
  123. package/lib/components/TextInput/TextInput.d.ts +1 -1
  124. package/lib/components/TextInput/TextInput.js +2 -2
  125. package/lib/components/Tile/Tile.d.ts +8 -8
  126. package/lib/components/Tile/Tile.js +11 -7
  127. package/lib/components/Tooltip/Tooltip.js +47 -1
  128. package/lib/components/UIShell/HeaderPanel.d.ts +36 -0
  129. package/lib/components/UIShell/HeaderPanel.js +7 -7
  130. package/lib/components/UIShell/Switcher.js +1 -1
  131. package/lib/index.js +4 -2
  132. package/lib/internal/useAnnouncer.js +2 -1
  133. package/lib/internal/useNoInteractiveChildren.js +2 -6
  134. package/package.json +4 -7
@@ -54,6 +54,7 @@ const Tag = _ref => {
54
54
  onClose,
55
55
  size,
56
56
  as: BaseComponent,
57
+ slug,
57
58
  ...other
58
59
  } = _ref;
59
60
  const prefix = usePrefix.usePrefix();
@@ -74,15 +75,26 @@ const Tag = _ref => {
74
75
  onClose(event);
75
76
  }
76
77
  };
78
+
79
+ // Slug is always size `md` and `inline`
80
+ let normalizedSlug;
81
+ if (slug && slug['type']?.displayName === 'Slug') {
82
+ normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
83
+ size: 'sm',
84
+ kind: 'inline'
85
+ });
86
+ }
77
87
  if (filter) {
78
88
  const ComponentTag = BaseComponent ?? 'div';
79
89
  return /*#__PURE__*/React__default["default"].createElement(ComponentTag, _rollupPluginBabelHelpers["extends"]({
80
90
  className: tagClasses,
81
91
  id: tagId
82
- }, other), /*#__PURE__*/React__default["default"].createElement(Text.Text, {
92
+ }, other), CustomIconElement ? /*#__PURE__*/React__default["default"].createElement("div", {
93
+ className: `${prefix}--tag__custom-icon`
94
+ }, /*#__PURE__*/React__default["default"].createElement(CustomIconElement, null)) : '', /*#__PURE__*/React__default["default"].createElement(Text.Text, {
83
95
  className: `${prefix}--tag__label`,
84
96
  title: typeof children === 'string' ? children : undefined
85
- }, children !== null && children !== undefined ? children : typeText), /*#__PURE__*/React__default["default"].createElement("button", {
97
+ }, children !== null && children !== undefined ? children : typeText), normalizedSlug, /*#__PURE__*/React__default["default"].createElement("button", {
86
98
  type: "button",
87
99
  className: `${prefix}--tag__close-icon`,
88
100
  onClick: handleClose,
@@ -100,7 +112,7 @@ const Tag = _ref => {
100
112
  className: `${prefix}--tag__custom-icon`
101
113
  }, /*#__PURE__*/React__default["default"].createElement(CustomIconElement, null)) : '', /*#__PURE__*/React__default["default"].createElement(Text.Text, {
102
114
  title: typeof children === 'string' ? children : undefined
103
- }, children !== null && children !== undefined ? children : typeText));
115
+ }, children !== null && children !== undefined ? children : typeText), normalizedSlug);
104
116
  };
105
117
  Tag.propTypes = {
106
118
  /**
@@ -109,7 +121,7 @@ Tag.propTypes = {
109
121
  */
110
122
  as: PropTypes__default["default"].elementType,
111
123
  /**
112
- * Provide content to be rendered inside of a <Tag>
124
+ * Provide content to be rendered inside of a `Tag`
113
125
  */
114
126
  children: PropTypes__default["default"].node,
115
127
  /**
@@ -117,11 +129,11 @@ Tag.propTypes = {
117
129
  */
118
130
  className: PropTypes__default["default"].string,
119
131
  /**
120
- * Specify if the <Tag> is disabled
132
+ * Specify if the `Tag` is disabled
121
133
  */
122
134
  disabled: PropTypes__default["default"].bool,
123
135
  /**
124
- * Determine if <Tag> is a filter/chip
136
+ * Determine if `Tag` is a filter/chip
125
137
  */
126
138
  filter: PropTypes__default["default"].bool,
127
139
  /**
@@ -142,12 +154,16 @@ Tag.propTypes = {
142
154
  * 'md' (default) sizes.
143
155
  */
144
156
  size: PropTypes__default["default"].oneOf(['sm', 'md']),
157
+ /**
158
+ * **Experimental:** Provide a `Slug` component to be rendered inside the `Tag` component
159
+ */
160
+ slug: PropTypes__default["default"].node,
145
161
  /**
146
162
  * Text to show on clear filters
147
163
  */
148
164
  title: PropTypes__default["default"].string,
149
165
  /**
150
- * Specify the type of the <Tag>
166
+ * Specify the type of the `Tag`
151
167
  */
152
168
  type: PropTypes__default["default"].oneOf(Object.keys(TYPES))
153
169
  };
@@ -25,7 +25,7 @@ export interface TextAreaProps extends React.InputHTMLAttributes<HTMLTextAreaEle
25
25
  */
26
26
  disabled?: boolean;
27
27
  /**
28
- * Specify whether to display the character counter
28
+ * Specify whether to display the counter
29
29
  */
30
30
  enableCounter?: boolean;
31
31
  /**
@@ -60,7 +60,7 @@ export interface TextAreaProps extends React.InputHTMLAttributes<HTMLTextAreaEle
60
60
  */
61
61
  light?: boolean;
62
62
  /**
63
- * Max character count allowed for the textarea. This is needed in order for enableCounter to display
63
+ * Max entity count allowed for the textarea. This is needed in order for enableCounter to display
64
64
  */
65
65
  maxCount?: number;
66
66
  /**
@@ -86,7 +86,7 @@ export interface TextAreaProps extends React.InputHTMLAttributes<HTMLTextAreaEle
86
86
  */
87
87
  rows?: number;
88
88
  /**
89
- * Provide a `Slug` component to be rendered inside the `TextArea` component
89
+ * **Experimental**: Provide a `Slug` component to be rendered inside the `TextArea` component
90
90
  */
91
91
  slug?: ReactNodeLike;
92
92
  /**
@@ -101,6 +101,10 @@ export interface TextAreaProps extends React.InputHTMLAttributes<HTMLTextAreaEle
101
101
  * Provide the text that is displayed when the control is in warning state
102
102
  */
103
103
  warnText?: ReactNodeLike;
104
+ /**
105
+ * Specify the method used for calculating the counter number
106
+ */
107
+ counterMode?: 'character' | 'word';
104
108
  }
105
109
  declare const TextArea: React.ForwardRefExoticComponent<TextAreaProps & React.RefAttributes<unknown>>;
106
110
  export default TextArea;
@@ -49,6 +49,7 @@ const TextArea = /*#__PURE__*/React__default["default"].forwardRef((props, forwa
49
49
  placeholder = '',
50
50
  enableCounter = false,
51
51
  maxCount = undefined,
52
+ counterMode = 'character',
52
53
  warn = false,
53
54
  warnText = '',
54
55
  rows = 4,
@@ -63,15 +64,25 @@ const TextArea = /*#__PURE__*/React__default["default"].forwardRef((props, forwa
63
64
  defaultValue,
64
65
  value
65
66
  } = other;
66
- const [textCount, setTextCount] = React.useState(defaultValue?.toString()?.length || value?.toString()?.length || 0);
67
67
  const {
68
68
  current: textAreaInstanceId
69
69
  } = React.useRef(getInstanceId());
70
70
  const textareaRef = React.useRef(null);
71
71
  const ref = useMergedRefs.useMergedRefs([forwardRef, textareaRef]);
72
+ function getInitialTextCount() {
73
+ const targetValue = defaultValue || value || textareaRef.current?.value || '';
74
+ const strValue = targetValue.toString();
75
+ if (counterMode === 'character') {
76
+ return strValue.length;
77
+ } else {
78
+ return strValue.match(/\w+/g)?.length || 0;
79
+ }
80
+ }
81
+ const [textCount, setTextCount] = React.useState(getInitialTextCount());
72
82
  React.useEffect(() => {
73
- setTextCount(defaultValue?.toString()?.length || value?.toString()?.length || 0);
74
- }, [value, defaultValue]);
83
+ setTextCount(getInitialTextCount());
84
+ // eslint-disable-next-line react-hooks/exhaustive-deps
85
+ }, [value, defaultValue, counterMode]);
75
86
  useIsomorphicEffect["default"](() => {
76
87
  if (other.cols && textareaRef.current) {
77
88
  textareaRef.current.style.width = '';
@@ -82,14 +93,63 @@ const TextArea = /*#__PURE__*/React__default["default"].forwardRef((props, forwa
82
93
  }, [other.cols]);
83
94
  const textareaProps = {
84
95
  id,
96
+ onKeyDown: evt => {
97
+ if (!disabled && enableCounter && counterMode === 'word') {
98
+ const key = evt.which;
99
+ if (maxCount && textCount >= maxCount && key === 32) {
100
+ evt.preventDefault();
101
+ }
102
+ }
103
+ },
104
+ onPaste: evt => {
105
+ if (!disabled) {
106
+ if (counterMode === 'word' && enableCounter && typeof maxCount !== 'undefined' && textareaRef.current !== null) {
107
+ const existingWords = textareaRef.current.value.match(/\w+/g) || [];
108
+ const pastedWords = evt.clipboardData.getData('Text').match(/\w+/g) || [];
109
+ const totalWords = existingWords.length + pastedWords.length;
110
+ if (totalWords > maxCount) {
111
+ evt.preventDefault();
112
+ const allowedWords = existingWords.concat(pastedWords).slice(0, maxCount);
113
+ setTimeout(() => {
114
+ setTextCount(maxCount);
115
+ }, 0);
116
+ textareaRef.current.value = allowedWords.join(' ');
117
+ }
118
+ }
119
+ }
120
+ },
85
121
  onChange: evt => {
86
- if (!disabled && onChange) {
87
- evt?.persist?.();
88
- // delay textCount assignation to give the textarea element value time to catch up if is a controlled input
89
- setTimeout(() => {
90
- setTextCount(evt.target?.value?.length);
91
- }, 0);
92
- onChange(evt);
122
+ if (!disabled) {
123
+ if (counterMode == 'character') {
124
+ evt?.persist?.();
125
+ // delay textCount assignation to give the textarea element value time to catch up if is a controlled input
126
+ setTimeout(() => {
127
+ setTextCount(evt.target?.value?.length);
128
+ }, 0);
129
+ } else if (counterMode == 'word') {
130
+ if (!evt.target.value) {
131
+ setTimeout(() => {
132
+ setTextCount(0);
133
+ }, 0);
134
+ return;
135
+ }
136
+ if (enableCounter && typeof maxCount !== 'undefined' && textareaRef.current !== null) {
137
+ const matchedWords = evt.target?.value?.match(/\w+/g);
138
+ if (matchedWords && matchedWords.length <= maxCount) {
139
+ textareaRef.current.removeAttribute('maxLength');
140
+ setTimeout(() => {
141
+ setTextCount(matchedWords.length);
142
+ }, 0);
143
+ } else if (matchedWords && matchedWords.length > maxCount) {
144
+ setTimeout(() => {
145
+ setTextCount(matchedWords.length);
146
+ }, 0);
147
+ }
148
+ }
149
+ }
150
+ if (onChange) {
151
+ onChange(evt);
152
+ }
93
153
  }
94
154
  },
95
155
  onClick: evt => {
@@ -124,7 +184,7 @@ const TextArea = /*#__PURE__*/React__default["default"].forwardRef((props, forwa
124
184
  htmlFor: id,
125
185
  className: labelClasses
126
186
  }, labelText) : null;
127
- const counter = enableCounter && maxCount ? /*#__PURE__*/React__default["default"].createElement(Text.Text, {
187
+ const counter = enableCounter && maxCount && (counterMode === 'character' || counterMode === 'word') ? /*#__PURE__*/React__default["default"].createElement(Text.Text, {
128
188
  as: "div",
129
189
  className: counterClasses
130
190
  }, `${textCount}/${maxCount}`) : null;
@@ -157,9 +217,12 @@ const TextArea = /*#__PURE__*/React__default["default"].forwardRef((props, forwa
157
217
  ariaDescribedBy = helperId;
158
218
  }
159
219
  if (enableCounter) {
160
- textareaProps.maxLength = maxCount;
220
+ // handle different counter mode
221
+ if (counterMode == 'character') {
222
+ textareaProps.maxLength = maxCount;
223
+ }
161
224
  }
162
- const ariaAnnouncement = useAnnouncer.useAnnouncer(textCount, maxCount);
225
+ const ariaAnnouncement = useAnnouncer.useAnnouncer(textCount, maxCount, counterMode === 'word' ? 'words' : undefined);
163
226
  const input = /*#__PURE__*/React__default["default"].createElement("textarea", _rollupPluginBabelHelpers["extends"]({}, other, textareaProps, {
164
227
  placeholder: placeholder,
165
228
  className: textareaClasses,
@@ -173,7 +236,7 @@ const TextArea = /*#__PURE__*/React__default["default"].forwardRef((props, forwa
173
236
 
174
237
  // Slug is always size `mini`
175
238
  let normalizedSlug;
176
- if (slug) {
239
+ if (slug && slug['type']?.displayName === 'Slug') {
177
240
  normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
178
241
  size: 'mini'
179
242
  });
@@ -207,6 +270,10 @@ TextArea.propTypes = {
207
270
  * Specify the `cols` attribute for the underlying `<textarea>` node
208
271
  */
209
272
  cols: PropTypes__default["default"].number,
273
+ /**
274
+ * Specify the method used for calculating the counter number
275
+ */
276
+ counterMode: PropTypes__default["default"].oneOf(['character', 'word']),
210
277
  /**
211
278
  * Optionally provide the default value of the `<textarea>`
212
279
  */
@@ -216,7 +283,7 @@ TextArea.propTypes = {
216
283
  */
217
284
  disabled: PropTypes__default["default"].bool,
218
285
  /**
219
- * Specify whether to display the character counter
286
+ * Specify whether to display the counter
220
287
  */
221
288
  enableCounter: PropTypes__default["default"].bool,
222
289
  /**
@@ -250,7 +317,7 @@ TextArea.propTypes = {
250
317
  */
251
318
  light: deprecate["default"](PropTypes__default["default"].bool, 'The `light` prop for `TextArea` has ' + 'been deprecated in favor of the new `Layer` component. It will be removed in the next major release.'),
252
319
  /**
253
- * Max character count allowed for the textarea. This is needed in order for enableCounter to display
320
+ * Max entity count allowed for the textarea. This is needed in order for enableCounter to display
254
321
  */
255
322
  maxCount: PropTypes__default["default"].number,
256
323
  /**
@@ -276,7 +343,7 @@ TextArea.propTypes = {
276
343
  */
277
344
  rows: PropTypes__default["default"].number,
278
345
  /**
279
- * Provide a `Slug` component to be rendered inside the `TextArea` component
346
+ * **Experimental**: Provide a `Slug` component to be rendered inside the `TextArea` component
280
347
  */
281
348
  slug: PropTypes__default["default"].node,
282
349
  /**
@@ -87,7 +87,7 @@ export interface TextInputProps extends Omit<React.InputHTMLAttributes<HTMLInput
87
87
  */
88
88
  size?: 'sm' | 'md' | 'lg' | 'xl';
89
89
  /**
90
- * Provide a `Slug` component to be rendered inside the `TextInput` component
90
+ * **Experimental**: Provide a `Slug` component to be rendered inside the `TextInput` component
91
91
  */
92
92
  slug?: ReactNodeLike;
93
93
  /**
@@ -167,7 +167,7 @@ const TextInput = /*#__PURE__*/React__default["default"].forwardRef(function Tex
167
167
 
168
168
  // Slug is always size `mini`
169
169
  let normalizedSlug;
170
- if (slug) {
170
+ if (slug && slug['type']?.displayName === 'Slug') {
171
171
  normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
172
172
  size: 'mini'
173
173
  });
@@ -271,7 +271,7 @@ TextInput.propTypes = {
271
271
  */
272
272
  size: PropTypes__default["default"].oneOf(['sm', 'md', 'lg']),
273
273
  /**
274
- * Provide a `Slug` component to be rendered inside the `TextInput` component
274
+ * **Experimental**: Provide a `Slug` component to be rendered inside the `TextInput` component
275
275
  */
276
276
  slug: PropTypes__default["default"].node,
277
277
  /**
@@ -6,12 +6,12 @@ export interface TileProps extends HTMLAttributes<HTMLDivElement> {
6
6
  /** @deprecated */
7
7
  light?: boolean;
8
8
  /**
9
- * Specify if the `Tile` component should be rendered with rounded corners. Only valid
9
+ * **Experimental**: Specify if the `Tile` component should be rendered with rounded corners. Only valid
10
10
  * when `slug` prop is present
11
11
  */
12
12
  hasRoundedCorners?: boolean;
13
13
  /**
14
- * Provide a `Slug` component to be rendered inside the `SelectableTile` component
14
+ * **Experimental**: Provide a `Slug` component to be rendered inside the `SelectableTile` component
15
15
  */
16
16
  slug?: ReactNodeLike;
17
17
  }
@@ -30,7 +30,7 @@ export interface ClickableTileProps extends HTMLAttributes<HTMLAnchorElement> {
30
30
  */
31
31
  disabled?: boolean;
32
32
  /**
33
- * Specify if the `ClickableTile` component should be rendered with rounded corners.
33
+ * **Experimental**: Specify if the `ClickableTile` component should be rendered with rounded corners.
34
34
  * Only valid when `slug` prop is present
35
35
  */
36
36
  hasRoundedCorners?: boolean;
@@ -57,7 +57,7 @@ export interface ClickableTileProps extends HTMLAttributes<HTMLAnchorElement> {
57
57
  */
58
58
  rel?: string;
59
59
  /**
60
- * Specify if a `Slug` icon should be rendered inside the `ClickableTile`
60
+ * **Experimental**: Specify if a `Slug` icon should be rendered inside the `ClickableTile`
61
61
  */
62
62
  slug?: boolean;
63
63
  }
@@ -72,7 +72,7 @@ export interface SelectableTileProps extends HTMLAttributes<HTMLDivElement> {
72
72
  */
73
73
  disabled?: boolean;
74
74
  /**
75
- * Specify if the `SelectableTile` component should be rendered with rounded corners.
75
+ * **Experimental**: Specify if the `SelectableTile` component should be rendered with rounded corners.
76
76
  * Only valid when `slug` prop is present
77
77
  */
78
78
  hasRoundedCorners?: boolean;
@@ -102,7 +102,7 @@ export interface SelectableTileProps extends HTMLAttributes<HTMLDivElement> {
102
102
  */
103
103
  selected?: boolean;
104
104
  /**
105
- * Provide a `Slug` component to be rendered inside the `SelectableTile` component
105
+ * **Experimental**: Provide a `Slug` component to be rendered inside the `SelectableTile` component
106
106
  */
107
107
  slug?: ReactNodeLike;
108
108
  /**
@@ -130,7 +130,7 @@ export interface ExpandableTileProps extends HTMLAttributes<HTMLDivElement> {
130
130
  */
131
131
  expanded?: boolean;
132
132
  /**
133
- * Specify if the `ExpandableTile` component should be rendered with rounded corners.
133
+ * **Experimental**: Specify if the `ExpandableTile` component should be rendered with rounded corners.
134
134
  * Only valid when `slug` prop is present
135
135
  */
136
136
  hasRoundedCorners?: boolean;
@@ -147,7 +147,7 @@ export interface ExpandableTileProps extends HTMLAttributes<HTMLDivElement> {
147
147
  */
148
148
  onKeyUp?(event: KeyboardEvent): void;
149
149
  /**
150
- * Provide a `Slug` component to be rendered inside the `ExpandableTile` component
150
+ * **Experimental**: Provide a `Slug` component to be rendered inside the `ExpandableTile` component
151
151
  */
152
152
  slug?: ReactNodeLike;
153
153
  /**
@@ -66,7 +66,7 @@ Tile.propTypes = {
66
66
  */
67
67
  className: PropTypes__default["default"].string,
68
68
  /**
69
- * Specify if the `Tile` component should be rendered with rounded corners. Only valid
69
+ * **Experimental**: Specify if the `Tile` component should be rendered with rounded corners. Only valid
70
70
  * when `slug` prop is present
71
71
  */
72
72
  hasRoundedCorners: PropTypes__default["default"].bool,
@@ -78,7 +78,7 @@ Tile.propTypes = {
78
78
  */
79
79
  light: deprecate["default"](PropTypes__default["default"].bool, 'The `light` prop for `Tile` is no longer needed and has been deprecated. It will be removed in the next major release. Use the Layer component instead.'),
80
80
  /**
81
- * Provide a `Slug` component to be rendered inside the `Tile` component
81
+ * **Experimental**: Provide a `Slug` component to be rendered inside the `Tile` component
82
82
  */
83
83
  slug: PropTypes__default["default"].node
84
84
  };
@@ -183,7 +183,7 @@ ClickableTile.propTypes = {
183
183
  */
184
184
  disabled: PropTypes__default["default"].bool,
185
185
  /**
186
- * Specify if the `ClickableTile` component should be rendered with rounded corners.
186
+ * **Experimental**: Specify if the `ClickableTile` component should be rendered with rounded corners.
187
187
  * Only valid when `slug` prop is present
188
188
  */
189
189
  hasRoundedCorners: PropTypes__default["default"].bool,
@@ -279,7 +279,7 @@ const SelectableTile = /*#__PURE__*/React__default["default"].forwardRef(functio
279
279
  // Slug is always size `xs`
280
280
  const slugRef = React.useRef(null);
281
281
  let normalizedSlug;
282
- if (slug) {
282
+ if (slug && slug['type']?.displayName === 'Slug') {
283
283
  normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
284
284
  size: 'xs',
285
285
  ref: slugRef
@@ -318,7 +318,7 @@ SelectableTile.propTypes = {
318
318
  */
319
319
  disabled: PropTypes__default["default"].bool,
320
320
  /**
321
- * Specify if the `SelectableTile` component should be rendered with rounded corners.
321
+ * **Experimental**: Specify if the `SelectableTile` component should be rendered with rounded corners.
322
322
  * Only valid when `slug` prop is present
323
323
  */
324
324
  hasRoundedCorners: PropTypes__default["default"].bool,
@@ -353,7 +353,7 @@ SelectableTile.propTypes = {
353
353
  */
354
354
  selected: PropTypes__default["default"].bool,
355
355
  /**
356
- * Provide a `Slug` component to be rendered inside the `SelectableTile` component
356
+ * **Experimental**: Provide a `Slug` component to be rendered inside the `SelectableTile` component
357
357
  */
358
358
  slug: PropTypes__default["default"].node,
359
359
  /**
@@ -504,7 +504,7 @@ const ExpandableTile = /*#__PURE__*/React__default["default"].forwardRef(functio
504
504
 
505
505
  // Slug is always size `xs`
506
506
  let normalizedSlug;
507
- if (slug) {
507
+ if (slug && slug['type']?.displayName === 'Slug') {
508
508
  normalizedSlug = /*#__PURE__*/React__default["default"].cloneElement(slug, {
509
509
  size: 'xs'
510
510
  });
@@ -583,6 +583,10 @@ ExpandableTile.propTypes = {
583
583
  * optional handler to trigger a function when a key is pressed
584
584
  */
585
585
  onKeyUp: PropTypes__default["default"].func,
586
+ /**
587
+ * **Experimental**: Provide a `Slug` component to be rendered inside the `ExpandableTile` component
588
+ */
589
+ slug: PropTypes__default["default"].node,
586
590
  /**
587
591
  * The `tabindex` attribute.
588
592
  */
@@ -27,6 +27,10 @@ var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
27
27
  var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
28
28
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
29
29
 
30
+ /**
31
+ * Event types that trigger a "drag" to stop.
32
+ */
33
+ const DRAG_STOP_EVENT_TYPES = new Set(['mouseup', 'touchend', 'touchcancel']);
30
34
  function Tooltip(_ref) {
31
35
  let {
32
36
  align = 'top',
@@ -43,6 +47,8 @@ function Tooltip(_ref) {
43
47
  const containerRef = React.useRef(null);
44
48
  const tooltipRef = React.useRef(null);
45
49
  const [open, setOpen] = useDelayedState.useDelayedState(defaultOpen);
50
+ const [isDragging, setIsDragging] = React.useState(false);
51
+ const [isPointerIntersecting, setIsPointerIntersecting] = React.useState(false);
46
52
  const id = useId.useId('tooltip');
47
53
  const prefix = usePrefix.usePrefix();
48
54
  const child = React__default["default"].Children.only(children);
@@ -51,7 +57,11 @@ function Tooltip(_ref) {
51
57
  onBlur: () => setOpen(false),
52
58
  onClick: () => closeOnActivation && setOpen(false),
53
59
  // This should be placed on the trigger in case the element is disabled
54
- onMouseEnter
60
+ onMouseEnter,
61
+ onMouseLeave,
62
+ onMouseDown: onDragStart,
63
+ onMouseMove: onMouseMove,
64
+ onTouchStart: onDragStart
55
65
  };
56
66
  function getChildEventHandlers(childProps) {
57
67
  const eventHandlerFunctions = ['onFocus', 'onBlur', 'onClick', 'onMouseEnter'];
@@ -81,11 +91,34 @@ function Tooltip(_ref) {
81
91
  }
82
92
  }
83
93
  function onMouseEnter() {
94
+ setIsPointerIntersecting(true);
84
95
  setOpen(true, enterDelayMs);
85
96
  }
86
97
  function onMouseLeave() {
98
+ setIsPointerIntersecting(false);
99
+ if (isDragging) {
100
+ return;
101
+ }
87
102
  setOpen(false, leaveDelayMs);
88
103
  }
104
+ function onMouseMove(evt) {
105
+ if (evt.buttons === 1) {
106
+ setIsDragging(true);
107
+ } else {
108
+ setIsDragging(false);
109
+ }
110
+ }
111
+ function onDragStart() {
112
+ setIsDragging(true);
113
+ }
114
+ const onDragStop = React.useCallback(() => {
115
+ setIsDragging(false);
116
+ // Close the tooltip, unless the mouse pointer is within the bounds of the
117
+ // trigger.
118
+ if (!isPointerIntersecting) {
119
+ setOpen(false, leaveDelayMs);
120
+ }
121
+ }, [isPointerIntersecting, leaveDelayMs, setOpen]);
89
122
  useNoInteractiveChildren.useNoInteractiveChildren(tooltipRef, 'The Tooltip component must have no interactive content rendered by the' + '`label` or `description` prop');
90
123
  React.useEffect(() => {
91
124
  if (containerRef !== null && containerRef.current) {
@@ -95,6 +128,19 @@ function Tooltip(_ref) {
95
128
  }
96
129
  }
97
130
  });
131
+ React.useEffect(() => {
132
+ if (isDragging) {
133
+ // Register drag stop handlers.
134
+ DRAG_STOP_EVENT_TYPES.forEach(eventType => {
135
+ document.addEventListener(eventType, onDragStop);
136
+ });
137
+ }
138
+ return () => {
139
+ DRAG_STOP_EVENT_TYPES.forEach(eventType => {
140
+ document.removeEventListener(eventType, onDragStop);
141
+ });
142
+ };
143
+ }, [isDragging, onDragStop]);
98
144
  return /*#__PURE__*/React__default["default"].createElement(index.Popover, _rollupPluginBabelHelpers["extends"]({}, rest, {
99
145
  align: align,
100
146
  className: cx__default["default"](`${prefix}--tooltip`, customClassName),
@@ -0,0 +1,36 @@
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
+ import React, { ReactNode } from 'react';
8
+ interface HeaderPanelProps {
9
+ /**
10
+ * Specify whether focus and blur listeners are added. They are by default.
11
+ */
12
+ addFocusListeners?: boolean;
13
+ /**
14
+ * The content that will render inside of the `HeaderPanel`
15
+ */
16
+ children?: ReactNode;
17
+ /**
18
+ * Optionally provide a custom class to apply to the underlying `<li>` node
19
+ */
20
+ className?: string;
21
+ /**
22
+ * Specify whether the panel is expanded
23
+ */
24
+ expanded?: boolean;
25
+ /**
26
+ * Provide the `href` to the id of the element on your package that could
27
+ * be target.
28
+ */
29
+ href?: string;
30
+ /**
31
+ * An optional listener that is called a callback to collapse the HeaderPanel
32
+ */
33
+ onHeaderPanelFocus?: () => void;
34
+ }
35
+ declare const HeaderPanel: React.FC<HeaderPanelProps>;
36
+ export default HeaderPanel;
@@ -10,9 +10,9 @@
10
10
  Object.defineProperty(exports, '__esModule', { value: true });
11
11
 
12
12
  var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
13
- var React = require('react');
14
13
  var cx = require('classnames');
15
14
  var PropTypes = require('prop-types');
15
+ var React = require('react');
16
16
  var usePrefix = require('../../internal/usePrefix.js');
17
17
  var useEvent = require('../../internal/useEvent.js');
18
18
  var useMergedRefs = require('../../internal/useMergedRefs.js');
@@ -21,9 +21,9 @@ var keys = require('../../internal/keyboard/keys.js');
21
21
 
22
22
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
23
23
 
24
- var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
25
24
  var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
26
25
  var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
26
+ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
27
27
 
28
28
  const noopFn = () => {};
29
29
  const HeaderPanel = /*#__PURE__*/React__default["default"].forwardRef(function HeaderPanel(_ref, ref) {
@@ -34,7 +34,7 @@ const HeaderPanel = /*#__PURE__*/React__default["default"].forwardRef(function H
34
34
  addFocusListeners = true,
35
35
  onHeaderPanelFocus = noopFn,
36
36
  href,
37
- ...other
37
+ ...rest
38
38
  } = _ref;
39
39
  const prefix = usePrefix.usePrefix();
40
40
  const headerPanelReference = React.useRef(null);
@@ -71,12 +71,13 @@ const HeaderPanel = /*#__PURE__*/React__default["default"].forwardRef(function H
71
71
  useEvent.useWindowEvent('click', () => {
72
72
  const focusedElement = document.activeElement;
73
73
  setLastClickedElement(focusedElement);
74
- if (children.type?.displayName === 'Switcher' && !focusedElement?.closest(`.${prefix}--header-panel--expanded`) && !focusedElement?.closest(`.${prefix}--header__action`) && !headerPanelRef?.current?.classList.contains(`${prefix}--switcher`) && expanded) {
74
+ const childJsxElement = children;
75
+ if (childJsxElement.type?.displayName === 'Switcher' && !focusedElement?.closest(`.${prefix}--header-panel--expanded`) && !focusedElement?.closest(`.${prefix}--header__action`) && !headerPanelReference?.current?.classList.contains(`${prefix}--switcher`) && expanded) {
75
76
  setExpandedState(false);
76
77
  onHeaderPanelFocus();
77
78
  }
78
79
  });
79
- return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({}, other, {
80
+ return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({}, rest, {
80
81
  className: className,
81
82
  ref: headerPanelRef
82
83
  }, eventHandlers), children);
@@ -109,6 +110,5 @@ HeaderPanel.propTypes = {
109
110
  onHeaderPanelFocus: PropTypes__default["default"].func
110
111
  };
111
112
  HeaderPanel.displayName = 'HeaderPanel';
112
- var HeaderPanel$1 = HeaderPanel;
113
113
 
114
- exports["default"] = HeaderPanel$1;
114
+ exports["default"] = HeaderPanel;
@@ -70,7 +70,7 @@ const Switcher = /*#__PURE__*/React.forwardRef(function Switcher(props, forwardR
70
70
  switcherItem.focus();
71
71
  }
72
72
  };
73
- const childrenWithProps = React__default["default"].Children.map(children, (child, index) => {
73
+ const childrenWithProps = React__default["default"].Children.toArray(children).map((child, index) => {
74
74
  // only setup click handlers if onChange event is passed
75
75
  if ( /*#__PURE__*/React__default["default"].isValidElement(child) && child.type && getDisplayName["default"](child.type) === 'Switcher') {
76
76
  return /*#__PURE__*/React__default["default"].cloneElement(child, {