var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

// Styles
import '../../../src/components/VMenu/VMenu.sass';
// Mixins
import Delayable from '../../mixins/delayable';
import Dependent from '../../mixins/dependent';
import Detachable from '../../mixins/detachable';
import Menuable from '../../mixins/menuable';
import Returnable from '../../mixins/returnable';
import Toggleable from '../../mixins/toggleable';
import Themeable from '../../mixins/themeable';
// Directives
import ClickOutside from '../../directives/click-outside';
import Resize from '../../directives/resize';
// Utilities
import mixins from '../../util/mixins';
import { convertToUnit, keyCodes } from '../../util/helpers';
import ThemeProvider from '../../util/ThemeProvider';
var baseMixins = mixins(Dependent, Delayable, Detachable, Menuable, Returnable, Toggleable, Themeable);
/* @vue/component */
export default baseMixins.extend({
    name: 'v-menu',
    provide: function provide() {
        return {
            // Pass theme through to default slot
            theme: this.theme
        };
    },

    directives: {
        ClickOutside: ClickOutside,
        Resize: Resize
    },
    props: {
        auto: Boolean,
        closeOnClick: {
            type: Boolean,
            default: true
        },
        closeOnContentClick: {
            type: Boolean,
            default: true
        },
        disabled: Boolean,
        disableKeys: Boolean,
        fullWidth: Boolean,
        maxHeight: {
            type: [Number, String],
            default: 'auto'
        },
        openOnClick: {
            type: Boolean,
            default: true
        },
        offsetX: Boolean,
        offsetY: Boolean,
        openOnHover: Boolean,
        origin: {
            type: String,
            default: 'top left'
        },
        transition: {
            type: [Boolean, String],
            default: 'v-menu-transition'
        }
    },
    data: function data() {
        return {
            calculatedTopAuto: 0,
            defaultOffset: 8,
            hasJustFocused: false,
            listIndex: -1,
            resizeTimeout: 0,
            selectedIndex: null,
            tiles: []
        };
    },

    computed: {
        calculatedLeft: function calculatedLeft() {
            var menuWidth = Math.max(this.dimensions.content.width, parseFloat(this.calculatedMinWidth));
            if (!this.auto) return this.calcLeft(menuWidth) || '0';
            return convertToUnit(this.calcXOverflow(this.calcLeftAuto(), menuWidth)) || '0';
        },
        calculatedMaxHeight: function calculatedMaxHeight() {
            var height = this.auto ? '200px' : convertToUnit(this.maxHeight);
            return height || '0';
        },
        calculatedMaxWidth: function calculatedMaxWidth() {
            return convertToUnit(this.maxWidth) || '0';
        },
        calculatedMinWidth: function calculatedMinWidth() {
            if (this.minWidth) {
                return convertToUnit(this.minWidth) || '0';
            }
            var minWidth = Math.min(this.dimensions.activator.width + Number(this.nudgeWidth) + (this.auto ? 16 : 0), Math.max(this.pageWidth - 24, 0));
            var calculatedMaxWidth = isNaN(parseInt(this.calculatedMaxWidth)) ? minWidth : parseInt(this.calculatedMaxWidth);
            return convertToUnit(Math.min(calculatedMaxWidth, minWidth)) || '0';
        },
        calculatedTop: function calculatedTop() {
            var top = !this.auto ? this.calcTop() : convertToUnit(this.calcYOverflow(this.calculatedTopAuto));
            return top || '0';
        },
        styles: function styles() {
            return {
                maxHeight: this.calculatedMaxHeight,
                minWidth: this.calculatedMinWidth,
                maxWidth: this.calculatedMaxWidth,
                top: this.calculatedTop,
                left: this.calculatedLeft,
                transformOrigin: this.origin,
                zIndex: this.zIndex || this.activeZIndex
            };
        }
    },
    watch: {
        isActive: function isActive(val) {
            if (!val) this.listIndex = -1;
        },
        isContentActive: function isContentActive(val) {
            this.hasJustFocused = val;
        },
        listIndex: function listIndex(next, prev) {
            if (next in this.tiles) {
                var tile = this.tiles[next];
                tile.classList.add('v-list-item--highlighted');
                this.$refs.content.scrollTop = tile.offsetTop - tile.clientHeight;
            }
            prev in this.tiles && this.tiles[prev].classList.remove('v-list-item--highlighted');
        }
    },
    mounted: function mounted() {
        this.isActive && this.activate();
    },

    methods: {
        activate: function activate() {
            var _this = this;

            // This exists primarily for v-select
            // helps determine which tiles to activate
            this.getTiles();
            // Update coordinates and dimensions of menu
            // and its activator
            this.updateDimensions();
            // Start the transition
            requestAnimationFrame(function () {
                // Once transitioning, calculate scroll and top position
                _this.startTransition().then(function () {
                    if (_this.$refs.content) {
                        _this.calculatedTopAuto = _this.calcTopAuto();
                        _this.auto && (_this.$refs.content.scrollTop = _this.calcScrollPosition());
                    }
                });
            });
        },
        calcScrollPosition: function calcScrollPosition() {
            var $el = this.$refs.content;
            var activeTile = $el.querySelector('.v-list-item--active');
            var maxScrollTop = $el.scrollHeight - $el.offsetHeight;
            return activeTile ? Math.min(maxScrollTop, Math.max(0, activeTile.offsetTop - $el.offsetHeight / 2 + activeTile.offsetHeight / 2)) : $el.scrollTop;
        },
        calcLeftAuto: function calcLeftAuto() {
            return parseInt(this.dimensions.activator.left - this.defaultOffset * 2);
        },
        calcTopAuto: function calcTopAuto() {
            var $el = this.$refs.content;
            var activeTile = $el.querySelector('.v-list-item--active');
            if (!activeTile) {
                this.selectedIndex = null;
            }
            if (this.offsetY || !activeTile) {
                return this.computedTop;
            }
            this.selectedIndex = Array.from(this.tiles).indexOf(activeTile);
            var tileDistanceFromMenuTop = activeTile.offsetTop - this.calcScrollPosition();
            var firstTileOffsetTop = $el.querySelector('.v-list-item').offsetTop;
            return this.computedTop - tileDistanceFromMenuTop - firstTileOffsetTop - 1;
        },
        changeListIndex: function changeListIndex(e) {
            // For infinite scroll and autocomplete, re-evaluate children
            this.getTiles();
            if (e.keyCode === keyCodes.down && this.listIndex < this.tiles.length - 1) {
                this.listIndex++;
                // Allow user to set listIndex to -1 so
                // that the list can be un-highlighted
            } else if (e.keyCode === keyCodes.up && this.listIndex > -1) {
                this.listIndex--;
            } else if (e.keyCode === keyCodes.enter && this.listIndex !== -1) {
                this.tiles[this.listIndex].click();
            } else {
                return;
            }
            // One of the conditions was met, prevent default action (#2988)
            e.preventDefault();
        },
        closeConditional: function closeConditional(e) {
            var target = e.target;
            return this.isActive && this.closeOnClick && !this.$refs.content.contains(target);
        },
        genTransition: function genTransition() {
            if (!this.transition) return this.genContent();
            return this.$createElement('transition', {
                props: {
                    name: this.transition
                }
            }, [this.genContent()]);
        },
        genDirectives: function genDirectives() {
            var _this2 = this;

            var directives = [{
                name: 'show',
                value: this.isContentActive
            }];
            // Do not add click outside for hover menu
            if (!this.openOnHover && this.closeOnClick) {
                directives.push({
                    name: 'click-outside',
                    value: function value() {
                        _this2.isActive = false;
                    },
                    args: {
                        closeConditional: this.closeConditional,
                        include: function include() {
                            return [_this2.$el].concat(_toConsumableArray(_this2.getOpenDependentElements()));
                        }
                    }
                });
            }
            return directives;
        },
        genContent: function genContent() {
            var _this3 = this;

            var options = {
                attrs: this.getScopeIdAttrs(),
                staticClass: 'v-menu__content',
                'class': _extends({}, this.rootThemeClasses, _defineProperty({
                    'v-menu__content--auto': this.auto,
                    'v-menu__content--fixed': this.activatorFixed,
                    'menuable__content__active': this.isActive
                }, this.contentClass.trim(), true)),
                style: this.styles,
                directives: this.genDirectives(),
                ref: 'content',
                on: {
                    click: function click(e) {
                        e.stopPropagation();
                        var target = e.target;
                        if (target.getAttribute('disabled')) return;
                        if (_this3.closeOnContentClick) _this3.isActive = false;
                    },
                    keydown: this.onKeyDown
                }
            };
            if (!this.disabled && this.openOnHover) {
                options.on = options.on || {};
                options.on.mouseenter = this.mouseEnterHandler;
            }
            if (this.openOnHover) {
                options.on = options.on || {};
                options.on.mouseleave = this.mouseLeaveHandler;
            }
            return this.$createElement('div', options, this.showLazyContent(this.getContentSlot()));
        },
        getTiles: function getTiles() {
            this.tiles = Array.from(this.$refs.content.querySelectorAll('.v-list-item'));
        },
        mouseEnterHandler: function mouseEnterHandler() {
            var _this4 = this;

            this.runDelay('open', function () {
                if (_this4.hasJustFocused) return;
                _this4.hasJustFocused = true;
                _this4.isActive = true;
            });
        },
        mouseLeaveHandler: function mouseLeaveHandler(e) {
            var _this5 = this;

            // Prevent accidental re-activation
            this.runDelay('close', function () {
                if (_this5.$refs.content.contains(e.relatedTarget)) return;
                requestAnimationFrame(function () {
                    _this5.isActive = false;
                    _this5.callDeactivate();
                });
            });
        },
        onKeyDown: function onKeyDown(e) {
            var _this6 = this;

            if (e.keyCode === keyCodes.esc) {
                // Wait for dependent elements to close first
                setTimeout(function () {
                    _this6.isActive = false;
                });
                var activator = this.getActivator();
                this.$nextTick(function () {
                    return activator && activator.focus();
                });
            } else if (e.keyCode === keyCodes.tab) {
                setTimeout(function () {
                    if (!_this6.$refs.content.contains(document.activeElement)) {
                        _this6.isActive = false;
                    }
                });
            } else {
                this.changeListIndex(e);
            }
        },
        onResize: function onResize() {
            if (!this.isActive) return;
            // Account for screen resize
            // and orientation change
            // eslint-disable-next-line no-unused-expressions
            this.$refs.content.offsetWidth;
            this.updateDimensions();
            // When resizing to a smaller width
            // content width is evaluated before
            // the new activator width has been
            // set, causing it to not size properly
            // hacky but will revisit in the future
            clearTimeout(this.resizeTimeout);
            this.resizeTimeout = window.setTimeout(this.updateDimensions, 100);
        }
    },
    render: function render(h) {
        var data = {
            staticClass: 'v-menu',
            class: {
                'v-menu--inline': !this.fullWidth && (this.$slots.activator || this.$scopedSlots.activator)
            },
            directives: [{
                arg: '500',
                name: 'resize',
                value: this.onResize
            }],
            on: this.disableKeys ? undefined : {
                keydown: this.onKeyDown
            }
        };
        return h('div', data, [this.genActivator(), this.$createElement(ThemeProvider, {
            props: {
                root: true,
                light: this.light,
                dark: this.dark
            }
        }, [this.genTransition()])]);
    }
});
//# sourceMappingURL=VMenu.js.map