import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { flip, offset, shift } from "@floating-ui/dom";
import { FloatingFocusManager, FloatingPortal, autoUpdate, safePolygon, useClick, useDismiss, useFloating, useHover, useInteractions, useTransitionStyles } from "@floating-ui/react";
import clsx from "clsx";
import { useState } from "react";
import { PopoverContext } from "./context";
import { defineSlot, processSlots } from "./slots";
function computeElementProps(value) {
    if (!value)
        return { enabled: false };
    return (typeof value === 'boolean' ? { enabled: value } : value);
}
function getHoverProps(props) {
    return props?.hover === true ? {
        enabled: true,
        handleClose: safePolygon({ blockPointerEvents: true }),
        restMs: 0,
    } : props?.hover;
}
function getClickProps(props) {
    return props && !props.hover && !props.click ? {
        enabled: true,
    } : props?.click;
}
/**
 * The component is instantiated when all interactions are known
 * @param param0
 * @returns
 */
export function Popover(props) {
    const slots = {};
    processSlots(props.children, slots);
    if (!slots.content) {
        throw new Error('Popover must provide a content slot');
    }
    const triggerProps = slots.trigger?.props;
    const contentProps = slots.content.props;
    // wait for the trigger to be defined
    return _jsx(ResolvedPopover, { ...props, trigger: triggerProps, content: contentProps });
}
function ResolvedPopover({ middleware, offset: defaultOffset, trigger, dismiss = true, content, placement, strategy, zIndex = 40 }) {
    const [isOpen, setIsOpen] = useState(false);
    const floating = useFloating({
        open: isOpen,
        placement,
        strategy,
        onOpenChange: setIsOpen,
        middleware: middleware || [offset(defaultOffset || 4), shift(), flip()],
        whileElementsMounted: autoUpdate // stick to the anchor when resizing / scrolling
    });
    const { floatingStyles, refs: { setReference, setFloating }, context, } = floating;
    const dismissInteraction = useDismiss(context, computeElementProps(dismiss));
    const clickInteraction = useClick(context, computeElementProps(getClickProps(trigger)));
    const hoverInteraction = useHover(context, computeElementProps(getHoverProps(trigger)));
    const { getReferenceProps, getFloatingProps, } = useInteractions([dismissInteraction, clickInteraction, hoverInteraction]);
    const { isMounted, styles: transitionStyles } = useTransitionStyles(context, content.transition);
    return (_jsxs(PopoverContext.Provider, { value: {
            ...floating,
            close: () => setIsOpen(false)
        }, children: [trigger &&
                _jsx("div", { className: clsx(trigger.className, "inline-block"), ref: setReference, ...getReferenceProps(), children: trigger.children }), _jsx(FloatingPortal, { children: isMounted && (_jsx("div", { ref: setFloating, style: { ...floatingStyles, zIndex: zIndex }, ...getFloatingProps(), children: _jsx(FloatingFocusManager, { context: context, children: _jsx("div", { className: clsx(content.className, "bg-popover rounded-md text-popover-foreground max-w-md"), style: transitionStyles, children: content.children }) }) })) })] }));
}
function PopoverTrigger(_props) {
    return null;
}
defineSlot('trigger', PopoverTrigger);
function PopoverContent(_props) {
    return null;
}
defineSlot('content', PopoverContent);
Popover.Trigger = PopoverTrigger;
Popover.Content = PopoverContent;
//# sourceMappingURL=Popover.js.map