Skip to content

Commit

Permalink
[@mantine/hooks] Support react 19 ref cleanup function
Browse files Browse the repository at this point in the history
  • Loading branch information
elecdeer committed Dec 24, 2024
1 parent 44af986 commit 8ed7594
Showing 1 changed file with 27 additions and 5 deletions.
32 changes: 27 additions & 5 deletions packages/@mantine/hooks/src/use-merged-ref/use-merged-ref.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,40 @@
import { Ref, useCallback } from 'react';
import { Ref, useCallback, type RefCallback, type RefObject } from 'react';

Check failure on line 1 in packages/@mantine/hooks/src/use-merged-ref/use-merged-ref.ts

View workflow job for this annotation

GitHub Actions / test_pull_request

'RefObject' is defined but never used

type PossibleRef<T> = Ref<T> | undefined;

export function assignRef<T>(ref: PossibleRef<T>, value: T) {
type RefCleanup<T> = ReturnType<RefCallback<T>>;

export function assignRef<T>(ref: PossibleRef<T>, value: T): RefCleanup<T> {
if (typeof ref === 'function') {
ref(value);
return ref(value);
} else if (typeof ref === 'object' && ref !== null && 'current' in ref) {
(ref as React.MutableRefObject<T>).current = value;
ref.current = value;
}
}

export function mergeRefs<T>(...refs: PossibleRef<T>[]) {
const cleanupMap = new Map<PossibleRef<T>, Exclude<RefCleanup<T>, void>>();

return (node: T | null) => {
refs.forEach((ref) => assignRef(ref, node));
refs.forEach((ref) => {
const cleanup = assignRef(ref, node);
if (cleanup) {
cleanupMap.set(ref, cleanup);
}
});

if (cleanupMap.size > 0) {
return () => {
refs.forEach((ref) => {
const cleanup = cleanupMap.get(ref);
if (cleanup) {
cleanup();
} else {
assignRef(ref, null);
}
});
};
}
};
}

Expand Down

0 comments on commit 8ed7594

Please sign in to comment.