Files
Webklar.com/node_modules/@radix-ui/react-hover-card/dist/index.mjs
Basilosaurusrex f027651f9b main repo
2025-11-24 18:09:40 +01:00

262 lines
9.8 KiB
JavaScript

"use client";
// packages/react/hover-card/src/HoverCard.tsx
import * as React from "react";
import { composeEventHandlers } from "@radix-ui/primitive";
import { createContextScope } from "@radix-ui/react-context";
import { useControllableState } from "@radix-ui/react-use-controllable-state";
import { useComposedRefs } from "@radix-ui/react-compose-refs";
import * as PopperPrimitive from "@radix-ui/react-popper";
import { createPopperScope } from "@radix-ui/react-popper";
import { Portal as PortalPrimitive } from "@radix-ui/react-portal";
import { Presence } from "@radix-ui/react-presence";
import { Primitive } from "@radix-ui/react-primitive";
import { DismissableLayer } from "@radix-ui/react-dismissable-layer";
import { jsx } from "react/jsx-runtime";
var originalBodyUserSelect;
var HOVERCARD_NAME = "HoverCard";
var [createHoverCardContext, createHoverCardScope] = createContextScope(HOVERCARD_NAME, [
createPopperScope
]);
var usePopperScope = createPopperScope();
var [HoverCardProvider, useHoverCardContext] = createHoverCardContext(HOVERCARD_NAME);
var HoverCard = (props) => {
const {
__scopeHoverCard,
children,
open: openProp,
defaultOpen,
onOpenChange,
openDelay = 700,
closeDelay = 300
} = props;
const popperScope = usePopperScope(__scopeHoverCard);
const openTimerRef = React.useRef(0);
const closeTimerRef = React.useRef(0);
const hasSelectionRef = React.useRef(false);
const isPointerDownOnContentRef = React.useRef(false);
const [open = false, setOpen] = useControllableState({
prop: openProp,
defaultProp: defaultOpen,
onChange: onOpenChange
});
const handleOpen = React.useCallback(() => {
clearTimeout(closeTimerRef.current);
openTimerRef.current = window.setTimeout(() => setOpen(true), openDelay);
}, [openDelay, setOpen]);
const handleClose = React.useCallback(() => {
clearTimeout(openTimerRef.current);
if (!hasSelectionRef.current && !isPointerDownOnContentRef.current) {
closeTimerRef.current = window.setTimeout(() => setOpen(false), closeDelay);
}
}, [closeDelay, setOpen]);
const handleDismiss = React.useCallback(() => setOpen(false), [setOpen]);
React.useEffect(() => {
return () => {
clearTimeout(openTimerRef.current);
clearTimeout(closeTimerRef.current);
};
}, []);
return /* @__PURE__ */ jsx(
HoverCardProvider,
{
scope: __scopeHoverCard,
open,
onOpenChange: setOpen,
onOpen: handleOpen,
onClose: handleClose,
onDismiss: handleDismiss,
hasSelectionRef,
isPointerDownOnContentRef,
children: /* @__PURE__ */ jsx(PopperPrimitive.Root, { ...popperScope, children })
}
);
};
HoverCard.displayName = HOVERCARD_NAME;
var TRIGGER_NAME = "HoverCardTrigger";
var HoverCardTrigger = React.forwardRef(
(props, forwardedRef) => {
const { __scopeHoverCard, ...triggerProps } = props;
const context = useHoverCardContext(TRIGGER_NAME, __scopeHoverCard);
const popperScope = usePopperScope(__scopeHoverCard);
return /* @__PURE__ */ jsx(PopperPrimitive.Anchor, { asChild: true, ...popperScope, children: /* @__PURE__ */ jsx(
Primitive.a,
{
"data-state": context.open ? "open" : "closed",
...triggerProps,
ref: forwardedRef,
onPointerEnter: composeEventHandlers(props.onPointerEnter, excludeTouch(context.onOpen)),
onPointerLeave: composeEventHandlers(props.onPointerLeave, excludeTouch(context.onClose)),
onFocus: composeEventHandlers(props.onFocus, context.onOpen),
onBlur: composeEventHandlers(props.onBlur, context.onClose),
onTouchStart: composeEventHandlers(props.onTouchStart, (event) => event.preventDefault())
}
) });
}
);
HoverCardTrigger.displayName = TRIGGER_NAME;
var PORTAL_NAME = "HoverCardPortal";
var [PortalProvider, usePortalContext] = createHoverCardContext(PORTAL_NAME, {
forceMount: void 0
});
var HoverCardPortal = (props) => {
const { __scopeHoverCard, forceMount, children, container } = props;
const context = useHoverCardContext(PORTAL_NAME, __scopeHoverCard);
return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopeHoverCard, forceMount, children: /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(PortalPrimitive, { asChild: true, container, children }) }) });
};
HoverCardPortal.displayName = PORTAL_NAME;
var CONTENT_NAME = "HoverCardContent";
var HoverCardContent = React.forwardRef(
(props, forwardedRef) => {
const portalContext = usePortalContext(CONTENT_NAME, props.__scopeHoverCard);
const { forceMount = portalContext.forceMount, ...contentProps } = props;
const context = useHoverCardContext(CONTENT_NAME, props.__scopeHoverCard);
return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(
HoverCardContentImpl,
{
"data-state": context.open ? "open" : "closed",
...contentProps,
onPointerEnter: composeEventHandlers(props.onPointerEnter, excludeTouch(context.onOpen)),
onPointerLeave: composeEventHandlers(props.onPointerLeave, excludeTouch(context.onClose)),
ref: forwardedRef
}
) });
}
);
HoverCardContent.displayName = CONTENT_NAME;
var HoverCardContentImpl = React.forwardRef((props, forwardedRef) => {
const {
__scopeHoverCard,
onEscapeKeyDown,
onPointerDownOutside,
onFocusOutside,
onInteractOutside,
...contentProps
} = props;
const context = useHoverCardContext(CONTENT_NAME, __scopeHoverCard);
const popperScope = usePopperScope(__scopeHoverCard);
const ref = React.useRef(null);
const composedRefs = useComposedRefs(forwardedRef, ref);
const [containSelection, setContainSelection] = React.useState(false);
React.useEffect(() => {
if (containSelection) {
const body = document.body;
originalBodyUserSelect = body.style.userSelect || body.style.webkitUserSelect;
body.style.userSelect = "none";
body.style.webkitUserSelect = "none";
return () => {
body.style.userSelect = originalBodyUserSelect;
body.style.webkitUserSelect = originalBodyUserSelect;
};
}
}, [containSelection]);
React.useEffect(() => {
if (ref.current) {
const handlePointerUp = () => {
setContainSelection(false);
context.isPointerDownOnContentRef.current = false;
setTimeout(() => {
const hasSelection = document.getSelection()?.toString() !== "";
if (hasSelection) context.hasSelectionRef.current = true;
});
};
document.addEventListener("pointerup", handlePointerUp);
return () => {
document.removeEventListener("pointerup", handlePointerUp);
context.hasSelectionRef.current = false;
context.isPointerDownOnContentRef.current = false;
};
}
}, [context.isPointerDownOnContentRef, context.hasSelectionRef]);
React.useEffect(() => {
if (ref.current) {
const tabbables = getTabbableNodes(ref.current);
tabbables.forEach((tabbable) => tabbable.setAttribute("tabindex", "-1"));
}
});
return /* @__PURE__ */ jsx(
DismissableLayer,
{
asChild: true,
disableOutsidePointerEvents: false,
onInteractOutside,
onEscapeKeyDown,
onPointerDownOutside,
onFocusOutside: composeEventHandlers(onFocusOutside, (event) => {
event.preventDefault();
}),
onDismiss: context.onDismiss,
children: /* @__PURE__ */ jsx(
PopperPrimitive.Content,
{
...popperScope,
...contentProps,
onPointerDown: composeEventHandlers(contentProps.onPointerDown, (event) => {
if (event.currentTarget.contains(event.target)) {
setContainSelection(true);
}
context.hasSelectionRef.current = false;
context.isPointerDownOnContentRef.current = true;
}),
ref: composedRefs,
style: {
...contentProps.style,
userSelect: containSelection ? "text" : void 0,
// Safari requires prefix
WebkitUserSelect: containSelection ? "text" : void 0,
// re-namespace exposed content custom properties
...{
"--radix-hover-card-content-transform-origin": "var(--radix-popper-transform-origin)",
"--radix-hover-card-content-available-width": "var(--radix-popper-available-width)",
"--radix-hover-card-content-available-height": "var(--radix-popper-available-height)",
"--radix-hover-card-trigger-width": "var(--radix-popper-anchor-width)",
"--radix-hover-card-trigger-height": "var(--radix-popper-anchor-height)"
}
}
}
)
}
);
});
var ARROW_NAME = "HoverCardArrow";
var HoverCardArrow = React.forwardRef(
(props, forwardedRef) => {
const { __scopeHoverCard, ...arrowProps } = props;
const popperScope = usePopperScope(__scopeHoverCard);
return /* @__PURE__ */ jsx(PopperPrimitive.Arrow, { ...popperScope, ...arrowProps, ref: forwardedRef });
}
);
HoverCardArrow.displayName = ARROW_NAME;
function excludeTouch(eventHandler) {
return (event) => event.pointerType === "touch" ? void 0 : eventHandler();
}
function getTabbableNodes(container) {
const nodes = [];
const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
acceptNode: (node) => {
return node.tabIndex >= 0 ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
}
});
while (walker.nextNode()) nodes.push(walker.currentNode);
return nodes;
}
var Root2 = HoverCard;
var Trigger = HoverCardTrigger;
var Portal = HoverCardPortal;
var Content2 = HoverCardContent;
var Arrow2 = HoverCardArrow;
export {
Arrow2 as Arrow,
Content2 as Content,
HoverCard,
HoverCardArrow,
HoverCardContent,
HoverCardPortal,
HoverCardTrigger,
Portal,
Root2 as Root,
Trigger,
createHoverCardScope
};
//# sourceMappingURL=index.mjs.map