import { __decorate, __extends } from "tslib";
import Popper from 'popper.js';
import Component from 'vue-class-component';
import { Prop } from 'vue-property-decorator';
import { BackdropMode, Portal } from '../../mixins/portal/portal';
import { Enums } from '../../utils/enums/enums';
import { REGEX_CSS_NUMBER_VALUE } from '../../utils/props-validation/props-validation';
import { ModulVue } from '../../utils/vue/vue';
import { POPPER_NAME } from '../component-names';
import WithRender from './popper.html?style=./popper.scss';
export var MPopperPlacement;
(function (MPopperPlacement) {
    MPopperPlacement["Top"] = "top";
    MPopperPlacement["TopStart"] = "top-start";
    MPopperPlacement["TopEnd"] = "top-end";
    MPopperPlacement["Right"] = "right";
    MPopperPlacement["RightStart"] = "right-start";
    MPopperPlacement["RightEnd"] = "right-end";
    MPopperPlacement["Bottom"] = "bottom";
    MPopperPlacement["BottomStart"] = "bottom-start";
    MPopperPlacement["BottomEnd"] = "bottom-end";
    MPopperPlacement["Left"] = "left";
    MPopperPlacement["LeftStart"] = "left-start";
    MPopperPlacement["LeftEnd"] = "left-end";
})(MPopperPlacement || (MPopperPlacement = {}));
var MPopper = /** @class */ (function (_super) {
    __extends(MPopper, _super);
    function MPopper() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.defaultAnimOpen = false;
        _this.internalOpen = false;
        _this.isHidden = false;
        return _this;
    }
    Object.defineProperty(MPopper.prototype, "popupBody", {
        get: function () {
            return this.$refs.body;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MPopper.prototype, "defaultAnimActive", {
        get: function () {
            return !(this.beforeEnter ||
                this.enter ||
                this.afterEnter ||
                this.beforeLeave ||
                this.leave ||
                this.afterLeave);
        },
        enumerable: false,
        configurable: true
    });
    MPopper.prototype.handlesFocus = function () {
        return this.focusManagement;
    };
    MPopper.prototype.getBackdropMode = function () {
        return BackdropMode.None;
    };
    MPopper.prototype.getPortalElement = function () {
        return this.$refs.popper;
    };
    MPopper.prototype.doCustomPropOpen = function (value, el) {
        var _this = this;
        if (value) {
            if (this.popper === undefined) {
                var options = {
                    placement: this.placement,
                    eventsEnabled: true,
                    onUpdate: function (data) {
                        _this.isHidden = data.hide;
                    },
                    modifiers: {
                        preventOverflow: {
                            boundariesElement: this.boundariesElement ? document.querySelector(this.boundariesElement) : 'window'
                        }
                    }
                };
                var reference = this.as().getTrigger();
                if (!reference) {
                    reference = document.getElementsByTagName('body')[0];
                }
                this.popper = new Popper(reference, el, options);
            }
            else {
                this.popper.update();
            }
        }
        return true;
    };
    MPopper.prototype.update = function () {
        if (this.popper !== undefined) {
            this.popper.scheduleUpdate();
        }
    };
    MPopper.prototype.onBeforeEnter = function (el) {
        if (this.beforeEnter) {
            this.beforeEnter(el.children[0]);
        }
    };
    MPopper.prototype.onEnter = function (el, done) {
        var _this = this;
        this.$nextTick(function () {
            _this.update();
            if (_this.enter) {
                _this.enter(el.children[0], done);
            }
            else {
                var transitionDuration = window.getComputedStyle(el).getPropertyValue('transition-duration').slice(1, -1) * 1000;
                setTimeout(function () {
                    _this.defaultAnimOpen = true;
                    done();
                }, transitionDuration);
            }
        });
    };
    MPopper.prototype.onAfterEnter = function (el) {
        if (this.afterEnter) {
            this.afterEnter(el.children[0]);
        }
        this.$emit('after-enter', el);
        this.as().setFocusToPortal();
    };
    MPopper.prototype.onEnterCancelled = function (el) {
        if (this.enterCancelled) {
            this.enterCancelled(el);
        }
    };
    MPopper.prototype.onBeforeLeave = function (el) {
        if (this.beforeLeave) {
            this.beforeLeave(el.children[0]);
        }
    };
    MPopper.prototype.onLeave = function (el, done) {
        if (this.leave) {
            this.leave(el.children[0], done);
        }
        else {
            this.defaultAnimOpen = false;
            setTimeout(done, 300);
        }
    };
    MPopper.prototype.onAfterLeave = function (el) {
        if (this.afterLeave) {
            this.afterLeave(el.children[0]);
        }
        this.as().setFocusToTrigger();
    };
    MPopper.prototype.onLeaveCancelled = function (el) {
        if (this.leaveCancelled) {
            this.leaveCancelled(el.children[0]);
        }
    };
    MPopper.prototype.mounted = function () {
        this.$modul.event.$on('updateAfterResize', this.update);
        // sometimes, the document.click event is stopped causing a menu to stay open, even if another menu has been clicked.
        // mouseup will always be caught even if click is stopped.
        document.addEventListener('mouseup', this.onDocumentClick);
        this.$on('portal-mounted', this.setPopperMutationObserver);
    };
    MPopper.prototype.beforeDestroy = function () {
        this.$modul.event.$off('updateAfterResize', this.update);
        document.removeEventListener('mouseup', this.onDocumentClick);
        if (this.observer) {
            this.observer.disconnect();
        }
        this.$off('portal-mounted', this.setPopperMutationObserver);
        this.destroyPopper();
    };
    MPopper.prototype.setPopperMutationObserver = function () {
        var _this = this;
        this.observer = new MutationObserver(function () {
            _this.update();
        });
        if (this.$refs.popper) {
            this.observer.observe(this.$refs.popper, { subtree: true, childList: true });
        }
    };
    MPopper.prototype.onDocumentClick = function (event) {
        if (this.as().propOpen) {
            var trigger = this.as().getTrigger();
            var element = this.as().getPortalElement();
            if (this.closeOnClickOutside
                && !(element && element.contains(event.target)
                    || this.$el.contains(event.target) ||
                    (trigger && trigger.contains(event.target)))) {
                this.as().propOpen = false;
            }
        }
    };
    MPopper.prototype.destroyPopper = function () {
        if (this.popper !== undefined) {
            this.popper.destroy();
            this.popper = undefined;
            this.isHidden = false;
        }
    };
    __decorate([
        Prop({
            default: MPopperPlacement.Bottom,
            validator: function (value) { return Enums.toValueArray(MPopperPlacement).includes(value); }
        })
    ], MPopper.prototype, "placement", void 0);
    __decorate([
        Prop({ default: true })
    ], MPopper.prototype, "closeOnClickOutside", void 0);
    __decorate([
        Prop({ default: true })
    ], MPopper.prototype, "focusManagement", void 0);
    __decorate([
        Prop({ default: true })
    ], MPopper.prototype, "shadow", void 0);
    __decorate([
        Prop({ default: false })
    ], MPopper.prototype, "padding", void 0);
    __decorate([
        Prop({ default: false })
    ], MPopper.prototype, "paddingHeader", void 0);
    __decorate([
        Prop({ default: false })
    ], MPopper.prototype, "paddingBody", void 0);
    __decorate([
        Prop({ default: false })
    ], MPopper.prototype, "paddingFooter", void 0);
    __decorate([
        Prop({ default: true })
    ], MPopper.prototype, "background", void 0);
    __decorate([
        Prop({
            default: 'auto',
            validator: function (value) {
                return REGEX_CSS_NUMBER_VALUE.test(value) || value === 'auto';
            }
        })
    ], MPopper.prototype, "width", void 0);
    __decorate([
        Prop()
    ], MPopper.prototype, "beforeEnter", void 0);
    __decorate([
        Prop()
    ], MPopper.prototype, "enter", void 0);
    __decorate([
        Prop()
    ], MPopper.prototype, "afterEnter", void 0);
    __decorate([
        Prop()
    ], MPopper.prototype, "enterCancelled", void 0);
    __decorate([
        Prop()
    ], MPopper.prototype, "beforeLeave", void 0);
    __decorate([
        Prop()
    ], MPopper.prototype, "leave", void 0);
    __decorate([
        Prop()
    ], MPopper.prototype, "afterLeave", void 0);
    __decorate([
        Prop()
    ], MPopper.prototype, "leaveCancelled", void 0);
    __decorate([
        Prop()
    ], MPopper.prototype, "boundariesElement", void 0);
    MPopper = __decorate([
        WithRender,
        Component({
            mixins: [Portal]
        })
    ], MPopper);
    return MPopper;
}(ModulVue));
export { MPopper };
var PopperPlugin = {
    install: function (v, options) {
        v.component(POPPER_NAME, MPopper);
    }
};
export default PopperPlugin;
//# sourceMappingURL=popper.js.map