"use strict";
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = usePopover;
const react_1 = require("react");
const tippy_js_1 = __importDefault(require("tippy.js"));
const utils_1 = require("../utils");
const consts_1 = require("./consts");
/**
 * Controls the logic of instantiating and managing a tippy instance.
 * Takes multiple configuration props that control closing, placement or behavior.
 * Exposes functions used for ref callbacks on consuming components, programatic open/close methods and properties.
 */
function usePopover(props = {}) {
    const { closeOnBlur = true, closeOnEsc = true, defaultIsOpen = false, flip = true, isOpen: isOpenProp, matchWidth, offset, onClose: onCloseProp, onOpen: onOpenProp, options, placement = 'bottom-start', trigger = 'click', } = props;
    const [isOpen, setIsOpen] = (0, react_1.useState)(isOpenProp !== null && isOpenProp !== void 0 ? isOpenProp : defaultIsOpen);
    const [instance, setInstance] = (0, react_1.useState)(null);
    const [reference, setReference] = (0, react_1.useState)(null);
    const [popper, setPopper] = (0, react_1.useState)(null);
    const close = (0, react_1.useCallback)(() => instance === null || instance === void 0 ? void 0 : instance.hide(), [instance]);
    const onClose = (0, utils_1.useCallbackRef)(onCloseProp);
    const onOpen = (0, utils_1.useCallbackRef)(onOpenProp);
    const open = (0, react_1.useCallback)(() => instance === null || instance === void 0 ? void 0 : instance.show(), [instance]);
    const isControlled = isOpenProp !== undefined;
    const tippyOptions = (0, react_1.useMemo)(() => {
        var _a, _b;
        const _c = options !== null && options !== void 0 ? options : {}, { aria, offset: optionsOffset, onHidden, onHide, onShow, plugins = [], popperOptions = {} } = _c, otherOptions = __rest(_c, ["aria", "offset", "onHidden", "onHide", "onShow", "plugins", "popperOptions"]);
        return Object.assign({ aria, arrow: false, duration: [200, 150], hideOnClick: !isControlled ? closeOnBlur : false, interactive: true, maxWidth: 'none', offset: (_a = optionsOffset !== null && optionsOffset !== void 0 ? optionsOffset : offset) !== null && _a !== void 0 ? _a : [0, 4], onHidden: instance => {
                setIsOpen(false);
                onHidden === null || onHidden === void 0 ? void 0 : onHidden(instance);
            }, onHide: instance => {
                onClose(instance);
                onHide === null || onHide === void 0 ? void 0 : onHide(instance);
            }, onShow: instance => {
                setIsOpen(true);
                onOpen(instance);
                onShow === null || onShow === void 0 ? void 0 : onShow(instance);
            }, placement, plugins: [...(!isControlled && closeOnEsc ? [consts_1.closeOnEscPlugin] : []), ...plugins], popperOptions: Object.assign(Object.assign({}, popperOptions), { modifiers: [
                    {
                        name: 'flip',
                        enabled: flip,
                    },
                    Object.assign(Object.assign({}, consts_1.matchWidthModifier), { enabled: !!matchWidth }),
                    ...((_b = popperOptions.modifiers) !== null && _b !== void 0 ? _b : []),
                ] }), showOnCreate: isOpenProp !== null && isOpenProp !== void 0 ? isOpenProp : defaultIsOpen, trigger: !isControlled ? trigger : 'manual' }, otherOptions);
    }, [closeOnBlur, closeOnEsc, offset, options, placement, trigger]);
    // Create a new Tippy instance
    (0, react_1.useEffect)(() => {
        if (popper !== null && reference !== null) {
            // Destroy old instance to ensure new options work
            instance === null || instance === void 0 ? void 0 : instance.destroy();
            const newInstance = (0, tippy_js_1.default)(reference, Object.assign(Object.assign({}, tippyOptions), { content: popper }));
            setInstance(newInstance);
        }
    }, [popper, tippyOptions, trigger]);
    // Handle showing/hiding popup in controlled mode
    (0, react_1.useEffect)(() => {
        if (isControlled) {
            if (isOpenProp)
                instance === null || instance === void 0 ? void 0 : instance.show();
            else
                instance === null || instance === void 0 ? void 0 : instance.hide();
        }
    }, [isOpenProp]);
    return {
        close,
        instance,
        isOpen,
        open,
        popper,
        reference,
        setPopper,
        setReference,
    };
}
//# sourceMappingURL=usePopover.js.map