@carbon/react 1.79.0 → 1.80.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 (157) hide show
  1. package/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +835 -779
  2. package/es/components/CodeSnippet/CodeSnippet.js +1 -1
  3. package/es/components/ComposedModal/ComposedModal.d.ts +6 -0
  4. package/es/components/ComposedModal/ModalFooter.d.ts +6 -0
  5. package/es/components/ContainedList/index.js +1 -1
  6. package/es/components/DataTable/DataTable.d.ts +3 -1
  7. package/es/components/DatePicker/DatePicker.d.ts +1 -1
  8. package/es/components/DatePicker/DatePicker.js +1 -1
  9. package/es/components/FluidTextArea/FluidTextArea.Skeleton.d.ts +6 -0
  10. package/es/components/InlineLoading/InlineLoading.js +10 -2
  11. package/es/components/Layer/LayerLevel.d.ts +6 -0
  12. package/es/components/Menu/Menu.d.ts +1 -1
  13. package/es/components/Menu/MenuItem.d.ts +4 -4
  14. package/es/components/Menu/MenuItem.js +1 -1
  15. package/es/components/Modal/Modal.js +1 -1
  16. package/es/components/ModalWrapper/ModalWrapper.d.ts +1 -1
  17. package/es/components/ModalWrapper/ModalWrapper.js +2 -1
  18. package/es/components/Notification/Notification.js +1 -1
  19. package/es/components/NumberInput/NumberInput.d.ts +1 -1
  20. package/es/components/OverflowMenu/OverflowMenu.js +3 -3
  21. package/es/components/OverflowMenuItem/OverflowMenuItem.js +1 -3
  22. package/es/components/OverflowMenuV2/index.js +1 -1
  23. package/es/components/PageHeader/PageHeader.d.ts +101 -0
  24. package/es/components/PageHeader/PageHeader.js +241 -0
  25. package/es/components/PageHeader/index.d.ts +8 -0
  26. package/es/components/PageHeader/index.js +8 -0
  27. package/es/components/PasswordInput/index.d.ts +6 -0
  28. package/es/components/Popover/index.js +1 -1
  29. package/es/components/Slider/SliderHandles.d.ts +6 -0
  30. package/es/components/Tag/DismissibleTag.d.ts +1 -55
  31. package/es/components/Tag/DismissibleTag.js +6 -4
  32. package/es/components/Tag/OperationalTag.d.ts +1 -1
  33. package/es/components/Tag/SelectableTag.d.ts +1 -43
  34. package/es/components/Tag/SelectableTag.js +7 -5
  35. package/es/components/Tag/Tag.js +2 -2
  36. package/es/components/Text/createTextComponent.js +1 -1
  37. package/es/components/TextArea/TextArea.d.ts +3 -3
  38. package/es/components/TextArea/TextArea.js +5 -2
  39. package/es/components/TextInput/ControlledPasswordInput.d.ts +6 -0
  40. package/es/components/TextInput/ControlledPasswordInput.js +1 -1
  41. package/es/components/TextInput/PasswordInput.d.ts +6 -0
  42. package/es/components/TextInput/index.js +1 -1
  43. package/es/components/Tile/Tile.d.ts +1 -1
  44. package/es/components/Tile/Tile.js +1 -4
  45. package/es/components/TreeView/TreeNode.d.ts +1 -1
  46. package/es/components/TreeView/TreeNode.js +11 -4
  47. package/es/components/TreeView/TreeView.d.ts +1 -1
  48. package/es/components/TreeView/TreeView.js +6 -6
  49. package/es/components/UIShell/Switcher.d.ts +1 -7
  50. package/es/components/UIShell/SwitcherDivider.d.ts +6 -0
  51. package/es/components/UIShell/SwitcherItem.d.ts +6 -0
  52. package/es/index.d.ts +5 -1
  53. package/es/index.js +3 -1
  54. package/es/internal/ClickListener.d.ts +13 -0
  55. package/es/internal/ClickListener.js +33 -60
  56. package/es/internal/FloatingMenu.js +2 -2
  57. package/es/internal/PolymorphicProps.d.ts +6 -0
  58. package/es/internal/deprecateFieldOnObject.d.ts +12 -0
  59. package/es/internal/deprecateFieldOnObject.js +4 -4
  60. package/es/internal/useControllableState.d.ts +34 -0
  61. package/es/internal/useControllableState.js +17 -32
  62. package/es/internal/useEvent.js +1 -1
  63. package/es/internal/useMergedRefs.d.ts +9 -6
  64. package/es/internal/useMergedRefs.js +8 -9
  65. package/es/internal/useNoInteractiveChildren.js +2 -2
  66. package/es/internal/useOutsideClick.d.ts +8 -0
  67. package/es/internal/useOutsideClick.js +9 -6
  68. package/es/internal/useSavedCallback.d.ts +15 -0
  69. package/es/internal/useSavedCallback.js +9 -12
  70. package/es/internal/warning.d.ts +17 -0
  71. package/es/internal/warning.js +16 -12
  72. package/es/internal/wrapFocus.js +1 -1
  73. package/es/prop-types/isRequiredOneOf.js +1 -1
  74. package/es/prop-types/requiredIfGivenPropIsTruthy.js +1 -1
  75. package/es/tools/events.js +1 -6
  76. package/es/tools/toggleClass.js +6 -0
  77. package/es/types/common.d.ts +6 -0
  78. package/lib/components/CodeSnippet/CodeSnippet.js +1 -1
  79. package/lib/components/ComposedModal/ComposedModal.d.ts +6 -0
  80. package/lib/components/ComposedModal/ModalFooter.d.ts +6 -0
  81. package/lib/components/ContainedList/index.js +1 -1
  82. package/lib/components/DataTable/DataTable.d.ts +3 -1
  83. package/lib/components/DatePicker/DatePicker.d.ts +1 -1
  84. package/lib/components/DatePicker/DatePicker.js +1 -1
  85. package/lib/components/FluidTextArea/FluidTextArea.Skeleton.d.ts +6 -0
  86. package/lib/components/InlineLoading/InlineLoading.js +10 -2
  87. package/lib/components/Layer/LayerLevel.d.ts +6 -0
  88. package/lib/components/Menu/Menu.d.ts +1 -1
  89. package/lib/components/Menu/MenuItem.d.ts +4 -4
  90. package/lib/components/Menu/MenuItem.js +1 -1
  91. package/lib/components/Modal/Modal.js +1 -1
  92. package/lib/components/ModalWrapper/ModalWrapper.d.ts +1 -1
  93. package/lib/components/ModalWrapper/ModalWrapper.js +2 -1
  94. package/lib/components/Notification/Notification.js +1 -1
  95. package/lib/components/NumberInput/NumberInput.d.ts +1 -1
  96. package/lib/components/OverflowMenu/OverflowMenu.js +3 -3
  97. package/lib/components/OverflowMenuItem/OverflowMenuItem.js +1 -3
  98. package/lib/components/OverflowMenuV2/index.js +1 -1
  99. package/lib/components/PageHeader/PageHeader.d.ts +101 -0
  100. package/lib/components/PageHeader/PageHeader.js +260 -0
  101. package/lib/components/PageHeader/index.d.ts +8 -0
  102. package/lib/components/PageHeader/index.js +25 -0
  103. package/lib/components/PasswordInput/index.d.ts +6 -0
  104. package/lib/components/Popover/index.js +1 -1
  105. package/lib/components/Slider/SliderHandles.d.ts +6 -0
  106. package/lib/components/Tag/DismissibleTag.d.ts +1 -55
  107. package/lib/components/Tag/DismissibleTag.js +5 -3
  108. package/lib/components/Tag/OperationalTag.d.ts +1 -1
  109. package/lib/components/Tag/SelectableTag.d.ts +1 -43
  110. package/lib/components/Tag/SelectableTag.js +6 -4
  111. package/lib/components/Tag/Tag.js +2 -2
  112. package/lib/components/Text/createTextComponent.js +1 -1
  113. package/lib/components/TextArea/TextArea.d.ts +3 -3
  114. package/lib/components/TextArea/TextArea.js +4 -1
  115. package/lib/components/TextInput/ControlledPasswordInput.d.ts +6 -0
  116. package/lib/components/TextInput/ControlledPasswordInput.js +1 -1
  117. package/lib/components/TextInput/PasswordInput.d.ts +6 -0
  118. package/lib/components/TextInput/index.js +1 -1
  119. package/lib/components/Tile/Tile.d.ts +1 -1
  120. package/lib/components/Tile/Tile.js +1 -4
  121. package/lib/components/TreeView/TreeNode.d.ts +1 -1
  122. package/lib/components/TreeView/TreeNode.js +11 -4
  123. package/lib/components/TreeView/TreeView.d.ts +1 -1
  124. package/lib/components/TreeView/TreeView.js +6 -6
  125. package/lib/components/UIShell/Switcher.d.ts +1 -7
  126. package/lib/components/UIShell/SwitcherDivider.d.ts +6 -0
  127. package/lib/components/UIShell/SwitcherItem.d.ts +6 -0
  128. package/lib/index.d.ts +5 -1
  129. package/lib/index.js +62 -57
  130. package/lib/internal/ClickListener.d.ts +13 -0
  131. package/lib/internal/ClickListener.js +32 -64
  132. package/lib/internal/FloatingMenu.js +2 -2
  133. package/lib/internal/PolymorphicProps.d.ts +6 -0
  134. package/lib/internal/deprecateFieldOnObject.d.ts +12 -0
  135. package/lib/internal/deprecateFieldOnObject.js +4 -4
  136. package/lib/internal/useControllableState.d.ts +34 -0
  137. package/lib/internal/useControllableState.js +17 -32
  138. package/lib/internal/useEvent.js +1 -1
  139. package/lib/internal/useMergedRefs.d.ts +9 -6
  140. package/lib/internal/useMergedRefs.js +8 -9
  141. package/lib/internal/useNoInteractiveChildren.js +2 -2
  142. package/lib/internal/useOutsideClick.d.ts +8 -0
  143. package/lib/internal/useOutsideClick.js +9 -6
  144. package/lib/internal/useSavedCallback.d.ts +15 -0
  145. package/lib/internal/useSavedCallback.js +9 -12
  146. package/lib/internal/warning.d.ts +17 -0
  147. package/lib/internal/warning.js +16 -12
  148. package/lib/internal/wrapFocus.js +1 -1
  149. package/lib/prop-types/isRequiredOneOf.js +1 -1
  150. package/lib/prop-types/requiredIfGivenPropIsTruthy.js +1 -1
  151. package/lib/tools/events.js +1 -6
  152. package/lib/tools/toggleClass.js +6 -0
  153. package/lib/types/common.d.ts +6 -0
  154. package/package.json +9 -8
  155. package/scss/components/page-header/_index.scss +9 -0
  156. package/scss/components/page-header/_page-header.scss +9 -0
  157. package/telemetry.yml +62 -23
@@ -5,70 +5,43 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import { defineProperty as _defineProperty } from '../_virtual/_rollupPluginBabelHelpers.js';
9
- import PropTypes from 'prop-types';
10
- import React__default from 'react';
8
+ import { useRef, useEffect, cloneElement } from 'react';
11
9
 
12
- /**
13
- * Generic component used for reacting to a click event happening outside of a
14
- * given `children` element.
15
- */
16
- class ClickListener extends React__default.Component {
17
- static getEventTarget(evt) {
18
- // support Shadow DOM
19
- if (evt.composed && typeof evt.composedPath === 'function') {
20
- return evt.composedPath()[0];
10
+ const ClickListener = _ref => {
11
+ let {
12
+ children,
13
+ onClickOutside
14
+ } = _ref;
15
+ const elementRef = useRef(null);
16
+ const getEventTarget = event => {
17
+ if (event.composed && typeof event.composedPath === 'function') {
18
+ return event.composedPath()[0];
21
19
  }
22
- return evt.target;
23
- }
24
- constructor(props) {
25
- super(props);
26
- // We manually bind handlers in this Component, versus using class
27
- // properties, so that we can properly test the `handleRef` handler.
28
- this.handleRef = this.handleRef.bind(this);
29
- this.handleDocumentClick = this.handleDocumentClick.bind(this);
30
- }
31
- componentDidMount() {
32
- document.addEventListener('click', this.handleDocumentClick);
33
- }
34
- componentWillUnmount() {
35
- document.removeEventListener('click', this.handleDocumentClick);
36
- }
37
- handleDocumentClick(evt) {
38
- if (this.element) {
39
- if (this.element.contains && !this.element.contains(ClickListener.getEventTarget(evt))) {
40
- this.props.onClickOutside(evt);
20
+ return event.target;
21
+ };
22
+ const handleDocumentClick = event => {
23
+ if (elementRef.current?.contains) {
24
+ const eventTarget = getEventTarget(event);
25
+ if (eventTarget instanceof Node && !elementRef.current.contains(eventTarget)) {
26
+ onClickOutside(event);
41
27
  }
42
28
  }
43
- }
44
- handleRef(el) {
45
- const {
46
- children
47
- } = this.props;
48
- this.element = el;
49
-
50
- /**
51
- * One important note, `children.ref` corresponds to a `ref` prop passed in
52
- * directly to the child, not necessarily a `ref` defined in the component.
53
- * This means that here we target the following `ref` location:
54
- *
55
- * <ClickListener onClickOutside={() => {}}>
56
- * <Child ref={targetedRefHere} />
57
- * </ClickListener>
58
- */
59
- if (children.ref && typeof children.ref === 'function') {
29
+ };
30
+ useEffect(() => {
31
+ document.addEventListener('click', handleDocumentClick);
32
+ return () => {
33
+ document.removeEventListener('click', handleDocumentClick);
34
+ };
35
+ }, [onClickOutside]);
36
+ const handleRef = el => {
37
+ elementRef.current = el;
38
+ if ('ref' in children && typeof children.ref === 'function') {
60
39
  children.ref(el);
61
40
  }
62
- }
63
- render() {
64
- return /*#__PURE__*/React__default.cloneElement(this.props.children, {
65
- ref: this.handleRef
66
- });
67
- }
68
- }
69
- _defineProperty(ClickListener, "propTypes", {
70
- children: PropTypes.element.isRequired,
71
- onClickOutside: PropTypes.func.isRequired
72
- });
41
+ };
42
+ return /*#__PURE__*/cloneElement(children, {
43
+ ref: handleRef
44
+ });
45
+ };
73
46
 
74
- export { ClickListener as default };
47
+ export { ClickListener };
@@ -104,7 +104,7 @@ const FloatingMenu = _ref2 => {
104
104
  const updateMenuPosition = useCallback(isAdjustment => {
105
105
  const menuBody = menuBodyRef.current;
106
106
  if (!menuBody) {
107
- process.env.NODE_ENV !== "production" ? warning(menuBody, 'The DOM node for menu body for calculating its position is not available. Skipping...') : void 0;
107
+ process.env.NODE_ENV !== "production" ? warning(!!menuBody, 'The DOM node for menu body for calculating its position is not available. Skipping...') : void 0;
108
108
  return;
109
109
  }
110
110
  const triggerEl = triggerRef.current;
@@ -174,7 +174,7 @@ const FloatingMenu = _ref2 => {
174
174
  // First programmatic focusable node
175
175
  menuBody;
176
176
  focusTarget.focus();
177
- if (focusTarget === menuBody && process.env.NODE_ENV !== "production") {
177
+ if (focusTarget === menuBody) {
178
178
  process.env.NODE_ENV !== "production" ? warning(focusableNode === null, 'Floating Menus must have at least a programmatically focusable child. This can be accomplished by adding tabIndex="-1" to the content element.') : void 0;
179
179
  }
180
180
  };
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Copyright IBM Corp. 2025
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
+ */
1
7
  type AsProp<C extends React.ElementType> = {
2
8
  as?: C;
3
9
  };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2025
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
+ export declare const deprecateFieldOnObject: <T extends {
8
+ displayName?: string;
9
+ }>(object: T, field: string, Component: {
10
+ displayName?: string;
11
+ name?: string;
12
+ }, message?: string) => void;
@@ -7,11 +7,11 @@
7
7
 
8
8
  import { warning } from './warning.js';
9
9
 
10
- const didWarnAboutDeprecation = {};
11
- function deprecateFieldOnObject(object, field, Component, message) {
10
+ const deprecateFieldOnObject = (object, field, Component, message) => {
11
+ const didWarnAboutDeprecation = {};
12
12
  Object.defineProperty(object, field, {
13
13
  enumerable: true,
14
- get() {
14
+ get: () => {
15
15
  if (!didWarnAboutDeprecation[field]) {
16
16
  process.env.NODE_ENV !== "production" ? warning(false, message || `The ${field} field has been deprecated on the ${object.displayName} object. ` + `Please import and use ${Component.displayName || Component.name || 'the field'} directly.`) : void 0;
17
17
  didWarnAboutDeprecation[field] = true;
@@ -19,6 +19,6 @@ function deprecateFieldOnObject(object, field, Component, message) {
19
19
  return Component;
20
20
  }
21
21
  });
22
- }
22
+ };
23
23
 
24
24
  export { deprecateFieldOnObject };
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2025
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
+ interface UseControllableStateConfig<T> {
8
+ /** The name of the component. */
9
+ name?: string;
10
+ /**
11
+ * The default value for the component. This value is used when the component
12
+ * is uncontrolled (i.e., when `value` is not provided).
13
+ */
14
+ defaultValue: T;
15
+ /**
16
+ * This callback is called whenever the state changes. It's useful for
17
+ * communicating state updates to parent components of controlled components.
18
+ */
19
+ onChange?: (value: T) => void;
20
+ /**
21
+ * Controlled value. If this prop is omitted, the state will be uncontrolled.
22
+ */
23
+ value?: T;
24
+ }
25
+ /**
26
+ * This hook simplifies the behavior of a component that has state which can be
27
+ * both controlled and uncontrolled. It works like `useState`. You can use the
28
+ * `onChange` callback to communicate state updates to parent components.
29
+ *
30
+ * Note: This hook will warn if the component switches between controlled and
31
+ * uncontrolled states.
32
+ */
33
+ export declare const useControllableState: <T>({ defaultValue, name, onChange, value, }: UseControllableStateConfig<T>) => [T, (stateOrUpdater: T | ((prev: T) => T)) => void];
34
+ export {};
@@ -9,66 +9,51 @@ import { useState, useRef, useEffect } from 'react';
9
9
  import { warning } from './warning.js';
10
10
 
11
11
  /**
12
- * This custom hook simplifies the behavior of a component if it has state that
13
- * can be both controlled and uncontrolled. It functions identical to a
14
- * useState() hook and provides [state, setState] for you to use. You can use
15
- * the `onChange` argument to allow updates to the `state` to be communicated to
16
- * owners of controlled components.
12
+ * This hook simplifies the behavior of a component that has state which can be
13
+ * both controlled and uncontrolled. It works like `useState`. You can use the
14
+ * `onChange` callback to communicate state updates to parent components.
17
15
  *
18
- * Note: this hook will warn if a component is switching from controlled to
19
- * uncontrolled, or vice-versa.
20
- *
21
- * @param {object} config
22
- * @param {string} [config.name] - the name of the custom component
23
- * @param {any} config.defaultValue - the default value used for the state. This will be
24
- * the fallback value used if `value` is not defined.
25
- * @param {Function|undefined} config.onChange - an optional function that is called when
26
- * the value of the state changes. This is useful for communicating to parents of
27
- * controlled components that the value is requesting to be changed.
28
- * @param {any} config.value - a controlled value. Omitting this means that the state is
29
- * uncontrolled
30
- * @returns {[any, (v: any) => void]}
16
+ * Note: This hook will warn if the component switches between controlled and
17
+ * uncontrolled states.
31
18
  */
32
- function useControllableState(_ref) {
19
+ const useControllableState = _ref => {
33
20
  let {
34
21
  defaultValue,
35
22
  name = 'custom',
36
23
  onChange,
37
24
  value
38
25
  } = _ref;
39
- const [state, internalSetState] = useState(value ?? defaultValue);
26
+ const [state, internalSetState] = useState(typeof value !== 'undefined' ? value : defaultValue);
40
27
  const controlled = useRef(null);
41
28
  if (controlled.current === null) {
42
- controlled.current = value !== undefined;
29
+ controlled.current = typeof value !== 'undefined';
43
30
  }
44
- function setState(stateOrUpdater) {
45
- const value = typeof stateOrUpdater === 'function' ? stateOrUpdater(state) : stateOrUpdater;
31
+ const setState = stateOrUpdater => {
32
+ const newValue = typeof stateOrUpdater === 'function' ? stateOrUpdater(state) : stateOrUpdater;
46
33
  if (controlled.current === false) {
47
- internalSetState(value);
34
+ internalSetState(newValue);
48
35
  }
49
36
  if (onChange) {
50
- onChange(value);
37
+ onChange(newValue);
51
38
  }
52
- }
39
+ };
53
40
  useEffect(() => {
54
- const controlledValue = value !== undefined;
41
+ const controlledValue = typeof value !== 'undefined';
55
42
 
56
43
  // Uncontrolled -> Controlled
57
- // If the component prop is uncontrolled, the prop value should be undefined
58
44
  if (controlled.current === false && controlledValue) {
59
- process.env.NODE_ENV !== "production" ? warning(false, 'A component is changing an uncontrolled %s component to be controlled. ' + 'This is likely caused by the value changing to a defined value ' + 'from undefined. Decide between using a controlled or uncontrolled ' + 'value for the lifetime of the component. ' + 'More info: https://reactjs.org/link/controlled-components', name) : void 0;
45
+ process.env.NODE_ENV !== "production" ? warning(false, `A component is changing an uncontrolled ${name} component to be controlled. ` + 'This is likely caused by the value changing to a defined value ' + 'from undefined. Decide between using a controlled or uncontrolled ' + 'value for the lifetime of the component. ' + 'More info: https://reactjs.org/link/controlled-components') : void 0;
60
46
  }
61
47
 
62
48
  // Controlled -> Uncontrolled
63
- // If the component prop is controlled, the prop value should be defined
64
49
  if (controlled.current === true && !controlledValue) {
65
- process.env.NODE_ENV !== "production" ? warning(false, 'A component is changing a controlled %s component to be uncontrolled. ' + 'This is likely caused by the value changing to an undefined value ' + 'from a defined one. Decide between using a controlled or ' + 'uncontrolled value for the lifetime of the component. ' + 'More info: https://reactjs.org/link/controlled-components', name) : void 0;
50
+ process.env.NODE_ENV !== "production" ? warning(false, `A component is changing a controlled ${name} component to be uncontrolled. ` + 'This is likely caused by the value changing to an undefined value ' + 'from a defined one. Decide between using a controlled or ' + 'uncontrolled value for the lifetime of the component. ' + 'More info: https://reactjs.org/link/controlled-components') : void 0;
66
51
  }
67
52
  }, [name, value]);
68
53
  if (controlled.current === true) {
69
54
  return [value, setState];
70
55
  }
71
56
  return [state, setState];
72
- }
57
+ };
73
58
 
74
59
  export { useControllableState };
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { useRef, useEffect } from 'react';
9
9
 
10
- /* eslint-disable jsdoc/check-tag-names */
10
+ // @ts-check
11
11
 
12
12
  /**
13
13
  * @template {keyof GlobalEventHandlersEventMap} E
@@ -1,13 +1,16 @@
1
1
  /**
2
- * Copyright IBM Corp. 2016, 2023
2
+ * Copyright IBM Corp. 2016, 2025
3
3
  *
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import { Ref, ForwardedRef } from 'react';
7
+ import { type ForwardedRef, type Ref } from 'react';
8
8
  /**
9
- * Combine multiple refs into a single ref. This use useful when you have two
10
- * refs from both `React.forwardRef` and `useRef` that you would like to add to
11
- * the same node.
9
+ * Merges multiple refs into a single callback ref.
10
+ *
11
+ * This hook is useful when you need to attach multiple refs (for example, a ref
12
+ * passed from `forwardRef` and a local ref from `useRef`) to the same node. It
13
+ * accepts an array of refs and returns a callback ref that, when attached to a
14
+ * node, assigns that node to every ref in the array.
12
15
  */
13
- export declare const useMergedRefs: <T extends unknown>(refs: ForwardedRef<T>[]) => Ref<T>;
16
+ export declare const useMergedRefs: <T>(refs: ForwardedRef<T>[]) => Ref<T>;
@@ -7,25 +7,24 @@
7
7
 
8
8
  import { useCallback } from 'react';
9
9
 
10
- // TODO: Investigate updating this hook based on the following code from
11
- // https://github.com/carbon-design-system/carbon/pull/18611:
12
- // https://github.com/adamalston/carbon/blob/dd403b6b10de3d8a6ccd8d2e21174c908c1e890a/packages/react/src/components/ListBox/ListBoxMenuItem.tsx#L23-L46
13
10
  /**
14
- * Combine multiple refs into a single ref. This use useful when you have two
15
- * refs from both `React.forwardRef` and `useRef` that you would like to add to
16
- * the same node.
11
+ * Merges multiple refs into a single callback ref.
12
+ *
13
+ * This hook is useful when you need to attach multiple refs (for example, a ref
14
+ * passed from `forwardRef` and a local ref from `useRef`) to the same node. It
15
+ * accepts an array of refs and returns a callback ref that, when attached to a
16
+ * node, assigns that node to every ref in the array.
17
17
  */
18
18
  const useMergedRefs = refs => {
19
19
  return useCallback(node => {
20
20
  refs.forEach(ref => {
21
21
  if (typeof ref === 'function') {
22
22
  ref(node);
23
- } else if (ref !== null && ref !== undefined) {
23
+ } else if (ref) {
24
24
  ref.current = node;
25
25
  }
26
26
  });
27
- // eslint-disable-next-line react-hooks/exhaustive-deps
28
- }, refs);
27
+ }, [refs]);
29
28
  };
30
29
 
31
30
  export { useMergedRefs };
@@ -9,7 +9,7 @@ import { useEffect } from 'react';
9
9
 
10
10
  function useNoInteractiveChildren(ref) {
11
11
  let message = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'component should have no interactive child nodes';
12
- if (process.env.NODE_ENV !== "production") {
12
+ if (process.env.NODE_ENV !== 'production') {
13
13
  // eslint-disable-next-line react-hooks/rules-of-hooks
14
14
  useEffect(() => {
15
15
  const node = ref.current ? getInteractiveContent(ref.current) : false;
@@ -21,7 +21,7 @@ function useNoInteractiveChildren(ref) {
21
21
  }
22
22
  function useInteractiveChildrenNeedDescription(ref) {
23
23
  let message = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : `interactive child node(s) should have an \`aria-describedby\` property`;
24
- if (process.env.NODE_ENV !== "production") {
24
+ if (process.env.NODE_ENV !== 'production') {
25
25
  // eslint-disable-next-line react-hooks/rules-of-hooks
26
26
  useEffect(() => {
27
27
  const node = ref.current ? getInteractiveContent(ref.current) : false;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2025
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 { type RefObject } from 'react';
8
+ export declare const useOutsideClick: <T extends HTMLElement>(ref: RefObject<T>, callback: (event: MouseEvent) => void) => void;
@@ -6,26 +6,29 @@
6
6
  */
7
7
 
8
8
  import { useRef, useEffect } from 'react';
9
- import { useEvent } from './useEvent.js';
10
9
  import { canUseDOM } from './environment.js';
10
+ import { useWindowEvent } from './useEvent.js';
11
11
 
12
- function useOutsideClick(ref, callback) {
12
+ const useOutsideClick = (ref, callback) => {
13
13
  const savedCallback = useRef(callback);
14
14
  useEffect(() => {
15
15
  savedCallback.current = callback;
16
- });
16
+ }, [callback]);
17
17
 
18
18
  // We conditionally guard the `useEvent` hook for SSR. `canUseDOM` can be
19
19
  // treated as a constant as it will be false when executed in a Node.js
20
20
  // environment and true when executed in the browser
21
21
  if (canUseDOM) {
22
22
  // eslint-disable-next-line react-hooks/rules-of-hooks
23
- useEvent(window, 'click', event => {
24
- if (ref.current && !ref.current.contains(event.target)) {
23
+ useWindowEvent('click', event => {
24
+ const {
25
+ target
26
+ } = event;
27
+ if (target instanceof Node && ref.current && !ref.current.contains(target)) {
25
28
  savedCallback.current(event);
26
29
  }
27
30
  });
28
31
  }
29
- }
32
+ };
30
33
 
31
34
  export { useOutsideClick };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2025
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
+ * Returns a stable callback reference that always points to the latest version
9
+ * of a callback. This is useful when you want to avoid including the callback
10
+ * in dependency arrays while still ensuring the latest callback implementation
11
+ * is used.
12
+ *
13
+ * @param callback - The callback to track.
14
+ */
15
+ export declare const useSavedCallback: <T extends (...args: any[]) => any>(callback: T | undefined) => (...args: Parameters<T>) => ReturnType<T> | undefined;
@@ -8,24 +8,21 @@
8
8
  import { useRef, useEffect, useCallback } from 'react';
9
9
 
10
10
  /**
11
- * Provide a stable reference for a callback that is passed as a prop to a
12
- * component. This is helpful when you want access to the latest version of a
13
- * callback prop but don't want it to be added to the dependency array of an
14
- * effect.
11
+ * Returns a stable callback reference that always points to the latest version
12
+ * of a callback. This is useful when you want to avoid including the callback
13
+ * in dependency arrays while still ensuring the latest callback implementation
14
+ * is used.
15
15
  *
16
- * @param {Function | undefined} callback
17
- * @returns {Function}
16
+ * @param callback - The callback to track.
18
17
  */
19
- function useSavedCallback(callback) {
18
+ const useSavedCallback = callback => {
20
19
  const savedCallback = useRef(callback);
21
20
  useEffect(() => {
22
21
  savedCallback.current = callback;
23
- });
22
+ }, [callback]);
24
23
  return useCallback(function () {
25
- if (savedCallback.current) {
26
- return savedCallback.current(...arguments);
27
- }
24
+ return savedCallback.current ? savedCallback.current(...arguments) : undefined;
28
25
  }, []);
29
- }
26
+ };
30
27
 
31
28
  export { useSavedCallback };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Copyright IBM Corp. 2016, 2025
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
+ * Logs a warning.
9
+ *
10
+ * The warning is only logged if the condition is not met and
11
+ * `process.env.NODE_ENV !== 'production'` is truthy.
12
+ *
13
+ * @param condition - Condition to evaluate.
14
+ * @param message - Warning message.
15
+ * @throws Error if no `message` is provided.
16
+ */
17
+ export declare const warning: (condition: boolean, message: string) => void;
@@ -5,21 +5,25 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- const emptyFunction = function () {};
9
- const warning = process.env.NODE_ENV !== "production" ? function warning(condition, format) {
10
- for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
11
- args[_key - 2] = arguments[_key];
12
- }
13
- if (format === undefined) {
14
- throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'format argument');
8
+ import { noopFn } from './noopFn.js';
9
+
10
+ /**
11
+ * Logs a warning.
12
+ *
13
+ * The warning is only logged if the condition is not met and
14
+ * `process.env.NODE_ENV !== 'production'` is truthy.
15
+ *
16
+ * @param condition - Condition to evaluate.
17
+ * @param message - Warning message.
18
+ * @throws Error if no `message` is provided.
19
+ */
20
+ const warning = process.env.NODE_ENV !== 'production' ? (condition, message) => {
21
+ if (typeof message === 'undefined') {
22
+ throw new Error('`warning(condition, message)` requires a warning ' + 'format argument');
15
23
  }
16
24
  if (!condition) {
17
- let index = 0;
18
- const message = format.replace(/%s/g, () => {
19
- return args[index++];
20
- });
21
25
  console.warn('Warning: ' + message);
22
26
  }
23
- } : emptyFunction;
27
+ } : noopFn;
24
28
 
25
29
  export { warning };
@@ -75,7 +75,7 @@ function wrapFocusWithoutSentinels(_ref2) {
75
75
  currentActiveNode,
76
76
  event
77
77
  } = _ref2;
78
- if (['blur', 'focusout', 'focusin', 'focus'].includes(event.type) && process.env.NODE_ENV !== "production") {
78
+ if (['blur', 'focusout', 'focusin', 'focus'].includes(event.type) && process.env.NODE_ENV !== 'production') {
79
79
  // eslint-disable-next-line react-hooks/rules-of-hooks
80
80
  useEffect(() => {
81
81
  throw new Error(`Error: wrapFocusWithoutSentinels(...) called in unsupported ${event.type} event.\n\nCall wrapFocusWithoutSentinels(...) from onKeyDown instead.`);
@@ -14,7 +14,7 @@
14
14
  function isRequiredOneOf(propTypes) {
15
15
  const names = Object.keys(propTypes);
16
16
  const checker = propType => function (props, propName, componentName) {
17
- if (process.env.NODE_ENV !== "production" && names.every(name => typeof props[name] === 'undefined')) {
17
+ if (process.env.NODE_ENV !== 'production' && names.every(name => typeof props[name] === 'undefined')) {
18
18
  return new Error(`${componentName} requires one of the following props: ${names.join(', ')}`);
19
19
  }
20
20
  for (var _len = arguments.length, rest = new Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {
@@ -14,7 +14,7 @@
14
14
  */
15
15
  function requiredIfGivenPropIsTruthy(name, propType) {
16
16
  return function check(props, propName, componentName) {
17
- if (process.env.NODE_ENV !== "production" && props[name] == true && props[propName] == null) {
17
+ if (process.env.NODE_ENV !== 'production' && props[name] == true && props[propName] == null) {
18
18
  return new Error(`You must provide a value for \`${propName}\` in \`${componentName}\` if \`${name}\` exists.`);
19
19
  }
20
20
  for (var _len = arguments.length, rest = new Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {
@@ -5,12 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- /**
9
- * Copyright IBM Corp. 2016, 2023
10
- *
11
- * This source code is licensed under the Apache-2.0 license found in the
12
- * LICENSE file in the root directory of this source tree.
13
- */
8
+ // @ts-check
14
9
 
15
10
  /**
16
11
  * Generic utility to compose event handlers so that consumers can supply their
@@ -5,6 +5,12 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
+ /**
9
+ * Adds or removes a CSS class to an element.
10
+ * @param {Element} element An element.
11
+ * @param {string} name A CSS class name.
12
+ * @param {boolean} add `true` to add the given CSS class to given the element. Otherwise to remove.
13
+ */
8
14
  function toggleClass(element, name, add) {
9
15
  if (element.classList.contains(name) === !add) {
10
16
  element.classList[add ? 'add' : 'remove'](name);
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Copyright IBM Corp. 2023, 2024
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
+ */
1
7
  import * as React from 'react';
2
8
  export type ReactAttr<T = HTMLElement> = React.HTMLAttributes<T>;
3
9
  export type ForwardRefProps<T, P = unknown> = React.PropsWithoutRef<React.PropsWithChildren<P>> & React.RefAttributes<T>;
@@ -13,7 +13,7 @@ var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelper
13
13
  var PropTypes = require('prop-types');
14
14
  var React = require('react');
15
15
  var cx = require('classnames');
16
- var useResizeObserver = require('use-resize-observer/polyfilled');
16
+ var useResizeObserver = require('use-resize-observer');
17
17
  var iconsReact = require('@carbon/icons-react');
18
18
  var Copy = require('../Copy/Copy.js');
19
19
  var Button = require('../Button/Button.js');
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Copyright IBM Corp. 2023, 2025
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
+ */
1
7
  import React, { type MouseEvent, type KeyboardEvent, type HTMLAttributes, type ReactNode, type RefObject } from 'react';
2
8
  export interface ModalBodyProps extends HTMLAttributes<HTMLDivElement> {
3
9
  /** Specify the content to be placed in the ModalBody. */
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Copyright IBM Corp. 2023, 2025
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
+ */
1
7
  import React, { type ReactNode, type MouseEvent, type Ref } from 'react';
2
8
  import { InlineLoadingStatus } from '../InlineLoading/InlineLoading';
3
9
  export interface SecondaryButtonProps {