Skip to content

Commit

Permalink
fix: types and api of tooltip provide and popout component
Browse files Browse the repository at this point in the history
  • Loading branch information
ajbura committed Apr 12, 2024
1 parent d260865 commit 70f0316
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 17 deletions.
15 changes: 10 additions & 5 deletions src/components/pop-out/PopOut.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, {
MutableRefObject,
ReactNode,
RefCallback,
useCallback,
useEffect,
useLayoutEffect,
Expand All @@ -18,7 +18,7 @@ export interface PopOutProps {
offset?: number;
alignOffset?: number;
content: ReactNode;
children: (anchorRef: MutableRefObject<null>) => ReactNode;
children: (anchorRef: RefCallback<HTMLElement | SVGElement>) => ReactNode;
}
export const PopOut = as<"div", PopOutProps>(
(
Expand All @@ -36,12 +36,13 @@ export const PopOut = as<"div", PopOutProps>(
},
ref
) => {
const anchorRef = useRef<unknown>(null);
const anchorRef = useRef<HTMLElement | SVGElement | null>(null);
const baseRef = useRef<HTMLDivElement>(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(
Expand Down Expand Up @@ -70,9 +71,13 @@ export const PopOut = as<"div", PopOutProps>(
if (open) positionPopOut();
}, [open, positionPopOut]);

const handleAnchorRef: RefCallback<HTMLElement | SVGElement> = useCallback((element) => {
anchorRef.current = element;
}, []);

return (
<>
{children(anchorRef as MutableRefObject<null>)}
{children(handleAnchorRef)}
<Portal>
{open && (
<AsPopOut
Expand Down
33 changes: 21 additions & 12 deletions src/components/tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import classNames from "classnames";
import React, {
MutableRefObject,
ReactNode,
RefCallback,
useCallback,
useEffect,
useLayoutEffect,
Expand Down Expand Up @@ -31,13 +32,14 @@ const useTooltip = (
alignOffset: number,
delay: number
) => {
const triggerRef = useRef<unknown>(null);
const baseRef = useRef<HTMLDivElement>(null);
const triggerRef = useRef<HTMLElement | SVGElement | null>(null);
const baseRef = useRef<HTMLElement | SVGElement | null>(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(
Expand All @@ -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) => {
Expand Down Expand Up @@ -101,9 +103,16 @@ const useTooltip = (
if (open) positionTooltip();
}, [open, positionTooltip]);

const handleTriggerRef: RefCallback<HTMLElement | SVGElement> = useCallback((element) => {
triggerRef.current = element;
}, []);
const handleBaseRef: RefCallback<HTMLElement | SVGElement> = useCallback((element) => {
baseRef.current = element;
}, []);

return {
triggerRef,
baseRef,
triggerRef: handleTriggerRef,
baseRef: handleBaseRef,
open,
};
};
Expand All @@ -115,7 +124,7 @@ interface TooltipProviderProps {
alignOffset?: number;
delay?: number;
tooltip: ReactNode;
children: (triggerRef: MutableRefObject<null>) => ReactNode;
children: (triggerRef: RefCallback<HTMLElement | SVGElement>) => ReactNode;
}
export const TooltipProvider = as<"div", TooltipProviderProps>(
(
Expand All @@ -137,7 +146,7 @@ export const TooltipProvider = as<"div", TooltipProviderProps>(

return (
<>
{children(triggerRef as MutableRefObject<null>)}
{children(triggerRef)}
{open && (
<Portal>
<AsTooltipProvider
Expand All @@ -152,12 +161,12 @@ export const TooltipProvider = as<"div", TooltipProviderProps>(
...style,
}}
{...props}
ref={(el) => {
(baseRef as MutableRefObject<HTMLDivElement | null>).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<HTMLDivElement | null>).current = el;
else (ref as MutableRefObject<typeof instance>).current = instance;
}
}}
>
Expand Down

0 comments on commit 70f0316

Please sign in to comment.