// Styles import '../../src/stylus/components/_overlay.styl'; // Utilities import { keyCodes, addPassiveEventListener } from '../util/helpers'; // Types import Vue from 'vue'; /* @vue/component */ export default Vue.extend().extend({ name: 'overlayable', props: { hideOverlay: Boolean }, data: function data() { return { overlay: null, overlayOffset: 0, overlayTimeout: undefined, overlayTransitionDuration: 500 + 150 // transition + delay }; }, watch: { hideOverlay: function hideOverlay(value) { if (value) this.removeOverlay();else this.genOverlay(); } }, beforeDestroy: function beforeDestroy() { this.removeOverlay(); }, methods: { genOverlay: function genOverlay() { var _this = this; // If fn is called and timeout is active // or overlay already exists // cancel removal of overlay and re-add active if (!this.isActive || this.hideOverlay || this.isActive && this.overlayTimeout || this.overlay) { clearTimeout(this.overlayTimeout); return this.overlay && this.overlay.classList.add('v-overlay--active'); } this.overlay = document.createElement('div'); this.overlay.className = 'v-overlay'; if (this.absolute) this.overlay.className += ' v-overlay--absolute'; this.hideScroll(); var parent = this.absolute ? this.$el.parentNode : document.querySelector('[data-app]'); parent && parent.insertBefore(this.overlay, parent.firstChild); // eslint-disable-next-line no-unused-expressions this.overlay.clientHeight; // Force repaint requestAnimationFrame(function () { // https://github.com/vuetifyjs/vuetify/issues/4678 if (!_this.overlay) return; _this.overlay.className += ' v-overlay--active'; if (_this.activeZIndex !== undefined) { _this.overlay.style.zIndex = String(_this.activeZIndex - 1); } }); return true; }, /** removeOverlay(false) will not restore the scollbar afterwards */ removeOverlay: function removeOverlay() { var _this2 = this; var showScroll = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; if (!this.overlay) { return showScroll && this.showScroll(); } this.overlay.classList.remove('v-overlay--active'); this.overlayTimeout = window.setTimeout(function () { // IE11 Fix try { if (_this2.overlay && _this2.overlay.parentNode) { _this2.overlay.parentNode.removeChild(_this2.overlay); } _this2.overlay = null; showScroll && _this2.showScroll(); } catch (e) { console.log(e); } clearTimeout(_this2.overlayTimeout); _this2.overlayTimeout = undefined; }, this.overlayTransitionDuration); }, scrollListener: function scrollListener(e) { if (e.type === 'keydown') { if (['INPUT', 'TEXTAREA', 'SELECT'].includes(e.target.tagName) || // https://github.com/vuetifyjs/vuetify/issues/4715 e.target.isContentEditable) return; var up = [keyCodes.up, keyCodes.pageup]; var down = [keyCodes.down, keyCodes.pagedown]; if (up.includes(e.keyCode)) { e.deltaY = -1; } else if (down.includes(e.keyCode)) { e.deltaY = 1; } else { return; } } if (e.target === this.overlay || e.type !== 'keydown' && e.target === document.body || this.checkPath(e)) e.preventDefault(); }, hasScrollbar: function hasScrollbar(el) { if (!el || el.nodeType !== Node.ELEMENT_NODE) return false; var style = window.getComputedStyle(el); return ['auto', 'scroll'].includes(style.overflowY) && el.scrollHeight > el.clientHeight; }, shouldScroll: function shouldScroll(el, delta) { if (el.scrollTop === 0 && delta < 0) return true; return el.scrollTop + el.clientHeight === el.scrollHeight && delta > 0; }, isInside: function isInside(el, parent) { if (el === parent) { return true; } else if (el === null || el === document.body) { return false; } else { return this.isInside(el.parentNode, parent); } }, checkPath: function checkPath(e) { var path = e.path || this.composedPath(e); var delta = e.deltaY; if (e.type === 'keydown' && path[0] === document.body) { var dialog = this.$refs.dialog; var selected = window.getSelection().anchorNode; if (dialog && this.hasScrollbar(dialog) && this.isInside(selected, dialog)) { return this.shouldScroll(dialog, delta); } return true; } for (var index = 0; index < path.length; index++) { var el = path[index]; if (el === document) return true; if (el === document.documentElement) return true; if (el === this.$refs.content) return true; if (this.hasScrollbar(el)) return this.shouldScroll(el, delta); } return true; }, /** * Polyfill for Event.prototype.composedPath */ composedPath: function composedPath(e) { if (e.composedPath) return e.composedPath(); var path = []; var el = e.target; while (el) { path.push(el); if (el.tagName === 'HTML') { path.push(document); path.push(window); return path; } el = el.parentElement; } return path; }, hideScroll: function hideScroll() { if (this.$vuetify.breakpoint.smAndDown) { document.documentElement.classList.add('overflow-y-hidden'); } else { addPassiveEventListener(window, 'wheel', this.scrollListener, { passive: false }); window.addEventListener('keydown', this.scrollListener); } }, showScroll: function showScroll() { document.documentElement.classList.remove('overflow-y-hidden'); window.removeEventListener('wheel', this.scrollListener); window.removeEventListener('keydown', this.scrollListener); } } }); //# sourceMappingURL=overlayable.js.map