"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.popoverBodyProps = void 0;
const vue_1 = require("vue");
const vueuc_1 = require("vueuc");
const vdirs_1 = require("vdirs");
const _mixins_1 = require("../../_mixins");
const _utils_1 = require("../../_utils");
const styles_1 = require("../styles");
const index_cssr_1 = require("./styles/index.cssr");
const interface_1 = require("./interface");
const interface_2 = require("../../drawer/src/interface");
const interface_3 = require("../../modal/src/interface");
exports.popoverBodyProps = Object.assign(Object.assign({}, _mixins_1.useTheme.props), { to: _utils_1.useAdjustedTo.propTo, show: Boolean, trigger: String, showArrow: Boolean, delay: Number, duration: Number, raw: Boolean, arrowStyle: [String, Object], displayDirective: String, x: Number, y: Number, filp: Boolean, overlap: Boolean, placement: String, width: [Number, String], 
    // private
    shadow: Boolean, padded: Boolean, animated: Boolean, 
    /** @deprecated */
    minWidth: Number, maxWidth: Number });
exports.default = vue_1.defineComponent({
    name: 'PopoverBody',
    inheritAttrs: false,
    props: exports.popoverBodyProps,
    setup(props, { slots, attrs }) {
        const { namespaceRef, mergedClsPrefixRef } = _mixins_1.useConfig(props);
        const themeRef = _mixins_1.useTheme('Popover', 'Popover', index_cssr_1.default, styles_1.popoverLight, props, mergedClsPrefixRef);
        const followerRef = vue_1.ref(null);
        const NPopover = vue_1.inject('NPopover');
        const bodyRef = vue_1.ref(null);
        const followerEnabledRef = vue_1.ref(props.show);
        const directivesRef = vue_1.computed(() => {
            const { trigger } = props;
            const directives = [];
            const { positionManuallyRef: { value: positionManually } } = NPopover;
            if (!positionManually) {
                if (trigger === 'click') {
                    directives.push([vdirs_1.clickoutside, handleClickOutside]);
                }
                if (trigger === 'hover') {
                    directives.push([vdirs_1.mousemoveoutside, handleMouseMoveOutside]);
                }
            }
            if (props.displayDirective === 'show') {
                directives.push([vue_1.vShow, props.show]);
            }
            return directives;
        });
        const styleRef = vue_1.computed(() => {
            return [
                {
                    width: props.width === 'trigger' ? '' : _utils_1.formatLength(props.width),
                    maxWidth: _utils_1.formatLength(props.maxWidth),
                    minWidth: _utils_1.formatLength(props.minWidth)
                },
                cssVarsRef.value
            ];
        });
        const cssVarsRef = vue_1.computed(() => {
            const { common: { cubicBezierEaseInOut, cubicBezierEaseIn, cubicBezierEaseOut }, self: { space, spaceArrow, padding, fontSize, textColor, color, boxShadow, borderRadius, arrowHeight, arrowOffset, arrowOffsetVertical } } = themeRef.value;
            return {
                '--box-shadow': boxShadow,
                '--bezier': cubicBezierEaseInOut,
                '--bezier-ease-in': cubicBezierEaseIn,
                '--bezier-ease-out': cubicBezierEaseOut,
                '--font-size': fontSize,
                '--text-color': textColor,
                '--color': color,
                '--border-radius': borderRadius,
                '--arrow-height': arrowHeight,
                '--arrow-offset': arrowOffset,
                '--arrow-offset-vertical': arrowOffsetVertical,
                '--padding': padding,
                '--space': space,
                '--space-arrow': spaceArrow
            };
        });
        NPopover.setBodyInstance({
            syncPosition
        });
        vue_1.onBeforeUnmount(() => {
            NPopover.setBodyInstance(null);
        });
        vue_1.watch(vue_1.toRef(props, 'show'), (value) => {
            // If no animation, no transition component will be applied to the
            // component. So we need to trigger follower manaully.
            if (props.animated)
                return;
            if (value) {
                followerEnabledRef.value = true;
            }
            else {
                followerEnabledRef.value = false;
            }
        });
        function syncPosition() {
            var _a;
            // eslint-disable-next-line no-unused-expressions
            (_a = followerRef.value) === null || _a === void 0 ? void 0 : _a.syncPosition();
        }
        function handleMouseEnter(e) {
            if (props.trigger === 'hover') {
                NPopover.handleMouseEnter(e);
            }
        }
        function handleMouseLeave(e) {
            if (props.trigger === 'hover') {
                NPopover.handleMouseLeave(e);
            }
        }
        function handleMouseMoveOutside(e) {
            if (props.trigger === 'hover' &&
                !getTriggerElement().contains(e.target)) {
                NPopover.handleMouseMoveOutside(e);
            }
        }
        function handleClickOutside(e) {
            if (props.trigger === 'click' &&
                !getTriggerElement().contains(e.target)) {
                NPopover.handleClickOutside(e);
            }
        }
        function getTriggerElement() {
            return NPopover.getTriggerElement();
        }
        vue_1.provide(interface_1.popoverBodyInjectionKey, bodyRef);
        vue_1.provide(interface_2.drawerBodyInjectionKey, null);
        vue_1.provide(interface_3.modalBodyInjectionKey, null);
        function renderContentNode() {
            const mergedClsPrefix = mergedClsPrefixRef.value;
            const extraClass = NPopover.extraClassRef.value;
            return props.displayDirective === 'show' || props.show
                ? vue_1.withDirectives(vue_1.h('div', vue_1.mergeProps({
                    class: [
                        `${mergedClsPrefix}-popover`,
                        extraClass && `${mergedClsPrefix}-${extraClass}`,
                        {
                            [`${mergedClsPrefix}-popover--overlap`]: props.overlap,
                            [`${mergedClsPrefix}-popover--no-arrow`]: !props.showArrow,
                            [`${mergedClsPrefix}-popover--shadow`]: props.shadow,
                            [`${mergedClsPrefix}-popover--padded`]: props.padded,
                            [`${mergedClsPrefix}-popover--raw`]: props.raw
                        }
                    ],
                    ref: bodyRef,
                    style: styleRef.value,
                    onMouseenter: handleMouseEnter,
                    onMouseleave: handleMouseLeave
                }, attrs), [
                    vue_1.renderSlot(slots, 'default'),
                    props.showArrow ? (vue_1.h("div", { class: `${mergedClsPrefix}-popover-arrow-wrapper`, key: "__popover-arrow__" },
                        vue_1.h("div", { class: `${mergedClsPrefix}-popover-arrow`, style: props.arrowStyle }))) : null
                ]), directivesRef.value)
                : null;
        }
        return {
            namespace: namespaceRef,
            NPopover,
            followerRef,
            adjustedTo: _utils_1.useAdjustedTo(props),
            followerEnabled: followerEnabledRef,
            renderContentNode
        };
    },
    render() {
        return vue_1.h(vueuc_1.VFollower, {
            show: this.show,
            enabled: this.followerEnabled,
            to: this.adjustedTo,
            x: this.x,
            y: this.y,
            placement: this.placement,
            containerClass: this.namespace,
            ref: 'followerRef',
            overlap: this.overlap,
            width: this.width === 'trigger' ? 'target' : undefined,
            teleportDisabled: this.adjustedTo === _utils_1.useAdjustedTo.tdkey
        }, {
            default: () => {
                return this.animated
                    ? vue_1.h(vue_1.Transition, {
                        name: 'popover-transition',
                        appear: this.NPopover.isMountedRef.value,
                        // Don't use watch to enable follower, since the transition may
                        // make position sync timing very subtle and buggy.
                        onEnter: () => {
                            this.followerEnabled = true;
                        },
                        onAfterLeave: () => {
                            this.followerEnabled = false;
                        }
                    }, {
                        default: this.renderContentNode
                    })
                    : this.renderContentNode();
            }
        });
    }
});
