"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; require("../../../src/components/VMenu/VMenu.sass"); var _delayable = _interopRequireDefault(require("../../mixins/delayable")); var _dependent = _interopRequireDefault(require("../../mixins/dependent")); var _detachable = _interopRequireDefault(require("../../mixins/detachable")); var _menuable = _interopRequireDefault(require("../../mixins/menuable")); var _returnable = _interopRequireDefault(require("../../mixins/returnable")); var _toggleable = _interopRequireDefault(require("../../mixins/toggleable")); var _themeable = _interopRequireDefault(require("../../mixins/themeable")); var _clickOutside = _interopRequireDefault(require("../../directives/click-outside")); var _resize = _interopRequireDefault(require("../../directives/resize")); var _mixins = _interopRequireDefault(require("../../util/mixins")); var _helpers = require("../../util/helpers"); var _ThemeProvider = _interopRequireDefault(require("../../util/ThemeProvider")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(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) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } } var baseMixins = (0, _mixins.default)(_dependent.default, _delayable.default, _detachable.default, _menuable.default, _returnable.default, _toggleable.default, _themeable.default); /* @vue/component */ var _default = baseMixins.extend({ name: 'v-menu', provide: function provide() { return { isInMenu: true, // Pass theme through to default slot theme: this.theme }; }, directives: { ClickOutside: _clickOutside.default, Resize: _resize.default }, 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' }, offsetX: Boolean, offsetY: Boolean, openOnClick: { type: Boolean, default: true }, 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: { activeTile: function activeTile() { return this.tiles[this.listIndex]; }, calculatedLeft: function calculatedLeft() { var menuWidth = Math.max(this.dimensions.content.width, parseFloat(this.calculatedMinWidth)); if (!this.auto) return this.calcLeft(menuWidth) || '0'; return (0, _helpers.convertToUnit)(this.calcXOverflow(this.calcLeftAuto(), menuWidth)) || '0'; }, calculatedMaxHeight: function calculatedMaxHeight() { var height = this.auto ? '200px' : (0, _helpers.convertToUnit)(this.maxHeight); return height || '0'; }, calculatedMaxWidth: function calculatedMaxWidth() { return (0, _helpers.convertToUnit)(this.maxWidth) || '0'; }, calculatedMinWidth: function calculatedMinWidth() { if (this.minWidth) { return (0, _helpers.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 (0, _helpers.convertToUnit)(Math.min(calculatedMaxWidth, minWidth)) || '0'; }, calculatedTop: function calculatedTop() { var top = !this.auto ? this.calcTop() : (0, _helpers.convertToUnit)(this.calcYOverflow(this.calculatedTopAuto)); return top || '0'; }, hasClickableTiles: function hasClickableTiles() { return Boolean(this.tiles.find(function (tile) { return tile.tabIndex > -1; })); }, 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.callActivate(); }, methods: { activate: function activate() { var _this = this; // 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 (!this.isActive || !this.hasClickableTiles) { return; } else if (e.keyCode === _helpers.keyCodes.tab) { this.isActive = false; return; } else if (e.keyCode === _helpers.keyCodes.down) { this.nextTile(); } else if (e.keyCode === _helpers.keyCodes.up) { this.prevTile(); } else if (e.keyCode === _helpers.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); }, genActivatorListeners: function genActivatorListeners() { var listeners = _menuable.default.options.methods.genActivatorListeners.call(this); if (!this.disableKeys) { listeners.keydown = this.onKeyDown; } return listeners; }, 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: _objectSpread({}, this.getScopeIdAttrs(), { role: 'role' in this.$attrs ? this.$attrs.role : 'menu' }), staticClass: 'v-menu__content', class: _objectSpread({}, 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(); }); }); }, nextTile: function nextTile() { var tile = this.tiles[this.listIndex + 1]; if (!tile) { if (!this.tiles.length) return; this.listIndex = -1; this.nextTile(); return; } this.listIndex++; if (tile.tabIndex === -1) this.nextTile(); }, prevTile: function prevTile() { var tile = this.tiles[this.listIndex - 1]; if (!tile) { if (!this.tiles.length) return; this.listIndex = this.tiles.length; this.prevTile(); return; } this.listIndex--; if (tile.tabIndex === -1) this.prevTile(); }, onKeyDown: function onKeyDown(e) { var _this6 = this; if (e.keyCode === _helpers.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 (!this.isActive && [_helpers.keyCodes.up, _helpers.keyCodes.down].includes(e.keyCode)) { this.isActive = true; } // Allow for isActive watcher to generate tile list this.$nextTick(function () { return _this6.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 }] }; return h('div', data, [this.genActivator(), this.$createElement(_ThemeProvider.default, { props: { root: true, light: this.light, dark: this.dark } }, [this.genTransition()])]); } }); exports.default = _default; //# sourceMappingURL=VMenu.js.map