@veracity/vui
Version:
Veracity UI is a React component library crafted for use within Veracity applications and pages. Based on Styled Components and @xstyled.
119 lines (117 loc) • 4.27 kB
JavaScript
import { isString } from "../utils/assertion.js";
import zIndices_default from "../theme/foundations/zIndices.js";
import { useTh } from "../core/theme.js";
import { useUp } from "../core/media.js";
import { v } from "../core/styled.js";
import { Link } from "../link/link.js";
import { useModalContext } from "../modal/context.js";
import { bg } from "./consts.js";
import { TooltipContent } from "./tooltipContent.js";
import { cloneElement, isValidElement, useMemo, useRef, useState } from "react";
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
import { FloatingArrow, FloatingPortal, arrow, autoUpdate, flip, offset, safePolygon, shift, useFloating, useHover, useInteractions, useRole, useTransitionStyles } from "@floating-ui/react";
//#region src/tooltip/tooltip.tsx
const stripHtmlTags = (html) => {
const withoutTags = html.replace(/<[^>]*>/g, "");
const textarea = document.createElement("textarea");
textarea.innerHTML = withoutTags;
return textarea.value;
};
/**
* A simple text popup hint.
*
* Displayed on mouse enter, and is hidden on mouse leave.
*
* */
const Tooltip = (props) => {
const { children, fontSize = "16px", linkText, linkProps, minWidth, maxWidth = "400px", text = "", placement = "top", disabled = false, visible = false, offset: offsetProp = [0, 0], whiteSpace = "pre-wrap", wordBreak = "break-word", portalRoot = void 0 } = props;
const isDesktop = useUp("md");
const [isOpen, setIsOpen] = useState(visible);
const arrowRef = useRef(null);
const middleware = useMemo(() => [
offset({
mainAxis: offsetProp[1] + 6,
crossAxis: offsetProp[0]
}),
flip(),
shift(),
arrow({ element: arrowRef })
], [offsetProp[0], offsetProp[1]]);
const { refs, floatingStyles, context } = useFloating({
open: visible || isOpen,
onOpenChange: setIsOpen,
placement,
middleware,
whileElementsMounted: autoUpdate
});
const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {
duration: 150,
initial: { opacity: 0 },
open: { opacity: 1 },
close: { opacity: 0 }
});
const hover = useHover(context, {
move: false,
handleClose: safePolygon()
});
const role = useRole(context, { role: "tooltip" });
const { getReferenceProps, getFloatingProps } = useInteractions([hover, role]);
const darkBlue18 = useTh(`colors.${bg.regular}`);
const sandstone55 = useTh(`colors.${bg.disabled}`);
const arrowColor = disabled ? sandstone55 : darkBlue18;
const strippedText = useMemo(() => isString(text) ? stripHtmlTags(text) : "", [text]);
const zIndex = useModalContext()?.zIndex ? zIndices_default.popover + 10 : zIndices_default.tooltip;
const content = isString(text) ? /* @__PURE__ */ jsx(TooltipContent, {
disabled,
fontSize,
maxWidth,
minWidth,
whiteSpace,
wordBreak,
children: /* @__PURE__ */ jsxs(v.div, { children: [strippedText, !!linkText && /* @__PURE__ */ jsxs(Fragment$1, { children: ["\xA0", /* @__PURE__ */ jsx(Link, {
variant: "white",
...linkProps,
children: linkText
})] })] })
}) : /* @__PURE__ */ jsx(TooltipContent, {
disabled,
fontSize,
maxWidth,
minWidth,
children: text
});
const childRef = isValidElement(children) ? children.ref ?? children.props?.ref : null;
const composedRef = childRef != null ? (el) => {
refs.setReference(el);
if (typeof childRef === "function") childRef(el);
else if (childRef && typeof childRef === "object") childRef.current = el;
} : refs.setReference;
const childElement = isValidElement(children) ? cloneElement(children, {
ref: composedRef,
...getReferenceProps()
}) : children;
return /* @__PURE__ */ jsxs(Fragment$1, { children: [childElement, isMounted && /* @__PURE__ */ jsx(FloatingPortal, {
root: portalRoot ?? void 0,
children: /* @__PURE__ */ jsxs("div", {
ref: refs.setFloating,
style: {
...floatingStyles,
...transitionStyles,
zIndex
},
...getFloatingProps(),
children: [content, isDesktop && /* @__PURE__ */ jsx(FloatingArrow, {
ref: arrowRef,
context,
fill: arrowColor,
width: 12,
height: 6
})]
})
}, portalRoot ? "custom" : "default")] });
};
Tooltip.displayName = "Tooltip";
//#endregion
export { Tooltip, Tooltip as default };
globalThis.__vuiVersion__ = "5.3.1"
//# sourceMappingURL=tooltip.js.map