UNPKG

@drivy/cobalt

Version:

Opinionated design system for Drivy's projects.

103 lines (100 loc) 4.75 kB
import { jsx, jsxs } from 'react/jsx-runtime'; import { useFloating, shift, offset, flip, arrow, autoUpdate, useHover, safePolygon, useClick, useDismiss, useRole, useInteractions, useTransitionStyles, FloatingArrow, FloatingPortal } from '@floating-ui/react'; import cx from 'classnames'; import { useRef, useEffect } from 'react'; import { zIndexes } from '../../tokens/index.js'; const ANIMATION_TRANSITION_DISTANCE_PX = 4; function useDesktopPopoverCore({ isOpen, onOpenChange, referenceElement, placement = "top", flip: flip$1 = true, tooltip = false, arrow: showArrow = true, theme = "", zIndex = zIndexes.dropdown, appendToBody = true, fitContent = true, withBorder = false, trigger = "click", interactive = false, delay = 0, offset: offset$1, bodySpacing = false, ariaLabel, onShow, onHidden, getFloatingExtraProps, }) { const arrowRef = useRef(null); const [crossAxis, mainAxis] = offset$1 !== null && offset$1 !== void 0 ? offset$1 : [0, showArrow ? 12 : 8]; const { refs, floatingStyles, context } = useFloating({ open: isOpen, onOpenChange, placement, transform: false, middleware: [ shift({ padding: 8 }), offset({ mainAxis, crossAxis }), ...(flip$1 ? [flip()] : []), ...(showArrow ? [arrow({ element: arrowRef })] : []), ], whileElementsMounted: autoUpdate, elements: { reference: referenceElement }, }); const isHover = trigger === "mouseenter"; const isClick = trigger === "click"; const hover = useHover(context, { enabled: isHover, move: false, delay, handleClose: isHover && interactive ? safePolygon() : undefined, }); 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: side === "top" ? `translateY(${ANIMATION_TRANSITION_DISTANCE_PX}px)` : side === "bottom" ? `translateY(-${ANIMATION_TRANSITION_DISTANCE_PX}px)` : side === "left" ? `translateX(${ANIMATION_TRANSITION_DISTANCE_PX}px)` : `translateX(-${ANIMATION_TRANSITION_DISTANCE_PX}px)`, }), }); const prevMountedRef = useRef(false); useEffect(() => { if (isMounted && !prevMountedRef.current) onShow === null || onShow === void 0 ? void 0 : onShow(); if (!isMounted && prevMountedRef.current) onHidden === null || onHidden === void 0 ? void 0 : onHidden(); prevMountedRef.current = isMounted; }, [isMounted, onShow, onHidden]); const renderFloating = (content) => { var _a; if (!isMounted) return null; const body = bodySpacing ? (jsx("div", { className: "cobalt-popover--bodySpacing", children: content })) : (content); const extraFloatingProps = (_a = getFloatingExtraProps === null || getFloatingExtraProps === void 0 ? void 0 : getFloatingExtraProps()) !== null && _a !== void 0 ? _a : {}; const { onMouseEnter, onMouseLeave, ...restExtraFloatingProps } = extraFloatingProps; const node = (jsxs("div", { ref: refs.setFloating, style: { ...floatingStyles, ...transitionStyles, zIndex, }, className: cx("cobalt-popover", { "cobalt-popover--withArrow": showArrow, "cobalt-popover--fitContent": fitContent, "cobalt-popover--withBorder": withBorder, }), "data-placement": context.placement, "data-theme": cx(theme, { tooltip: tooltip, }), ...getFloatingProps({ "aria-label": ariaLabel, ...restExtraFloatingProps, onMouseEnter, onMouseLeave, }), children: [showArrow && (jsx(FloatingArrow, { ref: arrowRef, context: context, className: "cobalt-popover__arrow" })), body] })); return appendToBody ? jsx(FloatingPortal, { children: node }) : node; }; return { refs: { setReference: refs.setReference, setFloating: refs.setFloating, }, getReferenceProps, renderFloating, isMounted, }; } export { useDesktopPopoverCore }; //# sourceMappingURL=useDesktopPopoverCore.js.map