diff --git a/src/components/pop-out/PopOut.tsx b/src/components/pop-out/PopOut.tsx index 694e0f5..ae09a00 100644 --- a/src/components/pop-out/PopOut.tsx +++ b/src/components/pop-out/PopOut.tsx @@ -1,6 +1,6 @@ import React, { - MutableRefObject, ReactNode, + RefCallback, useCallback, useEffect, useLayoutEffect, @@ -18,7 +18,7 @@ export interface PopOutProps { offset?: number; alignOffset?: number; content: ReactNode; - children: (anchorRef: MutableRefObject) => ReactNode; + children: (anchorRef: RefCallback) => ReactNode; } export const PopOut = as<"div", PopOutProps>( ( @@ -36,12 +36,13 @@ export const PopOut = as<"div", PopOutProps>( }, ref ) => { - const anchorRef = useRef(null); + const anchorRef = useRef(null); const baseRef = useRef(null); const positionPopOut = useCallback(() => { - const anchor = anchorRef.current as HTMLElement; + const anchor = anchorRef.current; const baseEl = baseRef.current; + if (!anchor) return; if (!baseEl) return; const css = getRelativeFixedPosition( @@ -70,9 +71,13 @@ export const PopOut = as<"div", PopOutProps>( if (open) positionPopOut(); }, [open, positionPopOut]); + const handleAnchorRef: RefCallback = useCallback((element) => { + anchorRef.current = element; + }, []); + return ( <> - {children(anchorRef as MutableRefObject)} + {children(handleAnchorRef)} {open && ( { - const triggerRef = useRef(null); - const baseRef = useRef(null); + const triggerRef = useRef(null); + const baseRef = useRef(null); const [open, setOpen] = useState(false); const positionTooltip = useCallback(() => { - const anchor = triggerRef.current as HTMLElement; + const anchor = triggerRef.current; const baseEl = baseRef.current; + if (!anchor) return; if (!baseEl) return; const tooltipCss = getRelativeFixedPosition( @@ -56,7 +58,7 @@ const useTooltip = ( }, [position, align, offset, alignOffset]); useEffect(() => { - const trigger = triggerRef.current as HTMLElement; + const trigger = triggerRef.current; let timeoutId: number | undefined; const openTooltip = (evt: Event) => { @@ -101,9 +103,16 @@ const useTooltip = ( if (open) positionTooltip(); }, [open, positionTooltip]); + const handleTriggerRef: RefCallback = useCallback((element) => { + triggerRef.current = element; + }, []); + const handleBaseRef: RefCallback = useCallback((element) => { + baseRef.current = element; + }, []); + return { - triggerRef, - baseRef, + triggerRef: handleTriggerRef, + baseRef: handleBaseRef, open, }; }; @@ -115,7 +124,7 @@ interface TooltipProviderProps { alignOffset?: number; delay?: number; tooltip: ReactNode; - children: (triggerRef: MutableRefObject) => ReactNode; + children: (triggerRef: RefCallback) => ReactNode; } export const TooltipProvider = as<"div", TooltipProviderProps>( ( @@ -137,7 +146,7 @@ export const TooltipProvider = as<"div", TooltipProviderProps>( return ( <> - {children(triggerRef as MutableRefObject)} + {children(triggerRef)} {open && ( ( ...style, }} {...props} - ref={(el) => { - (baseRef as MutableRefObject).current = el; + ref={(instance) => { + baseRef(instance); if (ref) { - if (typeof ref === "function") ref(el); + if (typeof ref === "function") ref(instance); // eslint-disable-next-line no-param-reassign - else (ref as MutableRefObject).current = el; + else (ref as MutableRefObject).current = instance; } }} >