carbon-react 114.14.1 → 114.16.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 (26) hide show
  1. package/esm/components/heading/heading.component.d.ts +4 -1
  2. package/esm/components/heading/heading.component.js +3 -1
  3. package/esm/components/heading/index.d.ts +1 -1
  4. package/esm/components/select/filterable-select/filterable-select.component.js +12 -9
  5. package/esm/components/select/multi-select/multi-select.component.js +9 -3
  6. package/esm/components/settings-row/settings-row.component.js +5 -0
  7. package/esm/components/settings-row/settings-row.d.ts +3 -0
  8. package/esm/components/settings-row/settings-row.style.js +1 -10
  9. package/esm/hooks/__internal__/useStableCallback/index.d.ts +1 -0
  10. package/esm/hooks/__internal__/useStableCallback/index.js +1 -0
  11. package/esm/hooks/__internal__/useStableCallback/useStableCallback.d.ts +2 -0
  12. package/esm/hooks/__internal__/useStableCallback/useStableCallback.js +14 -0
  13. package/lib/components/heading/heading.component.d.ts +4 -1
  14. package/lib/components/heading/heading.component.js +3 -1
  15. package/lib/components/heading/index.d.ts +1 -1
  16. package/lib/components/select/filterable-select/filterable-select.component.js +13 -9
  17. package/lib/components/select/multi-select/multi-select.component.js +10 -3
  18. package/lib/components/settings-row/settings-row.component.js +5 -0
  19. package/lib/components/settings-row/settings-row.d.ts +3 -0
  20. package/lib/components/settings-row/settings-row.style.js +0 -9
  21. package/lib/hooks/__internal__/useStableCallback/index.d.ts +1 -0
  22. package/lib/hooks/__internal__/useStableCallback/index.js +15 -0
  23. package/lib/hooks/__internal__/useStableCallback/package.json +6 -0
  24. package/lib/hooks/__internal__/useStableCallback/useStableCallback.d.ts +2 -0
  25. package/lib/hooks/__internal__/useStableCallback/useStableCallback.js +25 -0
  26. package/package.json +2 -1
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  import { MarginProps } from "styled-system";
3
3
  import { TagProps } from "../../__internal__/utils/helpers/tags/tags";
4
+ export declare type HeadingType = "h1" | "h2" | "h3" | "h4" | "h5";
4
5
  export interface HeadingProps extends MarginProps, TagProps {
5
6
  /** Child elements */
6
7
  children?: React.ReactNode;
@@ -12,6 +13,8 @@ export interface HeadingProps extends MarginProps, TagProps {
12
13
  subheader?: React.ReactNode;
13
14
  /** Defines the subtitle id for the heading. */
14
15
  subtitleId?: string;
16
+ /** Defines the HTML heading element of the title. */
17
+ headingType?: HeadingType;
15
18
  /** Defines the help text for the heading. */
16
19
  help?: string;
17
20
  /** Defines the help link for the heading. */
@@ -27,5 +30,5 @@ export interface HeadingProps extends MarginProps, TagProps {
27
30
  /** Aria label for rendered help component */
28
31
  helpAriaLabel?: string;
29
32
  }
30
- export declare const Heading: ({ children, backLink, divider, help, helpAriaLabel, helpLink, pills, separator, subheader, subtitleId, title, titleId, ...rest }: HeadingProps) => JSX.Element | null;
33
+ export declare const Heading: ({ children, backLink, divider, help, helpAriaLabel, helpLink, pills, separator, subheader, subtitleId, headingType, title, titleId, ...rest }: HeadingProps) => JSX.Element | null;
31
34
  export default Heading;
@@ -18,6 +18,7 @@ const Heading = ({
18
18
  separator = false,
19
19
  subheader,
20
20
  subtitleId,
21
+ headingType = "h1",
21
22
  title,
22
23
  titleId,
23
24
  ...rest
@@ -76,7 +77,7 @@ const Heading = ({
76
77
  hasBackLink: !!backLink
77
78
  }, backLink && getBackButton(), /*#__PURE__*/React.createElement(StyledHeaderContent, null, /*#__PURE__*/React.createElement(StyledHeadingTitle, {
78
79
  withMargin: !!pills || !!help,
79
- variant: "h1",
80
+ variant: headingType,
80
81
  "data-element": "title",
81
82
  id: titleId
82
83
  }, title), (help || helpLink) && getHelp(), pills && getPills()), separator && /*#__PURE__*/React.createElement(StyledSeparator, null), subheader && getSubheader()), divider && /*#__PURE__*/React.createElement(StyledDivider, {
@@ -91,6 +92,7 @@ Heading.propTypes = {
91
92
  "data-element": PropTypes.string,
92
93
  "data-role": PropTypes.string,
93
94
  "divider": PropTypes.bool,
95
+ "headingType": PropTypes.oneOf(["h1", "h2", "h3", "h4", "h5"]),
94
96
  "help": PropTypes.string,
95
97
  "helpAriaLabel": PropTypes.string,
96
98
  "helpLink": PropTypes.string,
@@ -1,2 +1,2 @@
1
1
  export { default } from "./heading.component";
2
- export type { HeadingProps } from "./heading.component";
2
+ export type { HeadingProps, HeadingType } from "./heading.component";
@@ -12,6 +12,7 @@ import SelectList from "../select-list/select-list.component";
12
12
  import isExpectedOption from "../utils/is-expected-option";
13
13
  import isNavigationKey from "../utils/is-navigation-key";
14
14
  import Logger from "../../../__internal__/utils/logger";
15
+ import useStableCallback from "../../../hooks/__internal__/useStableCallback";
15
16
  let deprecateInputRefWarnTriggered = false;
16
17
  const FilterableSelectList = withFilter(SelectList);
17
18
  const FilterableSelect = /*#__PURE__*/React.forwardRef(({
@@ -21,9 +22,9 @@ const FilterableSelect = /*#__PURE__*/React.forwardRef(({
21
22
  name,
22
23
  label,
23
24
  children,
24
- onOpen,
25
+ onOpen: onOpenProp,
25
26
  onChange,
26
- onFilterChange,
27
+ onFilterChange: onFilterChangeProp,
27
28
  onClick,
28
29
  onKeyDown,
29
30
  onFocus,
@@ -206,13 +207,14 @@ const FilterableSelect = /*#__PURE__*/React.forwardRef(({
206
207
  // eslint-disable-next-line react-hooks/exhaustive-deps
207
208
 
208
209
  }, [value, onChange, children]);
210
+ const onOpen = useStableCallback(onOpenProp);
209
211
  useEffect(() => {
210
212
  if (!isOpen) {
211
213
  setFilterText("");
212
214
  } else if (onOpen) {
213
215
  onOpen();
214
216
  }
215
- }, [isOpen, onOpen]);
217
+ }, [onOpen, isOpen]);
216
218
  useEffect(() => {
217
219
  const hasListActionButton = listActionButton !== undefined;
218
220
  const onListActionMissingMessage = "onListAction prop required when using listActionButton prop";
@@ -225,11 +227,16 @@ const FilterableSelect = /*#__PURE__*/React.forwardRef(({
225
227
  // eslint-disable-next-line react-hooks/exhaustive-deps
226
228
 
227
229
  }, [value, children]);
230
+ const onFilterChange = useStableCallback(onFilterChangeProp);
231
+ const isFirstRender = useRef(true);
228
232
  useEffect(() => {
229
- if (onFilterChange) {
233
+ if (onFilterChange && !isFirstRender.current) {
230
234
  onFilterChange(filterText);
231
235
  }
232
- }, [filterText, onFilterChange]);
236
+ }, [onFilterChange, filterText]);
237
+ useEffect(() => {
238
+ isFirstRender.current = false;
239
+ }, []);
233
240
  useEffect(() => {
234
241
  const clickEvent = "click";
235
242
  window.addEventListener(clickEvent, handleGlobalClick);
@@ -308,10 +315,6 @@ const FilterableSelect = /*#__PURE__*/React.forwardRef(({
308
315
  return true;
309
316
  }
310
317
 
311
- if (onOpen) {
312
- onOpen();
313
- }
314
-
315
318
  if (onFocus && !isInputFocused.current) {
316
319
  triggerFocus();
317
320
  isInputFocused.current = true;
@@ -14,6 +14,7 @@ import isExpectedOption from "../utils/is-expected-option";
14
14
  import isExpectedValue from "../utils/is-expected-value";
15
15
  import isNavigationKey from "../utils/is-navigation-key";
16
16
  import Logger from "../../../__internal__/utils/logger";
17
+ import useStableCallback from "../../../hooks/__internal__/useStableCallback";
17
18
  let deprecateInputRefWarnTriggered = false;
18
19
  const FilterableSelectList = withFilter(SelectList);
19
20
  const MultiSelect = /*#__PURE__*/React.forwardRef(({
@@ -25,7 +26,7 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
25
26
  readOnly,
26
27
  children,
27
28
  onOpen,
28
- onFilterChange,
29
+ onFilterChange: onFilterChangeProp,
29
30
  onChange,
30
31
  onClick,
31
32
  onFocus,
@@ -245,11 +246,16 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
245
246
  window.removeEventListener(clickEvent, handleGlobalClick);
246
247
  };
247
248
  }, [handleGlobalClick]);
249
+ const onFilterChange = useStableCallback(onFilterChangeProp);
250
+ const isFirstRender = useRef(true);
248
251
  useEffect(() => {
249
- if (onFilterChange) {
252
+ if (onFilterChange && !isFirstRender.current) {
250
253
  onFilterChange(filterText);
251
254
  }
252
- }, [filterText, onFilterChange]);
255
+ }, [onFilterChange, filterText]);
256
+ useEffect(() => {
257
+ isFirstRender.current = false;
258
+ }, []);
253
259
 
254
260
  function handleTextboxClick(event) {
255
261
  isMouseDownReported.current = false;
@@ -11,6 +11,7 @@ const marginPropTypes = filterStyledSystemMarginProps(styledSystemPropTypes.spac
11
11
 
12
12
  const SettingsRow = ({
13
13
  title,
14
+ headingType = "h3",
14
15
  description,
15
16
  children,
16
17
  className,
@@ -20,6 +21,7 @@ const SettingsRow = ({
20
21
  const heading = () => {
21
22
  if (!title) return null;
22
23
  return /*#__PURE__*/React.createElement(Heading, {
24
+ headingType: headingType,
23
25
  title: title,
24
26
  subheader: description,
25
27
  separator: description !== undefined,
@@ -46,6 +48,9 @@ SettingsRow.propTypes = { ...marginPropTypes,
46
48
  /** A title for this group of settings. */
47
49
  title: PropTypes.string,
48
50
 
51
+ /** Defines the HTML heading element of the `title` within the component. */
52
+ headingType: PropTypes.oneOf(["h1", "h2", "h3", "h4", "h5"]),
53
+
49
54
  /** A string or JSX object that provides a short description about the group of settings. */
50
55
  description: PropTypes.node,
51
56
 
@@ -1,10 +1,13 @@
1
1
  import * as React from "react";
2
+ import { HeadingType } from "../heading";
2
3
 
3
4
  export interface SettingsRowProps {
4
5
  /** The CSS classes to apply to the component. */
5
6
  className?: string;
6
7
  /** A title for this group of settings. */
7
8
  title?: string;
9
+ /** Defines the HTML heading element of the `title` within the component. */
10
+ headingType?: HeadingType;
8
11
  /** A string or JSX object that provides a short description about the group of settings. */
9
12
  description?: React.ReactNode;
10
13
  /** Shows a divider below the component. */
@@ -1,7 +1,7 @@
1
1
  import styled, { css } from "styled-components";
2
2
  import { margin } from "styled-system";
3
3
  import baseTheme from "../../style/themes/base";
4
- import { StyledHeader, StyledHeadingTitle, StyledSeparator } from "../heading/heading.style";
4
+ import { StyledHeader, StyledSeparator } from "../heading/heading.style";
5
5
  export const StyledSettingsRow = styled.div`
6
6
  ${margin}
7
7
 
@@ -24,15 +24,6 @@ export const StyledSettingsRow = styled.div`
24
24
  margin-bottom: 0;
25
25
  }
26
26
 
27
- ${StyledHeadingTitle} {
28
- color: var(--colorsUtilityYin090);
29
- font-size: 15px;
30
- font-weight: bold;
31
- line-height: 18px;
32
- margin-bottom: 10px;
33
- text-transform: uppercase;
34
- }
35
-
36
27
  ${StyledSeparator} {
37
28
  margin-bottom: 17px;
38
29
  }
@@ -0,0 +1 @@
1
+ export { default } from "./useStableCallback";
@@ -0,0 +1 @@
1
+ export { default } from "./useStableCallback";
@@ -0,0 +1,2 @@
1
+ export declare function useStableCallback(callback?: (...args: unknown[]) => unknown): ((...args: any[]) => unknown) | undefined;
2
+ export default useStableCallback;
@@ -0,0 +1,14 @@
1
+ import { useRef, useCallback } from "react"; // This is a hook that returns a memoized callback that is guaranteed to be the same reference between renders.
2
+ // This is useful when a stable reference is required to prevent unnecessary re-renders.
3
+
4
+ export function useStableCallback(callback) {
5
+ const ref = useRef(callback);
6
+ ref.current = callback;
7
+ const stableCallback = useCallback((...args) => {
8
+ var _ref$current;
9
+
10
+ return (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.call(ref, ...args);
11
+ }, []);
12
+ return callback ? stableCallback : undefined;
13
+ }
14
+ export default useStableCallback;
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  import { MarginProps } from "styled-system";
3
3
  import { TagProps } from "../../__internal__/utils/helpers/tags/tags";
4
+ export declare type HeadingType = "h1" | "h2" | "h3" | "h4" | "h5";
4
5
  export interface HeadingProps extends MarginProps, TagProps {
5
6
  /** Child elements */
6
7
  children?: React.ReactNode;
@@ -12,6 +13,8 @@ export interface HeadingProps extends MarginProps, TagProps {
12
13
  subheader?: React.ReactNode;
13
14
  /** Defines the subtitle id for the heading. */
14
15
  subtitleId?: string;
16
+ /** Defines the HTML heading element of the title. */
17
+ headingType?: HeadingType;
15
18
  /** Defines the help text for the heading. */
16
19
  help?: string;
17
20
  /** Defines the help link for the heading. */
@@ -27,5 +30,5 @@ export interface HeadingProps extends MarginProps, TagProps {
27
30
  /** Aria label for rendered help component */
28
31
  helpAriaLabel?: string;
29
32
  }
30
- export declare const Heading: ({ children, backLink, divider, help, helpAriaLabel, helpLink, pills, separator, subheader, subtitleId, title, titleId, ...rest }: HeadingProps) => JSX.Element | null;
33
+ export declare const Heading: ({ children, backLink, divider, help, helpAriaLabel, helpLink, pills, separator, subheader, subtitleId, headingType, title, titleId, ...rest }: HeadingProps) => JSX.Element | null;
31
34
  export default Heading;
@@ -32,6 +32,7 @@ const Heading = ({
32
32
  separator = false,
33
33
  subheader,
34
34
  subtitleId,
35
+ headingType = "h1",
35
36
  title,
36
37
  titleId,
37
38
  ...rest
@@ -90,7 +91,7 @@ const Heading = ({
90
91
  hasBackLink: !!backLink
91
92
  }, backLink && getBackButton(), /*#__PURE__*/_react.default.createElement(_heading.StyledHeaderContent, null, /*#__PURE__*/_react.default.createElement(_heading.StyledHeadingTitle, {
92
93
  withMargin: !!pills || !!help,
93
- variant: "h1",
94
+ variant: headingType,
94
95
  "data-element": "title",
95
96
  id: titleId
96
97
  }, title), (help || helpLink) && getHelp(), pills && getPills()), separator && /*#__PURE__*/_react.default.createElement(_heading.StyledSeparator, null), subheader && getSubheader()), divider && /*#__PURE__*/_react.default.createElement(_heading.StyledDivider, {
@@ -106,6 +107,7 @@ Heading.propTypes = {
106
107
  "data-element": _propTypes.default.string,
107
108
  "data-role": _propTypes.default.string,
108
109
  "divider": _propTypes.default.bool,
110
+ "headingType": _propTypes.default.oneOf(["h1", "h2", "h3", "h4", "h5"]),
109
111
  "help": _propTypes.default.string,
110
112
  "helpAriaLabel": _propTypes.default.string,
111
113
  "helpLink": _propTypes.default.string,
@@ -1,2 +1,2 @@
1
1
  export { default } from "./heading.component";
2
- export type { HeadingProps } from "./heading.component";
2
+ export type { HeadingProps, HeadingType } from "./heading.component";
@@ -29,6 +29,8 @@ var _isNavigationKey = _interopRequireDefault(require("../utils/is-navigation-ke
29
29
 
30
30
  var _logger = _interopRequireDefault(require("../../../__internal__/utils/logger"));
31
31
 
32
+ var _useStableCallback = _interopRequireDefault(require("../../../hooks/__internal__/useStableCallback"));
33
+
32
34
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
33
35
 
34
36
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
@@ -47,9 +49,9 @@ const FilterableSelect = /*#__PURE__*/_react.default.forwardRef(({
47
49
  name,
48
50
  label,
49
51
  children,
50
- onOpen,
52
+ onOpen: onOpenProp,
51
53
  onChange,
52
- onFilterChange,
54
+ onFilterChange: onFilterChangeProp,
53
55
  onClick,
54
56
  onKeyDown,
55
57
  onFocus,
@@ -233,13 +235,14 @@ const FilterableSelect = /*#__PURE__*/_react.default.forwardRef(({
233
235
  // eslint-disable-next-line react-hooks/exhaustive-deps
234
236
 
235
237
  }, [value, onChange, children]);
238
+ const onOpen = (0, _useStableCallback.default)(onOpenProp);
236
239
  (0, _react.useEffect)(() => {
237
240
  if (!isOpen) {
238
241
  setFilterText("");
239
242
  } else if (onOpen) {
240
243
  onOpen();
241
244
  }
242
- }, [isOpen, onOpen]);
245
+ }, [onOpen, isOpen]);
243
246
  (0, _react.useEffect)(() => {
244
247
  const hasListActionButton = listActionButton !== undefined;
245
248
  const onListActionMissingMessage = "onListAction prop required when using listActionButton prop";
@@ -252,11 +255,16 @@ const FilterableSelect = /*#__PURE__*/_react.default.forwardRef(({
252
255
  // eslint-disable-next-line react-hooks/exhaustive-deps
253
256
 
254
257
  }, [value, children]);
258
+ const onFilterChange = (0, _useStableCallback.default)(onFilterChangeProp);
259
+ const isFirstRender = (0, _react.useRef)(true);
255
260
  (0, _react.useEffect)(() => {
256
- if (onFilterChange) {
261
+ if (onFilterChange && !isFirstRender.current) {
257
262
  onFilterChange(filterText);
258
263
  }
259
- }, [filterText, onFilterChange]);
264
+ }, [onFilterChange, filterText]);
265
+ (0, _react.useEffect)(() => {
266
+ isFirstRender.current = false;
267
+ }, []);
260
268
  (0, _react.useEffect)(() => {
261
269
  const clickEvent = "click";
262
270
  window.addEventListener(clickEvent, handleGlobalClick);
@@ -335,10 +343,6 @@ const FilterableSelect = /*#__PURE__*/_react.default.forwardRef(({
335
343
  return true;
336
344
  }
337
345
 
338
- if (onOpen) {
339
- onOpen();
340
- }
341
-
342
346
  if (onFocus && !isInputFocused.current) {
343
347
  triggerFocus();
344
348
  isInputFocused.current = true;
@@ -33,6 +33,8 @@ var _isNavigationKey = _interopRequireDefault(require("../utils/is-navigation-ke
33
33
 
34
34
  var _logger = _interopRequireDefault(require("../../../__internal__/utils/logger"));
35
35
 
36
+ var _useStableCallback = _interopRequireDefault(require("../../../hooks/__internal__/useStableCallback"));
37
+
36
38
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
37
39
 
38
40
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
@@ -53,7 +55,7 @@ const MultiSelect = /*#__PURE__*/_react.default.forwardRef(({
53
55
  readOnly,
54
56
  children,
55
57
  onOpen,
56
- onFilterChange,
58
+ onFilterChange: onFilterChangeProp,
57
59
  onChange,
58
60
  onClick,
59
61
  onFocus,
@@ -275,11 +277,16 @@ const MultiSelect = /*#__PURE__*/_react.default.forwardRef(({
275
277
  window.removeEventListener(clickEvent, handleGlobalClick);
276
278
  };
277
279
  }, [handleGlobalClick]);
280
+ const onFilterChange = (0, _useStableCallback.default)(onFilterChangeProp);
281
+ const isFirstRender = (0, _react.useRef)(true);
278
282
  (0, _react.useEffect)(() => {
279
- if (onFilterChange) {
283
+ if (onFilterChange && !isFirstRender.current) {
280
284
  onFilterChange(filterText);
281
285
  }
282
- }, [filterText, onFilterChange]);
286
+ }, [onFilterChange, filterText]);
287
+ (0, _react.useEffect)(() => {
288
+ isFirstRender.current = false;
289
+ }, []);
283
290
 
284
291
  function handleTextboxClick(event) {
285
292
  isMouseDownReported.current = false;
@@ -27,6 +27,7 @@ const marginPropTypes = (0, _utils.filterStyledSystemMarginProps)(_propTypes2.de
27
27
 
28
28
  const SettingsRow = ({
29
29
  title,
30
+ headingType = "h3",
30
31
  description,
31
32
  children,
32
33
  className,
@@ -36,6 +37,7 @@ const SettingsRow = ({
36
37
  const heading = () => {
37
38
  if (!title) return null;
38
39
  return /*#__PURE__*/_react.default.createElement(_heading.default, {
40
+ headingType: headingType,
39
41
  title: title,
40
42
  subheader: description,
41
43
  separator: description !== undefined,
@@ -62,6 +64,9 @@ SettingsRow.propTypes = { ...marginPropTypes,
62
64
  /** A title for this group of settings. */
63
65
  title: _propTypes.default.string,
64
66
 
67
+ /** Defines the HTML heading element of the `title` within the component. */
68
+ headingType: _propTypes.default.oneOf(["h1", "h2", "h3", "h4", "h5"]),
69
+
65
70
  /** A string or JSX object that provides a short description about the group of settings. */
66
71
  description: _propTypes.default.node,
67
72
 
@@ -1,10 +1,13 @@
1
1
  import * as React from "react";
2
+ import { HeadingType } from "../heading";
2
3
 
3
4
  export interface SettingsRowProps {
4
5
  /** The CSS classes to apply to the component. */
5
6
  className?: string;
6
7
  /** A title for this group of settings. */
7
8
  title?: string;
9
+ /** Defines the HTML heading element of the `title` within the component. */
10
+ headingType?: HeadingType;
8
11
  /** A string or JSX object that provides a short description about the group of settings. */
9
12
  description?: React.ReactNode;
10
13
  /** Shows a divider below the component. */
@@ -41,15 +41,6 @@ const StyledSettingsRow = _styledComponents.default.div`
41
41
  margin-bottom: 0;
42
42
  }
43
43
 
44
- ${_heading.StyledHeadingTitle} {
45
- color: var(--colorsUtilityYin090);
46
- font-size: 15px;
47
- font-weight: bold;
48
- line-height: 18px;
49
- margin-bottom: 10px;
50
- text-transform: uppercase;
51
- }
52
-
53
44
  ${_heading.StyledSeparator} {
54
45
  margin-bottom: 17px;
55
46
  }
@@ -0,0 +1 @@
1
+ export { default } from "./useStableCallback";
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "default", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _useStableCallback.default;
10
+ }
11
+ });
12
+
13
+ var _useStableCallback = _interopRequireDefault(require("./useStableCallback"));
14
+
15
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -0,0 +1,6 @@
1
+ {
2
+ "sideEffects": false,
3
+ "module": "../../../../esm/hooks/__internal__/useStableCallback/index.js",
4
+ "main": "./index.js",
5
+ "types": "./index.d.ts"
6
+ }
@@ -0,0 +1,2 @@
1
+ export declare function useStableCallback(callback?: (...args: unknown[]) => unknown): ((...args: any[]) => unknown) | undefined;
2
+ export default useStableCallback;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useStableCallback = useStableCallback;
7
+ exports.default = void 0;
8
+
9
+ var _react = require("react");
10
+
11
+ // This is a hook that returns a memoized callback that is guaranteed to be the same reference between renders.
12
+ // This is useful when a stable reference is required to prevent unnecessary re-renders.
13
+ function useStableCallback(callback) {
14
+ const ref = (0, _react.useRef)(callback);
15
+ ref.current = callback;
16
+ const stableCallback = (0, _react.useCallback)((...args) => {
17
+ var _ref$current;
18
+
19
+ return (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.call(ref, ...args);
20
+ }, []);
21
+ return callback ? stableCallback : undefined;
22
+ }
23
+
24
+ var _default = useStableCallback;
25
+ exports.default = _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "carbon-react",
3
- "version": "114.14.1",
3
+ "version": "114.16.0",
4
4
  "description": "A library of reusable React components for easily building user interfaces.",
5
5
  "files": [
6
6
  "lib",
@@ -80,6 +80,7 @@
80
80
  "@storybook/theming": "^6.4.18",
81
81
  "@testing-library/jest-dom": "^5.16.2",
82
82
  "@testing-library/react": "^12.1.3",
83
+ "@testing-library/react-hooks": "^8.0.1",
83
84
  "@testing-library/user-event": "^14.4.3",
84
85
  "@types/crypto-js": "^4.1.1",
85
86
  "@types/draft-js": "^0.11.7",