@playbooks/ui
Version:
An interface library for Playbooks.
106 lines (105 loc) • 3.97 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import { useState, useRef, useEffect } from "react";
import { createPortal } from "react-dom";
import { a as arrow, f as flip, s as shift, c as computePosition, l as limitShift } from "./floating-ui.dom-CdHlWYu6.js";
import { F as Fade } from "./fade.es-DSuuKNg3.js";
import { a as useElementMouseEnter, b as useElementMouseLeave } from "./index.es-ThnjXBwV.js";
import { useUI } from "./context.es.js";
import { Div, Span } from "./html.es.js";
import { u as useMounted } from "./utils.es-CyRf46Mc.js";
const Tooltip = ({
id,
ref,
name = "Tooltip",
open,
placement = "right",
html,
onClick = () => null,
onHover,
className,
children,
tailwind,
...props
}) => {
const [show, setShow] = useState(false);
const context = useUI();
const base = context?.theme?.tooltip({ open: show, placement });
const computed = { ...base, ...props, tailwind, className, name };
const baseRef = useRef(null);
const popRef = useRef(null);
const arrowRef = useRef(null);
useEffect(() => {
const computedRef = ref || baseRef;
if (computedRef?.current && arrowRef?.current && popRef?.current) {
const middleware = [arrow({ element: arrowRef?.current }), flip(), shift({ limiter: limitShift() })];
const formattedOptions = { placement, middleware, strategy: "fixed" };
computePosition(computedRef?.current, popRef?.current, formattedOptions).then(({ x, y, middlewareData }) => {
Object.assign(popRef?.current.style, { left: `${x}px`, top: `${y}px` });
Object.assign(arrowRef?.current.style, {
left: `${middlewareData.arrow?.x}px`,
top: `${middlewareData.arrow?.y}px`
});
});
}
}, [ref?.current, baseRef?.current, arrowRef?.current, popRef?.current, open]);
useElementMouseEnter(ref?.current, onMouseEnter, [ref?.current]);
useElementMouseLeave(ref?.current, onMouseLeave, [ref?.current]);
const mounted = useMounted(null, []);
function onMouseEnter() {
onHover(true);
}
function onMouseLeave() {
onHover(false);
}
const onEnter = () => setShow(true);
const onExit = () => setShow(false);
if (!mounted) return null;
if (ref?.current) {
return createPortal(
/* @__PURE__ */ jsx(Fade, { ref: popRef, show: open, timeout: 200, onEnter, onExit, children: /* @__PURE__ */ jsxs(Div, { ref: popRef, position: "absolute", zIndex: "z-10", ...computed, children: [
/* @__PURE__ */ jsx(TooltipArrow, { ref: arrowRef, tailwind: tailwind?.arrow }),
/* @__PURE__ */ jsx(TooltipInner, { tailwind: tailwind?.inner, children: html })
] }) }),
document.body
);
}
return /* @__PURE__ */ jsxs(Span, { id, ref: baseRef, name, onClick, onMouseEnter, onMouseLeave, children: [
children,
createPortal(
/* @__PURE__ */ jsx(Fade, { ref: popRef, show: open, timeout: 200, onEnter, onExit, children: /* @__PURE__ */ jsxs(Div, { ref: popRef, position: "absolute", zIndex: "z-10", ...computed, children: [
/* @__PURE__ */ jsx(TooltipArrow, { ref: arrowRef, tailwind: tailwind?.arrow }),
/* @__PURE__ */ jsx(TooltipInner, { tailwind: tailwind?.inner, children: html })
] }) }),
document.body
)
] });
};
const TooltipInner = ({
name = "TooltipInner",
className,
children,
tailwind,
...props
}) => {
const context = useUI();
const base = context?.theme?.tooltipInner();
const computed = { ...base, ...props, tailwind, className, name };
return /* @__PURE__ */ jsx(Div, { ...computed, children });
};
const TooltipArrow = ({
name = "TooltipArrow",
ref,
tailwind,
className,
...props
}) => {
const context = useUI();
const base = context?.theme?.tooltipArrow();
const computed = { ...base, ...props, tailwind, className, name };
return /* @__PURE__ */ jsx(Div, { ref, position: "absolute", children: /* @__PURE__ */ jsx(Div, { ...computed }) });
};
export {
Tooltip,
TooltipArrow,
TooltipInner
};