@anoki/fse-ui
Version:
FSE UI components library
277 lines (276 loc) • 9.45 kB
JavaScript
import * as a from "react";
import { composeEventHandlers as y } from "./index.es470.js";
import { useComposedRefs as A } from "./index.es471.js";
import { createContextScope as G } from "./index.es472.js";
import { DismissableLayer as F } from "./index.es484.js";
import { createPopperScope as j, Anchor as B, Content as U, Arrow as V } from "./index.es487.js";
import { Presence as Y } from "./index.es489.js";
import { Primitive as q } from "./index.es474.js";
import { createSlottable as X } from "./index.es481.js";
import { Root as K } from "./index.es566.js";
import { j as d } from "./index.es244.js";
var [E, ge] = G("Tooltip", [
j
]), _ = j(), k = "TooltipProvider", W = 700, L = "tooltip.open", [z, D] = E(k), O = (t) => {
const {
__scopeTooltip: o,
delayDuration: e = W,
skipDelayDuration: r = 300,
disableHoverableContent: n = !1,
children: c
} = t, s = a.useRef(!0), f = a.useRef(!1), i = a.useRef(0);
return a.useEffect(() => {
const u = i.current;
return () => window.clearTimeout(u);
}, []), /* @__PURE__ */ d.jsx(
z,
{
scope: o,
isOpenDelayedRef: s,
delayDuration: e,
onOpen: a.useCallback(() => {
window.clearTimeout(i.current), s.current = !1;
}, []),
onClose: a.useCallback(() => {
window.clearTimeout(i.current), i.current = window.setTimeout(
() => s.current = !0,
r
);
}, [r]),
isPointerInTransitRef: f,
onPointerInTransitChange: a.useCallback((u) => {
f.current = u;
}, []),
disableHoverableContent: n,
children: c
}
);
};
O.displayName = k;
var M = "Tooltip", [Ee, P] = E(M), R = "TooltipTrigger", J = a.forwardRef(
(t, o) => {
const { __scopeTooltip: e, ...r } = t, n = P(R, e), c = D(R, e), s = _(e), f = a.useRef(null), i = A(o, f, n.onTriggerChange), u = a.useRef(!1), l = a.useRef(!1), p = a.useCallback(() => u.current = !1, []);
return a.useEffect(() => () => document.removeEventListener("pointerup", p), [p]), /* @__PURE__ */ d.jsx(B, { asChild: !0, ...s, children: /* @__PURE__ */ d.jsx(
q.button,
{
"aria-describedby": n.open ? n.contentId : void 0,
"data-state": n.stateAttribute,
...r,
ref: i,
onPointerMove: y(t.onPointerMove, (v) => {
v.pointerType !== "touch" && !l.current && !c.isPointerInTransitRef.current && (n.onTriggerEnter(), l.current = !0);
}),
onPointerLeave: y(t.onPointerLeave, () => {
n.onTriggerLeave(), l.current = !1;
}),
onPointerDown: y(t.onPointerDown, () => {
n.open && n.onClose(), u.current = !0, document.addEventListener("pointerup", p, { once: !0 });
}),
onFocus: y(t.onFocus, () => {
u.current || n.onOpen();
}),
onBlur: y(t.onBlur, n.onClose),
onClick: y(t.onClick, n.onClose)
}
) });
}
);
J.displayName = R;
var Q = "TooltipPortal", [Pe, Z] = E(Q, {
forceMount: void 0
}), C = "TooltipContent", $ = a.forwardRef(
(t, o) => {
const e = Z(C, t.__scopeTooltip), { forceMount: r = e.forceMount, side: n = "top", ...c } = t, s = P(C, t.__scopeTooltip);
return /* @__PURE__ */ d.jsx(Y, { present: r || s.open, children: s.disableHoverableContent ? /* @__PURE__ */ d.jsx(I, { side: n, ...c, ref: o }) : /* @__PURE__ */ d.jsx(ee, { side: n, ...c, ref: o }) });
}
), ee = a.forwardRef((t, o) => {
const e = P(C, t.__scopeTooltip), r = D(C, t.__scopeTooltip), n = a.useRef(null), c = A(o, n), [s, f] = a.useState(null), { trigger: i, onClose: u } = e, l = n.current, { onPointerInTransitChange: p } = r, v = a.useCallback(() => {
f(null), p(!1);
}, [p]), T = a.useCallback(
(x, h) => {
const m = x.currentTarget, g = { x: x.clientX, y: x.clientY }, b = se(g, m.getBoundingClientRect()), w = ie(g, b), S = ae(h.getBoundingClientRect()), H = le([...w, ...S]);
f(H), p(!0);
},
[p]
);
return a.useEffect(() => () => v(), [v]), a.useEffect(() => {
if (i && l) {
const x = (m) => T(m, l), h = (m) => T(m, i);
return i.addEventListener("pointerleave", x), l.addEventListener("pointerleave", h), () => {
i.removeEventListener("pointerleave", x), l.removeEventListener("pointerleave", h);
};
}
}, [i, l, T, v]), a.useEffect(() => {
if (s) {
const x = (h) => {
const m = h.target, g = { x: h.clientX, y: h.clientY }, b = (i == null ? void 0 : i.contains(m)) || (l == null ? void 0 : l.contains(m)), w = !ce(g, s);
b ? v() : w && (v(), u());
};
return document.addEventListener("pointermove", x), () => document.removeEventListener("pointermove", x);
}
}, [i, l, s, u, v]), /* @__PURE__ */ d.jsx(I, { ...t, ref: c });
}), [te, oe] = E(M, { isInside: !1 }), re = X("TooltipContent"), I = a.forwardRef(
(t, o) => {
const {
__scopeTooltip: e,
children: r,
"aria-label": n,
onEscapeKeyDown: c,
onPointerDownOutside: s,
...f
} = t, i = P(C, e), u = _(e), { onClose: l } = i;
return a.useEffect(() => (document.addEventListener(L, l), () => document.removeEventListener(L, l)), [l]), a.useEffect(() => {
if (i.trigger) {
const p = (v) => {
const T = v.target;
T != null && T.contains(i.trigger) && l();
};
return window.addEventListener("scroll", p, { capture: !0 }), () => window.removeEventListener("scroll", p, { capture: !0 });
}
}, [i.trigger, l]), /* @__PURE__ */ d.jsx(
F,
{
asChild: !0,
disableOutsidePointerEvents: !1,
onEscapeKeyDown: c,
onPointerDownOutside: s,
onFocusOutside: (p) => p.preventDefault(),
onDismiss: l,
children: /* @__PURE__ */ d.jsxs(
U,
{
"data-state": i.stateAttribute,
...u,
...f,
ref: o,
style: {
...f.style,
"--radix-tooltip-content-transform-origin": "var(--radix-popper-transform-origin)",
"--radix-tooltip-content-available-width": "var(--radix-popper-available-width)",
"--radix-tooltip-content-available-height": "var(--radix-popper-available-height)",
"--radix-tooltip-trigger-width": "var(--radix-popper-anchor-width)",
"--radix-tooltip-trigger-height": "var(--radix-popper-anchor-height)"
},
children: [
/* @__PURE__ */ d.jsx(re, { children: r }),
/* @__PURE__ */ d.jsx(te, { scope: e, isInside: !0, children: /* @__PURE__ */ d.jsx(K, { id: i.contentId, role: "tooltip", children: n || r }) })
]
}
)
}
);
}
);
$.displayName = C;
var N = "TooltipArrow", ne = a.forwardRef(
(t, o) => {
const { __scopeTooltip: e, ...r } = t, n = _(e);
return oe(
N,
e
).isInside ? null : /* @__PURE__ */ d.jsx(V, { ...n, ...r, ref: o });
}
);
ne.displayName = N;
function se(t, o) {
const e = Math.abs(o.top - t.y), r = Math.abs(o.bottom - t.y), n = Math.abs(o.right - t.x), c = Math.abs(o.left - t.x);
switch (Math.min(e, r, n, c)) {
case c:
return "left";
case n:
return "right";
case e:
return "top";
case r:
return "bottom";
default:
throw new Error("unreachable");
}
}
function ie(t, o, e = 5) {
const r = [];
switch (o) {
case "top":
r.push(
{ x: t.x - e, y: t.y + e },
{ x: t.x + e, y: t.y + e }
);
break;
case "bottom":
r.push(
{ x: t.x - e, y: t.y - e },
{ x: t.x + e, y: t.y - e }
);
break;
case "left":
r.push(
{ x: t.x + e, y: t.y - e },
{ x: t.x + e, y: t.y + e }
);
break;
case "right":
r.push(
{ x: t.x - e, y: t.y - e },
{ x: t.x - e, y: t.y + e }
);
break;
}
return r;
}
function ae(t) {
const { top: o, right: e, bottom: r, left: n } = t;
return [
{ x: n, y: o },
{ x: e, y: o },
{ x: e, y: r },
{ x: n, y: r }
];
}
function ce(t, o) {
const { x: e, y: r } = t;
let n = !1;
for (let c = 0, s = o.length - 1; c < o.length; s = c++) {
const f = o[c].x, i = o[c].y, u = o[s].x, l = o[s].y;
i > r != l > r && e < (u - f) * (r - i) / (l - i) + f && (n = !n);
}
return n;
}
function le(t) {
const o = t.slice();
return o.sort((e, r) => e.x < r.x ? -1 : e.x > r.x ? 1 : e.y < r.y ? -1 : e.y > r.y ? 1 : 0), ue(o);
}
function ue(t) {
if (t.length <= 1) return t.slice();
const o = [];
for (let r = 0; r < t.length; r++) {
const n = t[r];
for (; o.length >= 2; ) {
const c = o[o.length - 1], s = o[o.length - 2];
if ((c.x - s.x) * (n.y - s.y) >= (c.y - s.y) * (n.x - s.x)) o.pop();
else break;
}
o.push(n);
}
o.pop();
const e = [];
for (let r = t.length - 1; r >= 0; r--) {
const n = t[r];
for (; e.length >= 2; ) {
const c = e[e.length - 1], s = e[e.length - 2];
if ((c.x - s.x) * (n.y - s.y) >= (c.y - s.y) * (n.x - s.x)) e.pop();
else break;
}
e.push(n);
}
return e.pop(), o.length === 1 && e.length === 1 && o[0].x === e[0].x && o[0].y === e[0].y ? o : o.concat(e);
}
var be = O;
export {
be as Provider,
ne as TooltipArrow,
$ as TooltipContent,
O as TooltipProvider,
J as TooltipTrigger,
ge as createTooltipScope
};
//# sourceMappingURL=index.es564.js.map