@drivy/cobalt
Version:
Opinionated design system for Drivy's projects.
137 lines (136 loc) • 5.01 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import { FloatingArrow, FloatingPortal, arrow, autoUpdate, flip as react_flip, offset as react_offset, safePolygon, shift, useClick, useDismiss, useFloating, useHover, useInteractions, useRole, useTransitionStyles } from "@floating-ui/react";
import classnames from "classnames";
import { useEffect, useRef } from "react";
import { zIndexes } from "../../tokens/index.js";
const ANIMATION_TRANSITION_DISTANCE_PX = 4;
function useDesktopPopoverCore({ isOpen, onOpenChange, referenceElement, placement = "top", flip = true, tooltip = false, arrow: showArrow = true, theme = "", zIndex = zIndexes.dropdown, appendToBody = true, fixed = false, fitContent = true, withBorder = false, trigger = "click", interactive = false, delay = 0, offset, bodySpacing = false, ariaLabel, onShow, onHidden, getFloatingExtraProps }) {
const arrowRef = useRef(null);
const [crossAxis, mainAxis] = offset ?? [
0,
showArrow ? 12 : 8
];
const { refs, floatingStyles, context } = useFloating({
open: isOpen,
onOpenChange,
placement,
strategy: fixed ? "fixed" : "absolute",
transform: false,
middleware: [
shift({
padding: 8
}),
react_offset({
mainAxis,
crossAxis
}),
...flip ? [
react_flip()
] : [],
...showArrow ? [
arrow({
element: arrowRef
})
] : []
],
whileElementsMounted: autoUpdate,
elements: {
reference: referenceElement
}
});
const isHover = "mouseenter" === trigger;
const isClick = "click" === trigger;
const hover = useHover(context, {
enabled: isHover,
move: false,
delay,
handleClose: isHover && interactive ? safePolygon() : void 0
});
const click = useClick(context, {
enabled: isClick
});
const dismiss = useDismiss(context);
const role = useRole(context, {
role: "dialog"
});
const { getReferenceProps, getFloatingProps } = useInteractions([
hover,
click,
dismiss,
role
]);
const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {
duration: {
open: 200,
close: 150
},
initial: ({ side })=>({
opacity: 0,
transform: "top" === side ? `translateY(${ANIMATION_TRANSITION_DISTANCE_PX}px)` : "bottom" === side ? `translateY(-${ANIMATION_TRANSITION_DISTANCE_PX}px)` : "left" === side ? `translateX(${ANIMATION_TRANSITION_DISTANCE_PX}px)` : `translateX(-${ANIMATION_TRANSITION_DISTANCE_PX}px)`
})
});
const prevMountedRef = useRef(false);
useEffect(()=>{
if (isMounted && !prevMountedRef.current) onShow?.();
if (!isMounted && prevMountedRef.current) onHidden?.();
prevMountedRef.current = isMounted;
}, [
isMounted,
onShow,
onHidden
]);
const renderFloating = (content)=>{
if (!isMounted) return null;
const body = bodySpacing ? /*#__PURE__*/ jsx("div", {
className: "cobalt-popover--bodySpacing",
children: content
}) : content;
const extraFloatingProps = getFloatingExtraProps?.() ?? {};
const { onMouseEnter, onMouseLeave, ...restExtraFloatingProps } = extraFloatingProps;
const node = /*#__PURE__*/ jsxs("div", {
ref: refs.setFloating,
style: {
...floatingStyles,
...transitionStyles,
zIndex
},
className: classnames("cobalt-popover", {
"cobalt-popover--withArrow": showArrow,
"cobalt-popover--fitContent": fitContent,
"cobalt-popover--withBorder": withBorder
}),
"data-placement": context.placement,
"data-theme": classnames(theme, {
tooltip: tooltip
}),
...getFloatingProps({
"aria-label": ariaLabel,
...restExtraFloatingProps,
onMouseEnter,
onMouseLeave
}),
children: [
showArrow && /*#__PURE__*/ jsx(FloatingArrow, {
ref: arrowRef,
context: context,
className: "cobalt-popover__arrow"
}),
body
]
});
return appendToBody ? /*#__PURE__*/ jsx(FloatingPortal, {
children: node
}) : node;
};
return {
refs: {
setReference: refs.setReference,
setFloating: refs.setFloating
},
getReferenceProps,
renderFloating,
isMounted
};
}
export { useDesktopPopoverCore };
//# sourceMappingURL=useDesktopPopoverCore.js.map