281 lines
11 KiB
JavaScript
Raw Normal View History

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; };
// Styles
import '../../../src/stylus/components/_navigation-drawer.styl';
// Mixins
import Applicationable from '../../mixins/applicationable';
import Dependent from '../../mixins/dependent';
import Overlayable from '../../mixins/overlayable';
import SSRBootable from '../../mixins/ssr-bootable';
import Themeable from '../../mixins/themeable';
// Directives
import ClickOutside from '../../directives/click-outside';
import Resize from '../../directives/resize';
import Touch from '../../directives/touch';
// Utilities
import { convertToUnit } from '../../util/helpers';
import mixins from '../../util/mixins';
export default mixins(Applicationable('left', ['miniVariant', 'right', 'width']), Dependent, Overlayable, SSRBootable, Themeable
/* @vue/component */
).extend({
name: 'v-navigation-drawer',
directives: {
ClickOutside: ClickOutside,
Resize: Resize,
Touch: Touch
},
props: {
clipped: Boolean,
disableRouteWatcher: Boolean,
disableResizeWatcher: Boolean,
height: {
type: [Number, String],
default: '100%'
},
floating: Boolean,
miniVariant: Boolean,
miniVariantWidth: {
type: [Number, String],
default: 80
},
mobileBreakPoint: {
type: [Number, String],
default: 1264
},
permanent: Boolean,
right: Boolean,
stateless: Boolean,
temporary: Boolean,
touchless: Boolean,
width: {
type: [Number, String],
default: 300
},
value: { required: false }
},
data: function data() {
return {
isActive: false,
touchArea: {
left: 0,
right: 0
}
};
},
computed: {
/**
* Used for setting an app value from a dynamic
* property. Called from applicationable.js
*/
applicationProperty: function applicationProperty() {
return this.right ? 'right' : 'left';
},
calculatedTransform: function calculatedTransform() {
if (this.isActive) return 0;
return this.right ? this.calculatedWidth : -this.calculatedWidth;
},
calculatedWidth: function calculatedWidth() {
return parseInt(this.miniVariant ? this.miniVariantWidth : this.width);
},
classes: function classes() {
return _extends({
'v-navigation-drawer': true,
'v-navigation-drawer--absolute': this.absolute,
'v-navigation-drawer--clipped': this.clipped,
'v-navigation-drawer--close': !this.isActive,
'v-navigation-drawer--fixed': !this.absolute && (this.app || this.fixed),
'v-navigation-drawer--floating': this.floating,
'v-navigation-drawer--is-mobile': this.isMobile,
'v-navigation-drawer--mini-variant': this.miniVariant,
'v-navigation-drawer--open': this.isActive,
'v-navigation-drawer--right': this.right,
'v-navigation-drawer--temporary': this.temporary
}, this.themeClasses);
},
hasApp: function hasApp() {
return this.app && !this.isMobile && !this.temporary;
},
isMobile: function isMobile() {
return !this.stateless && !this.permanent && !this.temporary && this.$vuetify.breakpoint.width < parseInt(this.mobileBreakPoint, 10);
},
marginTop: function marginTop() {
if (!this.hasApp) return 0;
var marginTop = this.$vuetify.application.bar;
marginTop += this.clipped ? this.$vuetify.application.top : 0;
return marginTop;
},
maxHeight: function maxHeight() {
if (!this.hasApp) return null;
var maxHeight = this.$vuetify.application.bottom + this.$vuetify.application.footer + this.$vuetify.application.bar;
if (!this.clipped) return maxHeight;
return maxHeight + this.$vuetify.application.top;
},
reactsToClick: function reactsToClick() {
return !this.stateless && !this.permanent && (this.isMobile || this.temporary);
},
reactsToMobile: function reactsToMobile() {
return !this.disableResizeWatcher && !this.stateless && !this.permanent && !this.temporary;
},
reactsToRoute: function reactsToRoute() {
return !this.disableRouteWatcher && !this.stateless && (this.temporary || this.isMobile);
},
resizeIsDisabled: function resizeIsDisabled() {
return this.disableResizeWatcher || this.stateless;
},
showOverlay: function showOverlay() {
return this.isActive && (this.isMobile || this.temporary);
},
styles: function styles() {
var styles = {
height: convertToUnit(this.height),
marginTop: this.marginTop + 'px',
maxHeight: this.maxHeight != null ? 'calc(100% - ' + +this.maxHeight + 'px)' : undefined,
transform: 'translateX(' + this.calculatedTransform + 'px)',
width: this.calculatedWidth + 'px'
};
return styles;
}
},
watch: {
$route: function $route() {
if (this.reactsToRoute && this.closeConditional()) {
this.isActive = false;
}
},
isActive: function isActive(val) {
this.$emit('input', val);
this.callUpdate();
},
/**
* When mobile changes, adjust the active state
* only when there has been a previous value
*/
isMobile: function isMobile(val, prev) {
!val && this.isActive && !this.temporary && this.removeOverlay();
if (prev == null || this.resizeIsDisabled || !this.reactsToMobile) return;
this.isActive = !val;
this.callUpdate();
},
permanent: function permanent(val) {
// If enabling prop enable the drawer
if (val) {
this.isActive = true;
}
this.callUpdate();
},
showOverlay: function showOverlay(val) {
if (val) this.genOverlay();else this.removeOverlay();
},
temporary: function temporary() {
this.callUpdate();
},
value: function value(val) {
if (this.permanent) return;
// TODO: referring to this directly causes type errors
// all over the place for some reason
var _this = this;
if (val == null) return _this.init();
if (val !== this.isActive) this.isActive = val;
}
},
beforeMount: function beforeMount() {
this.init();
},
methods: {
calculateTouchArea: function calculateTouchArea() {
if (!this.$el.parentNode) return;
var parentRect = this.$el.parentNode.getBoundingClientRect();
this.touchArea = {
left: parentRect.left + 50,
right: parentRect.right - 50
};
},
closeConditional: function closeConditional() {
return this.isActive && this.reactsToClick;
},
genDirectives: function genDirectives() {
var _this2 = this;
var directives = [{
name: 'click-outside',
value: function value() {
return _this2.isActive = false;
},
args: {
closeConditional: this.closeConditional,
include: this.getOpenDependentElements
}
}];
!this.touchless && directives.push({
name: 'touch',
value: {
parent: true,
left: this.swipeLeft,
right: this.swipeRight
}
});
return directives;
},
/**
* Sets state before mount to avoid
* entry transitions in SSR
*/
init: function init() {
if (this.permanent) {
this.isActive = true;
} else if (this.stateless || this.value != null) {
this.isActive = this.value;
} else if (!this.temporary) {
this.isActive = !this.isMobile;
}
},
swipeRight: function swipeRight(e) {
if (this.isActive && !this.right) return;
this.calculateTouchArea();
if (Math.abs(e.touchendX - e.touchstartX) < 100) return;
if (!this.right && e.touchstartX <= this.touchArea.left) this.isActive = true;else if (this.right && this.isActive) this.isActive = false;
},
swipeLeft: function swipeLeft(e) {
if (this.isActive && this.right) return;
this.calculateTouchArea();
if (Math.abs(e.touchendX - e.touchstartX) < 100) return;
if (this.right && e.touchstartX >= this.touchArea.right) this.isActive = true;else if (!this.right && this.isActive) this.isActive = false;
},
/**
* Update the application layout
*/
updateApplication: function updateApplication() {
return !this.isActive || this.temporary || this.isMobile ? 0 : this.calculatedWidth;
}
},
render: function render(h) {
var _this3 = this;
var data = {
'class': this.classes,
style: this.styles,
directives: this.genDirectives(),
on: {
click: function click() {
if (!_this3.miniVariant) return;
_this3.$emit('update:miniVariant', false);
},
transitionend: function transitionend(e) {
if (e.target !== e.currentTarget) return;
_this3.$emit('transitionend', e);
// IE11 does not support new Event('resize')
var resizeEvent = document.createEvent('UIEvents');
resizeEvent.initUIEvent('resize', true, false, window, 0);
window.dispatchEvent(resizeEvent);
}
}
};
return h('aside', data, [this.$slots.default, h('div', { 'class': 'v-navigation-drawer__border' })]);
}
});
//# sourceMappingURL=VNavigationDrawer.js.map