@carbon/react 1.87.1 → 1.89.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 +804 -804
  2. package/es/components/AILabel/index.d.ts +4 -3
  3. package/es/components/AILabel/index.js +3 -1
  4. package/es/components/Button/Button.js +3 -1
  5. package/es/components/CodeSnippet/CodeSnippet.d.ts +9 -5
  6. package/es/components/CodeSnippet/CodeSnippet.js +3 -1
  7. package/es/components/ComboBox/ComboBox.d.ts +2 -1
  8. package/es/components/ComboBox/ComboBox.js +2 -1
  9. package/es/components/ContainedList/ContainedList.d.ts +2 -2
  10. package/es/components/ContentSwitcher/ContentSwitcher.d.ts +1 -6
  11. package/es/components/Copy/Copy.d.ts +9 -5
  12. package/es/components/Copy/Copy.js +3 -1
  13. package/es/components/CopyButton/CopyButton.d.ts +9 -5
  14. package/es/components/CopyButton/CopyButton.js +3 -1
  15. package/es/components/Dropdown/Dropdown.d.ts +4 -1
  16. package/es/components/Dropdown/Dropdown.js +4 -1
  17. package/es/components/FileUploader/FileUploaderButton.js +6 -3
  18. package/es/components/IconButton/index.d.ts +6 -4
  19. package/es/components/IconButton/index.js +3 -4
  20. package/es/components/MultiSelect/FilterableMultiSelect.d.ts +5 -2
  21. package/es/components/MultiSelect/FilterableMultiSelect.js +101 -22
  22. package/es/components/MultiSelect/MultiSelect.d.ts +2 -1
  23. package/es/components/MultiSelect/MultiSelect.js +2 -1
  24. package/es/components/Notification/Notification.d.ts +9 -1
  25. package/es/components/Notification/Notification.js +9 -1
  26. package/es/components/NumberInput/NumberInput.d.ts +4 -0
  27. package/es/components/NumberInput/NumberInput.js +12 -7
  28. package/es/components/OverflowMenu/next/index.d.ts +6 -2
  29. package/es/components/OverflowMenu/next/index.js +4 -1
  30. package/es/components/Popover/index.d.ts +4 -1
  31. package/es/components/Popover/index.js +15 -22
  32. package/es/components/Switch/IconSwitch.d.ts +44 -2
  33. package/es/components/Switch/IconSwitch.js +34 -27
  34. package/es/components/Switch/Switch.js +1 -0
  35. package/es/components/TextArea/TextArea.js +21 -4
  36. package/es/components/Toggletip/index.d.ts +4 -1
  37. package/es/components/Toggletip/index.js +4 -1
  38. package/es/components/Tooltip/DefinitionTooltip.d.ts +4 -2
  39. package/es/components/Tooltip/DefinitionTooltip.js +3 -1
  40. package/es/components/Tooltip/Tooltip.d.ts +0 -3
  41. package/es/components/Tooltip/Tooltip.js +2 -10
  42. package/es/components/TreeView/TreeNode.d.ts +4 -2
  43. package/es/components/TreeView/TreeNode.js +2 -1
  44. package/es/components/UIShell/Header.d.ts +3 -3
  45. package/es/components/UIShell/Header.js +7 -4
  46. package/es/components/UIShell/HeaderPanel.js +1 -1
  47. package/es/internal/Selection.d.ts +1 -0
  48. package/es/internal/Selection.js +10 -0
  49. package/lib/components/AILabel/index.d.ts +4 -3
  50. package/lib/components/AILabel/index.js +3 -1
  51. package/lib/components/Button/Button.js +3 -1
  52. package/lib/components/CodeSnippet/CodeSnippet.d.ts +9 -5
  53. package/lib/components/CodeSnippet/CodeSnippet.js +3 -1
  54. package/lib/components/ComboBox/ComboBox.d.ts +2 -1
  55. package/lib/components/ComboBox/ComboBox.js +2 -1
  56. package/lib/components/ContainedList/ContainedList.d.ts +2 -2
  57. package/lib/components/ContentSwitcher/ContentSwitcher.d.ts +1 -6
  58. package/lib/components/Copy/Copy.d.ts +9 -5
  59. package/lib/components/Copy/Copy.js +3 -1
  60. package/lib/components/CopyButton/CopyButton.d.ts +9 -5
  61. package/lib/components/CopyButton/CopyButton.js +3 -1
  62. package/lib/components/Dropdown/Dropdown.d.ts +4 -1
  63. package/lib/components/Dropdown/Dropdown.js +4 -1
  64. package/lib/components/FileUploader/FileUploaderButton.js +6 -3
  65. package/lib/components/IconButton/index.d.ts +6 -4
  66. package/lib/components/IconButton/index.js +3 -4
  67. package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +5 -2
  68. package/lib/components/MultiSelect/FilterableMultiSelect.js +100 -21
  69. package/lib/components/MultiSelect/MultiSelect.d.ts +2 -1
  70. package/lib/components/MultiSelect/MultiSelect.js +2 -1
  71. package/lib/components/Notification/Notification.d.ts +9 -1
  72. package/lib/components/Notification/Notification.js +9 -1
  73. package/lib/components/NumberInput/NumberInput.d.ts +4 -0
  74. package/lib/components/NumberInput/NumberInput.js +12 -7
  75. package/lib/components/OverflowMenu/next/index.d.ts +6 -2
  76. package/lib/components/OverflowMenu/next/index.js +4 -1
  77. package/lib/components/Popover/index.d.ts +4 -1
  78. package/lib/components/Popover/index.js +14 -21
  79. package/lib/components/Switch/IconSwitch.d.ts +44 -2
  80. package/lib/components/Switch/IconSwitch.js +35 -28
  81. package/lib/components/Switch/Switch.js +1 -0
  82. package/lib/components/TextArea/TextArea.js +21 -4
  83. package/lib/components/Toggletip/index.d.ts +4 -1
  84. package/lib/components/Toggletip/index.js +4 -1
  85. package/lib/components/Tooltip/DefinitionTooltip.d.ts +4 -2
  86. package/lib/components/Tooltip/DefinitionTooltip.js +3 -1
  87. package/lib/components/Tooltip/Tooltip.d.ts +0 -3
  88. package/lib/components/Tooltip/Tooltip.js +2 -10
  89. package/lib/components/TreeView/TreeNode.d.ts +4 -2
  90. package/lib/components/TreeView/TreeNode.js +2 -1
  91. package/lib/components/UIShell/Header.d.ts +3 -3
  92. package/lib/components/UIShell/Header.js +7 -4
  93. package/lib/components/UIShell/HeaderPanel.js +2 -2
  94. package/lib/internal/Selection.d.ts +1 -0
  95. package/lib/internal/Selection.js +10 -0
  96. package/package.json +8 -8
  97. package/telemetry.yml +2 -9
@@ -367,6 +367,10 @@ export interface ActionableNotificationProps extends HTMLAttributes<HTMLDivEleme
367
367
  * Provide a description for "close" icon button that can be read by screen readers
368
368
  */
369
369
  'aria-label'?: string;
370
+ /**
371
+ * Specify the caption
372
+ */
373
+ caption?: string;
370
374
  /**
371
375
  * Specify the content
372
376
  */
@@ -430,7 +434,7 @@ export interface ActionableNotificationProps extends HTMLAttributes<HTMLDivEleme
430
434
  */
431
435
  title?: string;
432
436
  }
433
- export declare function ActionableNotification({ actionButtonLabel, ['aria-label']: ariaLabel, ariaLabel: deprecatedAriaLabel, children, role, onActionButtonClick, onClose, onCloseButtonClick, statusIconDescription, className, inline, kind, lowContrast, hideCloseButton, hasFocus, closeOnEscape, title, subtitle, ...rest }: ActionableNotificationProps): import("react/jsx-runtime").JSX.Element | null;
437
+ export declare function ActionableNotification({ actionButtonLabel, ['aria-label']: ariaLabel, ariaLabel: deprecatedAriaLabel, caption, children, role, onActionButtonClick, onClose, onCloseButtonClick, statusIconDescription, className, inline, kind, lowContrast, hideCloseButton, hasFocus, closeOnEscape, title, subtitle, ...rest }: ActionableNotificationProps): import("react/jsx-runtime").JSX.Element | null;
434
438
  export declare namespace ActionableNotification {
435
439
  var propTypes: {
436
440
  /**
@@ -446,6 +450,10 @@ export declare namespace ActionableNotification {
446
450
  * Provide a description for "close" icon button that can be read by screen readers
447
451
  */
448
452
  ariaLabel: (props: Record<string, any>, propName: string, componentName: string, ...rest: any[]) => any;
453
+ /**
454
+ * Specify the caption
455
+ */
456
+ caption: PropTypes.Requireable<string>;
449
457
  /**
450
458
  * Specify the content
451
459
  */
@@ -474,6 +474,7 @@ function ActionableNotification({
474
474
  ['aria-label']: ariaLabel,
475
475
  // @ts-expect-error: deprecated prop
476
476
  ariaLabel: deprecatedAriaLabel,
477
+ caption,
477
478
  children,
478
479
  role = 'alertdialog',
479
480
  onActionButtonClick,
@@ -588,7 +589,10 @@ function ActionableNotification({
588
589
  as: "div",
589
590
  className: `${prefix}--actionable-notification__subtitle`,
590
591
  id: subtitleId
591
- }, subtitle), children))), /*#__PURE__*/React.createElement("div", {
592
+ }, subtitle), caption && /*#__PURE__*/React.createElement(Text.Text, {
593
+ as: "div",
594
+ className: `${prefix}--actionable-notification__caption`
595
+ }, caption), children))), /*#__PURE__*/React.createElement("div", {
592
596
  className: `${prefix}--actionable-notification__button-wrapper`,
593
597
  ref: innerModal
594
598
  }, actionButtonLabel && /*#__PURE__*/React.createElement(NotificationActionButton, {
@@ -619,6 +623,10 @@ ActionableNotification.propTypes = {
619
623
  * Provide a description for "close" icon button that can be read by screen readers
620
624
  */
621
625
  ariaLabel: deprecate.deprecate(PropTypes.string, 'This prop syntax has been deprecated. Please use the new `aria-label`.'),
626
+ /**
627
+ * Specify the caption
628
+ */
629
+ caption: PropTypes.string,
622
630
  /**
623
631
  * Specify the content
624
632
  */
@@ -51,6 +51,10 @@ export interface NumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInp
51
51
  * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#options
52
52
  */
53
53
  formatOptions?: NumberFormatOptions;
54
+ /**
55
+ * Provide the value stepping should begin at when the input is empty
56
+ */
57
+ stepStartValue?: number;
54
58
  /**
55
59
  * Provide text that is used alongside the control label for additional help
56
60
  */
@@ -78,6 +78,7 @@ const NumberInput = /*#__PURE__*/React.forwardRef(function NumberInput(props, fo
78
78
  defaultValue = type === 'number' ? 0 : NaN,
79
79
  warn = false,
80
80
  warnText = '',
81
+ stepStartValue = 0,
81
82
  value: controlledValue,
82
83
  ...rest
83
84
  } = props;
@@ -238,14 +239,14 @@ const NumberInput = /*#__PURE__*/React.forwardRef(function NumberInput(props, fo
238
239
  if (inputRef.current) {
239
240
  const currentValue = type === 'number' ? Number(inputRef.current.value) : numberValue;
240
241
  let rawValue;
241
- if (Number.isNaN(currentValue)) {
242
- // When the field is empty (NaN), incrementing begins at min,
243
- // decrementing begins at max.
244
- // When there's no min or max to use, it begins at 0.
245
- if (direction === `up` && min) {
242
+ if (Number.isNaN(currentValue) || !currentValue) {
243
+ if (typeof stepStartValue === 'number' && stepStartValue) {
244
+ rawValue = stepStartValue;
245
+ } else if (min && min < 0 && max && max > 0 || !max && !min || max) {
246
+ if (direction === `up`) rawValue = 1;
247
+ if (direction === `down`) rawValue = -1;
248
+ } else if (min && min > 0 && max && max > 0 || min) {
246
249
  rawValue = min;
247
- } else if (direction === `down` && max) {
248
- rawValue = max;
249
250
  } else {
250
251
  rawValue = 0;
251
252
  }
@@ -534,6 +535,10 @@ NumberInput.propTypes = {
534
535
  * The minimum value.
535
536
  */
536
537
  min: PropTypes.number,
538
+ /**
539
+ * Provide the value stepping should begin at when the input is empty
540
+ */
541
+ stepStartValue: PropTypes.number,
537
542
  /**
538
543
  * Provide an optional handler that is called when the input or stepper
539
544
  * buttons are blurred.
@@ -5,9 +5,13 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import React, { type ElementType } from 'react';
8
+ import type { PopoverAlignment } from '../../Popover';
8
9
  interface OverflowMenuProps {
9
10
  /**
10
- * **Experimental**: Will attempt to automatically align the floating element to avoid collisions with the viewport and being clipped by ancestor elements.
11
+ * **Experimental**: Will attempt to automatically align the floating element
12
+ * to avoid collisions with the viewport and being clipped by ancestor
13
+ * elements. Requires React v17+
14
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
11
15
  */
12
16
  autoAlign?: boolean;
13
17
  /**
@@ -37,7 +41,7 @@ interface OverflowMenuProps {
37
41
  /**
38
42
  * Specify how the trigger tooltip should be aligned.
39
43
  */
40
- tooltipAlignment?: 'top' | 'top-left' | 'top-right' | 'bottom' | 'bottom-left' | 'bottom-right' | 'left' | 'right';
44
+ tooltipAlignment?: PopoverAlignment;
41
45
  /**
42
46
  * Specify a DOM node where the Menu should be rendered in. Defaults to document.body.
43
47
  */
@@ -134,7 +134,10 @@ const OverflowMenu = /*#__PURE__*/React.forwardRef(function OverflowMenu({
134
134
  });
135
135
  OverflowMenu.propTypes = {
136
136
  /**
137
- * **Experimental**: Will attempt to automatically align the floating element to avoid collisions with the viewport and being clipped by ancestor elements.
137
+ * **Experimental**: Will attempt to automatically align the floating element
138
+ * to avoid collisions with the viewport and being clipped by ancestor
139
+ * elements. Requires React v17+
140
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
138
141
  */
139
142
  autoAlign: PropTypes.bool,
140
143
  /**
@@ -26,7 +26,10 @@ export interface PopoverBaseProps {
26
26
  */
27
27
  align?: PopoverAlignment;
28
28
  /**
29
- * Will auto-align the popover on first render if it is not visible. This prop is currently experimental and is subject to future changes.
29
+ * Will auto-align the popover on first render if it is not visible. This prop
30
+ * is currently experimental and is subject to future changes. Requires
31
+ * React v17+
32
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
30
33
  */
31
34
  autoAlign?: boolean;
32
35
  /**
@@ -64,7 +64,14 @@ forwardRef) {
64
64
  // The `Popover` should close whenever it and its children loses focus
65
65
  useEvent.useEvent(popover, 'focusout', event => {
66
66
  const relatedTarget = event.relatedTarget;
67
- if (!popover.current?.contains(relatedTarget)) {
67
+ if (!relatedTarget) {
68
+ return;
69
+ }
70
+ const isOutsideMainContainer = !popover.current?.contains(relatedTarget);
71
+ const isOutsideFloating = enableFloatingStyles && refs.floating.current ? !refs.floating.current.contains(relatedTarget) : true;
72
+
73
+ // Only close if focus moved outside both containers
74
+ if (isOutsideMainContainer && isOutsideFloating) {
68
75
  onRequestClose?.();
69
76
  }
70
77
  });
@@ -293,7 +300,10 @@ Popover.propTypes = {
293
300
  */
294
301
  as: PropTypes.oneOfType([PropTypes.string, PropTypes.elementType]),
295
302
  /**
296
- * Will auto-align the popover on first render if it is not visible. This prop is currently experimental and is subject to future changes.
303
+ * Will auto-align the popover on first render if it is not visible. This prop
304
+ * is currently experimental and is subject to future changes. Requires
305
+ * React v17+
306
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
297
307
  */
298
308
  autoAlign: PropTypes.bool,
299
309
  /**
@@ -353,29 +363,12 @@ function PopoverContentRenderFunction(
353
363
  caretRef,
354
364
  autoAlign
355
365
  } = React.useContext(PopoverContext);
356
- const textRef = React.useRef(null);
357
- const [isMultiLine, setIsMultiLine] = React.useState(false);
358
- const ref = useMergedRefs.useMergedRefs([setFloating, textRef, forwardRef]);
366
+ const ref = useMergedRefs.useMergedRefs([setFloating, forwardRef]);
359
367
  const enableFloatingStyles = index.useFeatureFlag('enable-v12-dynamic-floating-styles') || autoAlign;
360
- React.useEffect(() => {
361
- checkIfMultiLine();
362
- }, [children]);
363
- const checkIfMultiLine = () => {
364
- const el = textRef.current;
365
- if (el) {
366
- const style = getComputedStyle(el);
367
- const lineHeight = parseFloat(style.lineHeight);
368
- const height = el.offsetHeight;
369
- const lines = Math.floor(height / lineHeight);
370
- setIsMultiLine(lines > 1);
371
- }
372
- };
373
368
  return /*#__PURE__*/React.createElement("span", _rollupPluginBabelHelpers.extends({}, rest, {
374
369
  className: `${prefix}--popover`
375
370
  }), /*#__PURE__*/React.createElement("span", {
376
- className: cx(`${prefix}--popover-content`, className, {
377
- [`${prefix}--tooltip-content--multiline`]: isMultiLine
378
- }),
371
+ className: cx(`${prefix}--popover-content`, className),
379
372
  ref: ref
380
373
  }, children, enableFloatingStyles && /*#__PURE__*/React.createElement("span", {
381
374
  className: cx({
@@ -1,3 +1,45 @@
1
- export default IconSwitch;
2
- declare const IconSwitch: React.ForwardRefExoticComponent<React.RefAttributes<any>>;
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
+ */
3
7
  import React from 'react';
8
+ import { type IconButtonProps } from '../IconButton';
9
+ import type { SwitchEventHandlersParams } from './Switch';
10
+ interface IconSwitchProps extends Omit<IconButtonProps, 'onClick' | 'onKeyDown' | 'label' | 'name'> {
11
+ /**
12
+ * The index of the `IconSwitch`.
13
+ *
14
+ * Reserved for usage in `ContentSwitcher`.
15
+ */
16
+ index?: number;
17
+ /**
18
+ * The name of the `IconSwitch`.
19
+ */
20
+ name?: string | number;
21
+ /**
22
+ * A handler that is invoked when a user clicks on the control.
23
+ *
24
+ * Reserved for usage in `ContentSwitcher`.
25
+ */
26
+ onClick?: (params: SwitchEventHandlersParams) => void;
27
+ /**
28
+ * A handler that is invoked on the key down event for the control.
29
+ *
30
+ * Reserved for usage in `ContentSwitcher`.
31
+ */
32
+ onKeyDown?: (params: SwitchEventHandlersParams) => void;
33
+ /**
34
+ * Whether the `IconSwitch` is selected.
35
+ *
36
+ * Reserved for usage in `ContentSwitcher`.
37
+ */
38
+ selected?: boolean;
39
+ /**
40
+ * `Tooltip` text.
41
+ */
42
+ text?: string;
43
+ }
44
+ declare const IconSwitch: React.ForwardRefExoticComponent<IconSwitchProps & React.RefAttributes<HTMLButtonElement>>;
45
+ export default IconSwitch;
@@ -15,9 +15,10 @@ var React = require('react');
15
15
  var cx = require('classnames');
16
16
  var index = require('../IconButton/index.js');
17
17
  var usePrefix = require('../../internal/usePrefix.js');
18
+ var noopFn = require('../../internal/noopFn.js');
18
19
 
19
- const noopFn = () => {};
20
- const IconSwitch = /*#__PURE__*/React.forwardRef(function Switch(props, tabRef) {
20
+ const frFn = React.forwardRef;
21
+ const IconSwitch = frFn((props, ref) => {
21
22
  const {
22
23
  align,
23
24
  children,
@@ -27,8 +28,8 @@ const IconSwitch = /*#__PURE__*/React.forwardRef(function Switch(props, tabRef)
27
28
  index: index$1,
28
29
  leaveDelayMs = 0,
29
30
  name,
30
- onClick = noopFn,
31
- onKeyDown = noopFn,
31
+ onClick = noopFn.noopFn,
32
+ onKeyDown = noopFn.noopFn,
32
33
  selected = false,
33
34
  size,
34
35
  text,
@@ -36,8 +37,8 @@ const IconSwitch = /*#__PURE__*/React.forwardRef(function Switch(props, tabRef)
36
37
  } = props;
37
38
  const prefix = usePrefix.usePrefix();
38
39
  const [isHovered, setIsHovered] = React.useState(false);
39
- const handleClick = e => {
40
- e.preventDefault();
40
+ const handleClick = event => {
41
+ event.preventDefault();
41
42
  onClick({
42
43
  index: index$1,
43
44
  name,
@@ -45,6 +46,7 @@ const IconSwitch = /*#__PURE__*/React.forwardRef(function Switch(props, tabRef)
45
46
  });
46
47
  };
47
48
  const handleKeyDown = event => {
49
+ // TODO: `which` was deprecated years ago. When can its usage be deleted?
48
50
  const key = event.key || event.which;
49
51
  onKeyDown({
50
52
  index: index$1,
@@ -66,20 +68,10 @@ const IconSwitch = /*#__PURE__*/React.forwardRef(function Switch(props, tabRef)
66
68
  [`${prefix}--content-switcher-popover--selected`]: selected,
67
69
  [`${prefix}--content-switcher-popover--disabled`]: disabled
68
70
  });
69
- const commonProps = {
70
- onClick: handleClick,
71
- onKeyDown: handleKeyDown,
72
- className: classes,
73
- disabled,
74
- align,
75
- enterDelayMs,
76
- leaveDelayMs,
77
- size
78
- };
79
71
  return /*#__PURE__*/React.createElement(index.IconButton, _rollupPluginBabelHelpers.extends({
80
72
  label: text,
81
73
  type: "button",
82
- ref: tabRef,
74
+ ref: ref,
83
75
  role: "tab",
84
76
  tabIndex: selected || isHovered ? 0 : -1,
85
77
  onMouseEnter: handleMouseEnter,
@@ -89,7 +81,16 @@ const IconSwitch = /*#__PURE__*/React.forwardRef(function Switch(props, tabRef)
89
81
  "aria-selected": selected,
90
82
  "aria-label": text,
91
83
  wrapperClasses: iconButtonClasses
92
- }, other, commonProps), children);
84
+ }, other, {
85
+ align: align,
86
+ className: classes,
87
+ disabled: disabled,
88
+ enterDelayMs: enterDelayMs,
89
+ leaveDelayMs: leaveDelayMs,
90
+ onClick: handleClick,
91
+ onKeyDown: handleKeyDown,
92
+ size: size
93
+ }), children);
93
94
  });
94
95
  IconSwitch.displayName = 'IconSwitch';
95
96
  IconSwitch.propTypes = {
@@ -98,15 +99,15 @@ IconSwitch.propTypes = {
98
99
  */
99
100
  align: PropTypes.oneOf(['top', 'top-left', 'top-right', 'bottom', 'bottom-left', 'bottom-right', 'left', 'right']),
100
101
  /**
101
- * Provide child elements to be rendered inside of the Switch
102
+ * Children to be rendered inside of the `IconSwitch`.
102
103
  */
103
104
  children: PropTypes.node,
104
105
  /**
105
- * Specify an optional className to be added to your Switch
106
+ * Specify an optional className to be added to your `IconSwitch`.
106
107
  */
107
108
  className: PropTypes.string,
108
109
  /**
109
- * Specify whether or not the Switch should be disabled
110
+ * Whether the `IconSwitch` should be disabled.
110
111
  */
111
112
  disabled: PropTypes.bool,
112
113
  /**
@@ -114,8 +115,9 @@ IconSwitch.propTypes = {
114
115
  */
115
116
  enterDelayMs: PropTypes.number,
116
117
  /**
117
- * The index of your Switch in your ContentSwitcher that is used for event handlers.
118
- * Reserved for usage in ContentSwitcher
118
+ * The index of the `IconSwitch`.
119
+ *
120
+ * Reserved for usage in `ContentSwitcher`.
119
121
  */
120
122
  index: PropTypes.number,
121
123
  /**
@@ -123,29 +125,34 @@ IconSwitch.propTypes = {
123
125
  */
124
126
  leaveDelayMs: PropTypes.number,
125
127
  /**
126
- * Provide the name of your Switch that is used for event handlers
128
+ * The name of the `IconSwitch`.
127
129
  */
128
130
  name: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
129
131
  /**
130
132
  * A handler that is invoked when a user clicks on the control.
131
- * Reserved for usage in ContentSwitcher
133
+ *
134
+ * Reserved for usage in `ContentSwitcher`.
132
135
  */
133
136
  onClick: PropTypes.func,
134
137
  /**
135
138
  * A handler that is invoked on the key down event for the control.
136
- * Reserved for usage in ContentSwitcher
139
+ *
140
+ * Reserved for usage in `ContentSwitcher`.
137
141
  */
138
142
  onKeyDown: PropTypes.func,
139
143
  /**
140
- * Whether your Switch is selected. Reserved for usage in ContentSwitcher
144
+ * Whether the `IconSwitch` is selected.
145
+ *
146
+ * Reserved for usage in `ContentSwitcher`.
141
147
  */
142
148
  selected: PropTypes.bool,
149
+ // TODO: Icon only variant of what? Isn't the `IconSwitch` always icon only?
143
150
  /**
144
151
  * Passed in from `ContentSwitcher` to render icon-only variant
145
152
  */
146
153
  size: PropTypes.oneOf(['sm', 'md', 'lg']),
147
154
  /**
148
- * Provide the visible text displayed by the Tooltip
155
+ * `Tooltip` text.
149
156
  */
150
157
  text: PropTypes.string
151
158
  };
@@ -39,6 +39,7 @@ const Switch = /*#__PURE__*/React.forwardRef(function Switch(props, tabRef) {
39
39
  });
40
40
  };
41
41
  const handleKeyDown = event => {
42
+ // TODO: `which` was deprecated years ago. When can its usage be deleted?
42
43
  const key = event.key || event.which;
43
44
  onKeyDown?.({
44
45
  index,
@@ -63,7 +63,11 @@ const TextArea = frFn((props, forwardRef) => {
63
63
  value
64
64
  } = other;
65
65
  const textAreaInstanceId = useId.useId();
66
+ const wrapperRef = React.useRef(null);
66
67
  const textareaRef = React.useRef(null);
68
+ const helperTextRef = React.useRef(null);
69
+ const errorTextRef = React.useRef(null);
70
+ const warnTextRef = React.useRef(null);
67
71
  const ref = useMergedRefs.useMergedRefs([forwardRef, textareaRef]);
68
72
  function getInitialTextCount() {
69
73
  const targetValue = defaultValue || value || textareaRef.current?.value || '';
@@ -80,13 +84,20 @@ const TextArea = frFn((props, forwardRef) => {
80
84
  // eslint-disable-next-line react-hooks/exhaustive-deps
81
85
  }, [value, defaultValue, counterMode]);
82
86
  useIsomorphicEffect.default(() => {
87
+ const measuredWidth = wrapperRef.current?.scrollWidth;
83
88
  if (other.cols && textareaRef.current) {
84
89
  textareaRef.current.style.width = '';
85
90
  textareaRef.current.style.resize = 'none';
86
91
  } else if (textareaRef.current) {
87
92
  textareaRef.current.style.width = `100%`;
88
93
  }
89
- }, [other.cols]);
94
+ [helperTextRef, errorTextRef, warnTextRef].forEach(r => {
95
+ if (r.current) {
96
+ r.current.style.maxWidth = `${measuredWidth}px`;
97
+ r.current.style.overflowWrap = 'break-word';
98
+ }
99
+ });
100
+ }, [other.cols, invalid, warn]);
90
101
  const textareaProps = {
91
102
  id,
92
103
  onKeyDown: evt => {
@@ -194,21 +205,26 @@ const TextArea = frFn((props, forwardRef) => {
194
205
  const helper = helperText ? /*#__PURE__*/React.createElement(Text.Text, {
195
206
  as: "div",
196
207
  id: helperId,
197
- className: helperTextClasses
208
+ className: helperTextClasses,
209
+ ref: helperTextRef
198
210
  }, helperText) : null;
199
211
  const errorId = id + '-error-msg';
200
212
  const error = invalid ? /*#__PURE__*/React.createElement(Text.Text, {
201
213
  as: "div",
202
214
  role: "alert",
203
215
  className: `${prefix}--form-requirement`,
204
- id: errorId
216
+ id: errorId,
217
+ ref: errorTextRef
205
218
  }, invalidText, isFluid && /*#__PURE__*/React.createElement(iconsReact.WarningFilled, {
206
219
  className: `${prefix}--text-area__invalid-icon`
207
220
  })) : null;
221
+ const warnId = id + '-warn-msg';
208
222
  const warning = warn ? /*#__PURE__*/React.createElement(Text.Text, {
209
223
  as: "div",
210
224
  role: "alert",
211
- className: `${prefix}--form-requirement`
225
+ className: `${prefix}--form-requirement`,
226
+ id: warnId,
227
+ ref: warnTextRef
212
228
  }, warnText, isFluid && /*#__PURE__*/React.createElement(iconsReact.WarningAltFilled, {
213
229
  className: `${prefix}--text-area__invalid-icon ${prefix}--text-area__invalid-icon--warning`
214
230
  })) : null;
@@ -274,6 +290,7 @@ const TextArea = frFn((props, forwardRef) => {
274
290
  }, /*#__PURE__*/React.createElement("div", {
275
291
  className: `${prefix}--text-area__label-wrapper`
276
292
  }, label, counter), /*#__PURE__*/React.createElement("div", {
293
+ ref: wrapperRef,
277
294
  className: textAreaWrapperClasses,
278
295
  "data-invalid": invalid || null
279
296
  }, invalid && !isFluid && /*#__PURE__*/React.createElement(iconsReact.WarningFilled, {
@@ -67,7 +67,10 @@ export declare namespace Toggletip {
67
67
  */
68
68
  as: PropTypes.Requireable<PropTypes.ReactComponentLike>;
69
69
  /**
70
- * Will auto-align the popover on first render if it is not visible. This prop is currently experimental and is subject to future changes.
70
+ * Will auto-align the popover on first render if it is not visible. This prop
71
+ * is currently experimental and is subject to future changes. Requires
72
+ * React v17+
73
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
71
74
  */
72
75
  autoAlign: PropTypes.Requireable<boolean>;
73
76
  /**
@@ -187,7 +187,10 @@ Toggletip.propTypes = {
187
187
  */
188
188
  as: PropTypes.elementType,
189
189
  /**
190
- * Will auto-align the popover on first render if it is not visible. This prop is currently experimental and is subject to future changes.
190
+ * Will auto-align the popover on first render if it is not visible. This prop
191
+ * is currently experimental and is subject to future changes. Requires
192
+ * React v17+
193
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
191
194
  */
192
195
  autoAlign: PropTypes.bool,
193
196
  /**
@@ -12,13 +12,15 @@ export interface DefinitionTooltipProps extends Omit<React.ButtonHTMLAttributes<
12
12
  */
13
13
  align?: PopoverAlignment;
14
14
  /**
15
- * Will auto-align Definition Tooltip. This prop is currently experimental and is subject to future changes.
15
+ * Will auto-align Definition Tooltip. This prop is currently experimental
16
+ * and is subject to future changes. Requires React v17+
17
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
16
18
  */
17
19
  autoAlign?: boolean;
18
20
  /**
19
21
  * The `children` prop will be used as the value that is being defined
20
22
  */
21
- children?: React.ReactNode;
23
+ children: React.ReactNode;
22
24
  /**
23
25
  * Specify an optional className to be applied to the container node
24
26
  */
@@ -103,7 +103,9 @@ DefinitionTooltip.propTypes = {
103
103
  // new values to match floating-ui
104
104
  'top-start', 'top-end', 'bottom-start', 'bottom-end', 'left-end', 'left-start', 'right-end', 'right-start']),
105
105
  /**
106
- * Will auto-align the popover. This prop is currently experimental and is subject to future changes.
106
+ * Will auto-align the popover. This prop is currently experimental and is
107
+ * subject to future changes. Requires React v17+
108
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
107
109
  */
108
110
  autoAlign: PropTypes.bool,
109
111
  /**
@@ -54,9 +54,6 @@ interface TooltipBaseProps {
54
54
  /**
55
55
  * Provide the label to be rendered inside of the Tooltip. The label will use
56
56
  * `aria-labelledby` and will fully describe the child node that is provided.
57
- * If the child already has an `aria-label`, the tooltip will not apply
58
- * `aria-labelledby`. If the child has its own `aria-labelledby`, that value
59
- * will be kept. Otherwise, the tooltip will use its own ID to label the child.
60
57
  * This means that if you have text in the child node, that it will not be
61
58
  * announced to the screen reader.
62
59
  *
@@ -48,20 +48,12 @@ const Tooltip = /*#__PURE__*/React.forwardRef(({
48
48
  const prefix = usePrefix.usePrefix();
49
49
  const child = React.Children.only(children);
50
50
  const {
51
- 'aria-label': ariaLabel,
52
51
  'aria-labelledby': ariaLabelledBy,
53
52
  'aria-describedby': ariaDescribedBy
54
53
  } = child?.props ?? {};
55
54
  const hasLabel = !!label;
56
- const hasAriaLabel = typeof ariaLabel === 'string' ? ariaLabel.trim() !== '' : false;
57
-
58
- // An `aria-label` takes precedence over `aria-describedby`, but when it's
59
- // needed and the user doesn't specify one, the fallback `id` is used.
60
- const labelledBy = hasAriaLabel ? undefined : hasLabel ? ariaLabelledBy ?? id : undefined;
61
-
62
- // If `aria-label` is present, use any provided `aria-describedby`.
63
- // If not, fallback to child's `aria-describedby` or the tooltip `id` if needed.
64
- const describedBy = hasAriaLabel ? ariaDescribedBy : ariaDescribedBy ?? (!hasLabel && !ariaLabelledBy ? id : undefined);
55
+ const labelledBy = ariaLabelledBy ?? (hasLabel ? id : undefined);
56
+ const describedBy = ariaDescribedBy ?? (!hasLabel ? id : undefined);
65
57
  const triggerProps = {
66
58
  onFocus: () => !focusByMouse && setOpen(true),
67
59
  onBlur: () => {
@@ -88,7 +88,8 @@ export type TreeNodeProps = {
88
88
  /**
89
89
  * **Experimental**: Will attempt to automatically align the floating
90
90
  * element to avoid collisions with the viewport and being clipped by
91
- * ancestor elements.
91
+ * ancestor elements. Requires React v17+
92
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
92
93
  */
93
94
  autoAlign?: boolean;
94
95
  } & Omit<React.LiHTMLAttributes<HTMLElement>, 'onSelect'>;
@@ -173,7 +174,8 @@ declare const TreeNode: React.ForwardRefExoticComponent<{
173
174
  /**
174
175
  * **Experimental**: Will attempt to automatically align the floating
175
176
  * element to avoid collisions with the viewport and being clipped by
176
- * ancestor elements.
177
+ * ancestor elements. Requires React v17+
178
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
177
179
  */
178
180
  autoAlign?: boolean;
179
181
  } & Omit<React.LiHTMLAttributes<HTMLElement>, "onSelect"> & React.RefAttributes<HTMLElement>>;
@@ -494,7 +494,8 @@ TreeNode.propTypes = {
494
494
  /**
495
495
  * **Experimental**: Will attempt to automatically align the floating
496
496
  * element to avoid collisions with the viewport and being clipped by
497
- * ancestor elements.
497
+ * ancestor elements. Requires React v17+
498
+ * @see https://github.com/carbon-design-system/carbon/issues/18714
498
499
  */
499
500
  autoAlign: PropTypes.bool
500
501
  };
@@ -8,15 +8,15 @@ import React, { ReactNode } from 'react';
8
8
  export interface HeaderProps {
9
9
  children?: ReactNode;
10
10
  /**
11
- * Required props for the accessibility label of the header
11
+ * Optionally provide aria-label
12
12
  */
13
13
  'aria-label'?: string;
14
14
  /**
15
- * Required props for the accessibility label of the header
15
+ * Optionally provide aria-labelledby
16
16
  */
17
17
  'aria-labelledby'?: string;
18
18
  /**
19
- * Optionally provide a custom class name that is applied to the underlying <header>
19
+ * Optionally provide a custom class name that is applied to the underlying header
20
20
  */
21
21
  className?: string;
22
22
  }