tfrere's picture
tfrere HF Staff
refactor: remove MUI, unify publisher pipeline, add shared component registry
d15d7f7
import { useState, useRef, useCallback, useEffect, type ReactNode } from "react";
import { computePosition, offset, flip, shift, type Placement } from "@floating-ui/dom";
interface TooltipProps {
title: string;
placement?: Placement;
children: ReactNode;
}
export function Tooltip({ title, placement = "top", children }: TooltipProps) {
const triggerRef = useRef<HTMLSpanElement>(null);
const tooltipRef = useRef<HTMLDivElement>(null);
const [open, setOpen] = useState(false);
const reposition = useCallback(() => {
const trigger = triggerRef.current;
const tip = tooltipRef.current;
if (!trigger || !tip) return;
computePosition(trigger, tip, {
placement,
strategy: "fixed",
middleware: [offset(6), flip(), shift({ padding: 8 })],
}).then(({ x, y }) => {
tip.style.left = `${x}px`;
tip.style.top = `${y}px`;
});
}, [placement]);
useEffect(() => {
if (open) reposition();
}, [open, reposition]);
if (!title) return <>{children}</>;
return (
<>
<span
ref={triggerRef}
onMouseEnter={() => setOpen(true)}
onMouseLeave={() => setOpen(false)}
onFocus={() => setOpen(true)}
onBlur={() => setOpen(false)}
style={{ display: "inline-flex" }}
>
{children}
</span>
{open && (
<div ref={tooltipRef} className="ed-tooltip" role="tooltip">
{title}
</div>
)}
</>
);
}