Files
Basilosaurusrex f027651f9b main repo
2025-11-24 18:09:40 +01:00

525 lines
21 KiB
JavaScript

"use strict";
"use client";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// packages/react/tooltip/src/index.ts
var src_exports = {};
__export(src_exports, {
Arrow: () => Arrow2,
Content: () => Content2,
Portal: () => Portal,
Provider: () => Provider,
Root: () => Root3,
Tooltip: () => Tooltip,
TooltipArrow: () => TooltipArrow,
TooltipContent: () => TooltipContent,
TooltipPortal: () => TooltipPortal,
TooltipProvider: () => TooltipProvider,
TooltipTrigger: () => TooltipTrigger,
Trigger: () => Trigger,
createTooltipScope: () => createTooltipScope
});
module.exports = __toCommonJS(src_exports);
// packages/react/tooltip/src/Tooltip.tsx
var React = __toESM(require("react"));
var import_primitive = require("@radix-ui/primitive");
var import_react_compose_refs = require("@radix-ui/react-compose-refs");
var import_react_context = require("@radix-ui/react-context");
var import_react_dismissable_layer = require("@radix-ui/react-dismissable-layer");
var import_react_id = require("@radix-ui/react-id");
var PopperPrimitive = __toESM(require("@radix-ui/react-popper"));
var import_react_popper = require("@radix-ui/react-popper");
var import_react_portal = require("@radix-ui/react-portal");
var import_react_presence = require("@radix-ui/react-presence");
var import_react_primitive = require("@radix-ui/react-primitive");
var import_react_slot = require("@radix-ui/react-slot");
var import_react_use_controllable_state = require("@radix-ui/react-use-controllable-state");
var VisuallyHiddenPrimitive = __toESM(require("@radix-ui/react-visually-hidden"));
var import_jsx_runtime = require("react/jsx-runtime");
var [createTooltipContext, createTooltipScope] = (0, import_react_context.createContextScope)("Tooltip", [
import_react_popper.createPopperScope
]);
var usePopperScope = (0, import_react_popper.createPopperScope)();
var PROVIDER_NAME = "TooltipProvider";
var DEFAULT_DELAY_DURATION = 700;
var TOOLTIP_OPEN = "tooltip.open";
var [TooltipProviderContextProvider, useTooltipProviderContext] = createTooltipContext(PROVIDER_NAME);
var TooltipProvider = (props) => {
const {
__scopeTooltip,
delayDuration = DEFAULT_DELAY_DURATION,
skipDelayDuration = 300,
disableHoverableContent = false,
children
} = props;
const [isOpenDelayed, setIsOpenDelayed] = React.useState(true);
const isPointerInTransitRef = React.useRef(false);
const skipDelayTimerRef = React.useRef(0);
React.useEffect(() => {
const skipDelayTimer = skipDelayTimerRef.current;
return () => window.clearTimeout(skipDelayTimer);
}, []);
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
TooltipProviderContextProvider,
{
scope: __scopeTooltip,
isOpenDelayed,
delayDuration,
onOpen: React.useCallback(() => {
window.clearTimeout(skipDelayTimerRef.current);
setIsOpenDelayed(false);
}, []),
onClose: React.useCallback(() => {
window.clearTimeout(skipDelayTimerRef.current);
skipDelayTimerRef.current = window.setTimeout(
() => setIsOpenDelayed(true),
skipDelayDuration
);
}, [skipDelayDuration]),
isPointerInTransitRef,
onPointerInTransitChange: React.useCallback((inTransit) => {
isPointerInTransitRef.current = inTransit;
}, []),
disableHoverableContent,
children
}
);
};
TooltipProvider.displayName = PROVIDER_NAME;
var TOOLTIP_NAME = "Tooltip";
var [TooltipContextProvider, useTooltipContext] = createTooltipContext(TOOLTIP_NAME);
var Tooltip = (props) => {
const {
__scopeTooltip,
children,
open: openProp,
defaultOpen = false,
onOpenChange,
disableHoverableContent: disableHoverableContentProp,
delayDuration: delayDurationProp
} = props;
const providerContext = useTooltipProviderContext(TOOLTIP_NAME, props.__scopeTooltip);
const popperScope = usePopperScope(__scopeTooltip);
const [trigger, setTrigger] = React.useState(null);
const contentId = (0, import_react_id.useId)();
const openTimerRef = React.useRef(0);
const disableHoverableContent = disableHoverableContentProp ?? providerContext.disableHoverableContent;
const delayDuration = delayDurationProp ?? providerContext.delayDuration;
const wasOpenDelayedRef = React.useRef(false);
const [open = false, setOpen] = (0, import_react_use_controllable_state.useControllableState)({
prop: openProp,
defaultProp: defaultOpen,
onChange: (open2) => {
if (open2) {
providerContext.onOpen();
document.dispatchEvent(new CustomEvent(TOOLTIP_OPEN));
} else {
providerContext.onClose();
}
onOpenChange?.(open2);
}
});
const stateAttribute = React.useMemo(() => {
return open ? wasOpenDelayedRef.current ? "delayed-open" : "instant-open" : "closed";
}, [open]);
const handleOpen = React.useCallback(() => {
window.clearTimeout(openTimerRef.current);
wasOpenDelayedRef.current = false;
setOpen(true);
}, [setOpen]);
const handleClose = React.useCallback(() => {
window.clearTimeout(openTimerRef.current);
setOpen(false);
}, [setOpen]);
const handleDelayedOpen = React.useCallback(() => {
window.clearTimeout(openTimerRef.current);
openTimerRef.current = window.setTimeout(() => {
wasOpenDelayedRef.current = true;
setOpen(true);
}, delayDuration);
}, [delayDuration, setOpen]);
React.useEffect(() => {
return () => window.clearTimeout(openTimerRef.current);
}, []);
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PopperPrimitive.Root, { ...popperScope, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
TooltipContextProvider,
{
scope: __scopeTooltip,
contentId,
open,
stateAttribute,
trigger,
onTriggerChange: setTrigger,
onTriggerEnter: React.useCallback(() => {
if (providerContext.isOpenDelayed) handleDelayedOpen();
else handleOpen();
}, [providerContext.isOpenDelayed, handleDelayedOpen, handleOpen]),
onTriggerLeave: React.useCallback(() => {
if (disableHoverableContent) {
handleClose();
} else {
window.clearTimeout(openTimerRef.current);
}
}, [handleClose, disableHoverableContent]),
onOpen: handleOpen,
onClose: handleClose,
disableHoverableContent,
children
}
) });
};
Tooltip.displayName = TOOLTIP_NAME;
var TRIGGER_NAME = "TooltipTrigger";
var TooltipTrigger = React.forwardRef(
(props, forwardedRef) => {
const { __scopeTooltip, ...triggerProps } = props;
const context = useTooltipContext(TRIGGER_NAME, __scopeTooltip);
const providerContext = useTooltipProviderContext(TRIGGER_NAME, __scopeTooltip);
const popperScope = usePopperScope(__scopeTooltip);
const ref = React.useRef(null);
const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, ref, context.onTriggerChange);
const isPointerDownRef = React.useRef(false);
const hasPointerMoveOpenedRef = React.useRef(false);
const handlePointerUp = React.useCallback(() => isPointerDownRef.current = false, []);
React.useEffect(() => {
return () => document.removeEventListener("pointerup", handlePointerUp);
}, [handlePointerUp]);
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PopperPrimitive.Anchor, { asChild: true, ...popperScope, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_react_primitive.Primitive.button,
{
"aria-describedby": context.open ? context.contentId : void 0,
"data-state": context.stateAttribute,
...triggerProps,
ref: composedRefs,
onPointerMove: (0, import_primitive.composeEventHandlers)(props.onPointerMove, (event) => {
if (event.pointerType === "touch") return;
if (!hasPointerMoveOpenedRef.current && !providerContext.isPointerInTransitRef.current) {
context.onTriggerEnter();
hasPointerMoveOpenedRef.current = true;
}
}),
onPointerLeave: (0, import_primitive.composeEventHandlers)(props.onPointerLeave, () => {
context.onTriggerLeave();
hasPointerMoveOpenedRef.current = false;
}),
onPointerDown: (0, import_primitive.composeEventHandlers)(props.onPointerDown, () => {
isPointerDownRef.current = true;
document.addEventListener("pointerup", handlePointerUp, { once: true });
}),
onFocus: (0, import_primitive.composeEventHandlers)(props.onFocus, () => {
if (!isPointerDownRef.current) context.onOpen();
}),
onBlur: (0, import_primitive.composeEventHandlers)(props.onBlur, context.onClose),
onClick: (0, import_primitive.composeEventHandlers)(props.onClick, context.onClose)
}
) });
}
);
TooltipTrigger.displayName = TRIGGER_NAME;
var PORTAL_NAME = "TooltipPortal";
var [PortalProvider, usePortalContext] = createTooltipContext(PORTAL_NAME, {
forceMount: void 0
});
var TooltipPortal = (props) => {
const { __scopeTooltip, forceMount, children, container } = props;
const context = useTooltipContext(PORTAL_NAME, __scopeTooltip);
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PortalProvider, { scope: __scopeTooltip, forceMount, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_presence.Presence, { present: forceMount || context.open, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_portal.Portal, { asChild: true, container, children }) }) });
};
TooltipPortal.displayName = PORTAL_NAME;
var CONTENT_NAME = "TooltipContent";
var TooltipContent = React.forwardRef(
(props, forwardedRef) => {
const portalContext = usePortalContext(CONTENT_NAME, props.__scopeTooltip);
const { forceMount = portalContext.forceMount, side = "top", ...contentProps } = props;
const context = useTooltipContext(CONTENT_NAME, props.__scopeTooltip);
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_presence.Presence, { present: forceMount || context.open, children: context.disableHoverableContent ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TooltipContentImpl, { side, ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TooltipContentHoverable, { side, ...contentProps, ref: forwardedRef }) });
}
);
var TooltipContentHoverable = React.forwardRef((props, forwardedRef) => {
const context = useTooltipContext(CONTENT_NAME, props.__scopeTooltip);
const providerContext = useTooltipProviderContext(CONTENT_NAME, props.__scopeTooltip);
const ref = React.useRef(null);
const composedRefs = (0, import_react_compose_refs.useComposedRefs)(forwardedRef, ref);
const [pointerGraceArea, setPointerGraceArea] = React.useState(null);
const { trigger, onClose } = context;
const content = ref.current;
const { onPointerInTransitChange } = providerContext;
const handleRemoveGraceArea = React.useCallback(() => {
setPointerGraceArea(null);
onPointerInTransitChange(false);
}, [onPointerInTransitChange]);
const handleCreateGraceArea = React.useCallback(
(event, hoverTarget) => {
const currentTarget = event.currentTarget;
const exitPoint = { x: event.clientX, y: event.clientY };
const exitSide = getExitSideFromRect(exitPoint, currentTarget.getBoundingClientRect());
const paddedExitPoints = getPaddedExitPoints(exitPoint, exitSide);
const hoverTargetPoints = getPointsFromRect(hoverTarget.getBoundingClientRect());
const graceArea = getHull([...paddedExitPoints, ...hoverTargetPoints]);
setPointerGraceArea(graceArea);
onPointerInTransitChange(true);
},
[onPointerInTransitChange]
);
React.useEffect(() => {
return () => handleRemoveGraceArea();
}, [handleRemoveGraceArea]);
React.useEffect(() => {
if (trigger && content) {
const handleTriggerLeave = (event) => handleCreateGraceArea(event, content);
const handleContentLeave = (event) => handleCreateGraceArea(event, trigger);
trigger.addEventListener("pointerleave", handleTriggerLeave);
content.addEventListener("pointerleave", handleContentLeave);
return () => {
trigger.removeEventListener("pointerleave", handleTriggerLeave);
content.removeEventListener("pointerleave", handleContentLeave);
};
}
}, [trigger, content, handleCreateGraceArea, handleRemoveGraceArea]);
React.useEffect(() => {
if (pointerGraceArea) {
const handleTrackPointerGrace = (event) => {
const target = event.target;
const pointerPosition = { x: event.clientX, y: event.clientY };
const hasEnteredTarget = trigger?.contains(target) || content?.contains(target);
const isPointerOutsideGraceArea = !isPointInPolygon(pointerPosition, pointerGraceArea);
if (hasEnteredTarget) {
handleRemoveGraceArea();
} else if (isPointerOutsideGraceArea) {
handleRemoveGraceArea();
onClose();
}
};
document.addEventListener("pointermove", handleTrackPointerGrace);
return () => document.removeEventListener("pointermove", handleTrackPointerGrace);
}
}, [trigger, content, pointerGraceArea, onClose, handleRemoveGraceArea]);
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TooltipContentImpl, { ...props, ref: composedRefs });
});
var [VisuallyHiddenContentContextProvider, useVisuallyHiddenContentContext] = createTooltipContext(TOOLTIP_NAME, { isInside: false });
var TooltipContentImpl = React.forwardRef(
(props, forwardedRef) => {
const {
__scopeTooltip,
children,
"aria-label": ariaLabel,
onEscapeKeyDown,
onPointerDownOutside,
...contentProps
} = props;
const context = useTooltipContext(CONTENT_NAME, __scopeTooltip);
const popperScope = usePopperScope(__scopeTooltip);
const { onClose } = context;
React.useEffect(() => {
document.addEventListener(TOOLTIP_OPEN, onClose);
return () => document.removeEventListener(TOOLTIP_OPEN, onClose);
}, [onClose]);
React.useEffect(() => {
if (context.trigger) {
const handleScroll = (event) => {
const target = event.target;
if (target?.contains(context.trigger)) onClose();
};
window.addEventListener("scroll", handleScroll, { capture: true });
return () => window.removeEventListener("scroll", handleScroll, { capture: true });
}
}, [context.trigger, onClose]);
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_react_dismissable_layer.DismissableLayer,
{
asChild: true,
disableOutsidePointerEvents: false,
onEscapeKeyDown,
onPointerDownOutside,
onFocusOutside: (event) => event.preventDefault(),
onDismiss: onClose,
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
PopperPrimitive.Content,
{
"data-state": context.stateAttribute,
...popperScope,
...contentProps,
ref: forwardedRef,
style: {
...contentProps.style,
// re-namespace exposed content custom properties
...{
"--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__ */ (0, import_jsx_runtime.jsx)(import_react_slot.Slottable, { children }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(VisuallyHiddenContentContextProvider, { scope: __scopeTooltip, isInside: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VisuallyHiddenPrimitive.Root, { id: context.contentId, role: "tooltip", children: ariaLabel || children }) })
]
}
)
}
);
}
);
TooltipContent.displayName = CONTENT_NAME;
var ARROW_NAME = "TooltipArrow";
var TooltipArrow = React.forwardRef(
(props, forwardedRef) => {
const { __scopeTooltip, ...arrowProps } = props;
const popperScope = usePopperScope(__scopeTooltip);
const visuallyHiddenContentContext = useVisuallyHiddenContentContext(
ARROW_NAME,
__scopeTooltip
);
return visuallyHiddenContentContext.isInside ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PopperPrimitive.Arrow, { ...popperScope, ...arrowProps, ref: forwardedRef });
}
);
TooltipArrow.displayName = ARROW_NAME;
function getExitSideFromRect(point, rect) {
const top = Math.abs(rect.top - point.y);
const bottom = Math.abs(rect.bottom - point.y);
const right = Math.abs(rect.right - point.x);
const left = Math.abs(rect.left - point.x);
switch (Math.min(top, bottom, right, left)) {
case left:
return "left";
case right:
return "right";
case top:
return "top";
case bottom:
return "bottom";
default:
throw new Error("unreachable");
}
}
function getPaddedExitPoints(exitPoint, exitSide, padding = 5) {
const paddedExitPoints = [];
switch (exitSide) {
case "top":
paddedExitPoints.push(
{ x: exitPoint.x - padding, y: exitPoint.y + padding },
{ x: exitPoint.x + padding, y: exitPoint.y + padding }
);
break;
case "bottom":
paddedExitPoints.push(
{ x: exitPoint.x - padding, y: exitPoint.y - padding },
{ x: exitPoint.x + padding, y: exitPoint.y - padding }
);
break;
case "left":
paddedExitPoints.push(
{ x: exitPoint.x + padding, y: exitPoint.y - padding },
{ x: exitPoint.x + padding, y: exitPoint.y + padding }
);
break;
case "right":
paddedExitPoints.push(
{ x: exitPoint.x - padding, y: exitPoint.y - padding },
{ x: exitPoint.x - padding, y: exitPoint.y + padding }
);
break;
}
return paddedExitPoints;
}
function getPointsFromRect(rect) {
const { top, right, bottom, left } = rect;
return [
{ x: left, y: top },
{ x: right, y: top },
{ x: right, y: bottom },
{ x: left, y: bottom }
];
}
function isPointInPolygon(point, polygon) {
const { x, y } = point;
let inside = false;
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
const xi = polygon[i].x;
const yi = polygon[i].y;
const xj = polygon[j].x;
const yj = polygon[j].y;
const intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi;
if (intersect) inside = !inside;
}
return inside;
}
function getHull(points) {
const newPoints = points.slice();
newPoints.sort((a, b) => {
if (a.x < b.x) return -1;
else if (a.x > b.x) return 1;
else if (a.y < b.y) return -1;
else if (a.y > b.y) return 1;
else return 0;
});
return getHullPresorted(newPoints);
}
function getHullPresorted(points) {
if (points.length <= 1) return points.slice();
const upperHull = [];
for (let i = 0; i < points.length; i++) {
const p = points[i];
while (upperHull.length >= 2) {
const q = upperHull[upperHull.length - 1];
const r = upperHull[upperHull.length - 2];
if ((q.x - r.x) * (p.y - r.y) >= (q.y - r.y) * (p.x - r.x)) upperHull.pop();
else break;
}
upperHull.push(p);
}
upperHull.pop();
const lowerHull = [];
for (let i = points.length - 1; i >= 0; i--) {
const p = points[i];
while (lowerHull.length >= 2) {
const q = lowerHull[lowerHull.length - 1];
const r = lowerHull[lowerHull.length - 2];
if ((q.x - r.x) * (p.y - r.y) >= (q.y - r.y) * (p.x - r.x)) lowerHull.pop();
else break;
}
lowerHull.push(p);
}
lowerHull.pop();
if (upperHull.length === 1 && lowerHull.length === 1 && upperHull[0].x === lowerHull[0].x && upperHull[0].y === lowerHull[0].y) {
return upperHull;
} else {
return upperHull.concat(lowerHull);
}
}
var Provider = TooltipProvider;
var Root3 = Tooltip;
var Trigger = TooltipTrigger;
var Portal = TooltipPortal;
var Content2 = TooltipContent;
var Arrow2 = TooltipArrow;
//# sourceMappingURL=index.js.map