Skip to content

Commit 149f0f2

Browse files
authored
refactor: rewrite mergeRefs in typescript (#20404)
1 parent 27569e3 commit 149f0f2

File tree

18 files changed

+128
-55
lines changed

18 files changed

+128
-55
lines changed

packages/react/src/components/ComboBox/ComboBox.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import ListBox, { ListBoxSizePropType, type ListBoxSize } from '../ListBox';
4040
import { ListBoxTrigger, ListBoxSelection } from '../ListBox/next';
4141
import { match, keys } from '../../internal/keyboard';
4242
import { useId } from '../../internal/useId';
43-
import mergeRefs from '../../tools/mergeRefs';
43+
import { mergeRefs } from '../../tools/mergeRefs';
4444
import { deprecate } from '../../prop-types/deprecate';
4545
import { usePrefix } from '../../internal/usePrefix';
4646
import { FormContext } from '../FluidForm';

packages/react/src/components/ComboButton/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
autoUpdate,
2424
} from '@floating-ui/react';
2525
import { useFeatureFlag } from '../FeatureFlags';
26-
import mergeRefs from '../../tools/mergeRefs';
26+
import { mergeRefs } from '../../tools/mergeRefs';
2727
import { MenuAlignment } from '../MenuButton';
2828
import { TranslateWithId } from '../../types/common';
2929
import { deprecateValuesWithin } from '../../prop-types/deprecateValuesWithin';

packages/react/src/components/ComposedModal/ComposedModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { ModalHeader, type ModalHeaderProps } from './ModalHeader';
2626
import { ModalFooter, type ModalFooterProps } from './ModalFooter';
2727
import { debounce } from 'es-toolkit/compat';
2828
import useIsomorphicEffect from '../../internal/useIsomorphicEffect';
29-
import mergeRefs from '../../tools/mergeRefs';
29+
import { mergeRefs } from '../../tools/mergeRefs';
3030
import cx from 'classnames';
3131
import { toggleClass } from '../../tools/toggleClass';
3232
import { requiredIfGivenPropIsTruthy } from '../../prop-types/requiredIfGivenPropIsTruthy';

packages/react/src/components/Dropdown/Dropdown.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import React, {
1212
useContext,
1313
useEffect,
1414
useMemo,
15+
useRef,
1516
useState,
1617
type FocusEvent,
1718
type ForwardedRef,
@@ -42,7 +43,7 @@ import ListBox, {
4243
type ListBoxSize,
4344
type ListBoxType,
4445
} from '../ListBox';
45-
import mergeRefs from '../../tools/mergeRefs';
46+
import { mergeRefs } from '../../tools/mergeRefs';
4647
import { deprecate } from '../../prop-types/deprecate';
4748
import { usePrefix } from '../../internal/usePrefix';
4849
import { FormContext } from '../FluidForm';
@@ -510,7 +511,12 @@ const Dropdown = React.forwardRef(
510511
setIsFocused(evt.type === 'focus' && !selectedItem ? true : false);
511512
};
512513

513-
const mergedRef = mergeRefs(toggleButtonProps.ref, ref);
514+
const buttonRef = useRef<HTMLButtonElement>(null);
515+
const mergedRef = mergeRefs<HTMLButtonElement>(
516+
toggleButtonProps.ref,
517+
ref,
518+
buttonRef
519+
);
514520

515521
const [currTimer, setCurrTimer] = useState<NodeJS.Timeout>();
516522

@@ -563,7 +569,7 @@ const Dropdown = React.forwardRef(
563569
// NOTE: does not prevent click
564570
evt.preventDefault();
565571
// focus on the element as per readonly input behavior
566-
mergedRef?.current?.focus();
572+
buttonRef.current?.focus();
567573
},
568574
onKeyDown: (evt: React.KeyboardEvent<HTMLButtonElement>) => {
569575
const selectAccessKeys = ['ArrowDown', 'ArrowUp', ' ', 'Enter'];
@@ -578,7 +584,6 @@ const Dropdown = React.forwardRef(
578584
onKeyDown: onKeyDownHandler,
579585
};
580586
}
581-
// eslint-disable-next-line react-hooks/exhaustive-deps -- https://github.com/carbon-design-system/carbon/issues/20071
582587
}, [readOnly, onKeyDownHandler]);
583588

584589
const menuProps = useMemo(

packages/react/src/components/ExpandableSearch/ExpandableSearch.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright IBM Corp. 2021
2+
* Copyright IBM Corp. 2021, 2025
33
*
44
* This source code is licensed under the Apache-2.0 license found in the
55
* LICENSE file in the root directory of this source tree.
@@ -11,7 +11,7 @@ import Search, { type SearchProps } from '../Search';
1111
import { usePrefix } from '../../internal/usePrefix';
1212
import { composeEventHandlers } from '../../tools/events';
1313
import { match, keys } from '../../internal/keyboard';
14-
import mergeRefs from '../../tools/mergeRefs';
14+
import { mergeRefs } from '../../tools/mergeRefs';
1515

1616
const ExpandableSearch = React.forwardRef(function ExpandableSearch(
1717
{

packages/react/src/components/MenuButton/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright IBM Corp. 2023
2+
* Copyright IBM Corp. 2023, 2025
33
*
44
* This source code is licensed under the Apache-2.0 license found in the
55
* LICENSE file in the root directory of this source tree.
@@ -29,7 +29,7 @@ import {
2929
autoUpdate,
3030
} from '@floating-ui/react';
3131
import { useFeatureFlag } from '../FeatureFlags';
32-
import mergeRefs from '../../tools/mergeRefs';
32+
import { mergeRefs } from '../../tools/mergeRefs';
3333

3434
const validButtonKinds = ['primary', 'tertiary', 'ghost'];
3535
const defaultButtonKind = 'primary';

packages/react/src/components/MultiSelect/FilterableMultiSelect.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ import ListBox, {
5050
import Checkbox from '../Checkbox';
5151
import { ListBoxTrigger, ListBoxSelection } from '../ListBox/next';
5252
import { match, keys } from '../../internal/keyboard';
53-
import mergeRefs from '../../tools/mergeRefs';
53+
import { mergeRefs } from '../../tools/mergeRefs';
5454
import { deprecate } from '../../prop-types/deprecate';
5555
import { useId } from '../../internal/useId';
5656
import { defaultSortItems, defaultCompareItems } from './tools/sorting';
@@ -977,8 +977,8 @@ export const FilterableMultiSelect = forwardRef(function FilterableMultiSelect<
977977
// NOTE: does not prevent click
978978
evt.preventDefault();
979979
// focus on the element as per readonly input behavior
980-
if (mergedRef.current !== undefined) {
981-
mergedRef.current.focus();
980+
if (textInput.current) {
981+
textInput.current.focus();
982982
}
983983
},
984984
onKeyDown: (evt: React.KeyboardEvent<HTMLInputElement>) => {

packages/react/src/components/MultiSelect/MultiSelect.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import React, {
2222
useContext,
2323
useLayoutEffect,
2424
useMemo,
25+
useRef,
2526
useState,
2627
type ForwardedRef,
2728
type ReactNode,
@@ -40,7 +41,7 @@ import {
4041
import { defaultSortItems, defaultCompareItems } from './tools/sorting';
4142
import { useSelection } from '../../internal/Selection';
4243
import { useId } from '../../internal/useId';
43-
import mergeRefs from '../../tools/mergeRefs';
44+
import { mergeRefs } from '../../tools/mergeRefs';
4445
import { deprecate } from '../../prop-types/deprecate';
4546
import { keys, match } from '../../internal/keyboard';
4647
import { usePrefix } from '../../internal/usePrefix';
@@ -504,7 +505,12 @@ export const MultiSelect = React.forwardRef(
504505
},
505506
});
506507

507-
const mergedRef = mergeRefs(toggleButtonProps.ref, ref);
508+
const toggleButtonRef = useRef<HTMLButtonElement>(null);
509+
const mergedRef = mergeRefs<HTMLButtonElement>(
510+
toggleButtonProps.ref,
511+
ref,
512+
toggleButtonRef
513+
);
508514

509515
const selectedItems = selectedItem as ItemType[];
510516

@@ -670,8 +676,8 @@ export const MultiSelect = React.forwardRef(
670676
// NOTE: does not prevent click
671677
evt.preventDefault();
672678
// focus on the element as per readonly input behavior
673-
if (mergedRef.current !== undefined) {
674-
mergedRef.current.focus();
679+
if (toggleButtonRef.current) {
680+
toggleButtonRef.current.focus();
675681
}
676682
},
677683
onKeyDown: (evt: React.KeyboardEvent<HTMLButtonElement>) => {

packages/react/src/components/OverflowMenu/OverflowMenu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import { matches as keyCodeMatches, keys } from '../../internal/keyboard';
3838
import { noopFn } from '../../internal/noopFn';
3939
import { PrefixContext } from '../../internal/usePrefix';
4040
import { deprecate } from '../../prop-types/deprecate';
41-
import mergeRefs from '../../tools/mergeRefs';
41+
import { mergeRefs } from '../../tools/mergeRefs';
4242
import { setupGetInstanceId } from '../../tools/setupGetInstanceId';
4343
import { IconButton, IconButtonProps } from '../IconButton';
4444
import { OverflowMenuItemProps } from '../OverflowMenuItem/OverflowMenuItem';

packages/react/src/components/OverflowMenu/next/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { useFeatureFlag } from '../../FeatureFlags';
1515
import { IconButton } from '../../IconButton';
1616
import { Menu } from '../../Menu';
1717
import type { PopoverAlignment } from '../../Popover';
18-
import mergeRefs from '../../../tools/mergeRefs';
18+
import { mergeRefs } from '../../../tools/mergeRefs';
1919

2020
import { useId } from '../../../internal/useId';
2121
import { usePrefix } from '../../../internal/usePrefix';

0 commit comments

Comments
 (0)