vue-material/src/components/mdDialog/mdDialog.vue
2016-11-17 03:05:25 -02:00

125 lines
3.6 KiB
Vue

<template>
<div class="md-dialog-container" :class="classes" @keyup.esc="mdEscToClose && close()" tabindex="0">
<div class="md-dialog" ref="dialog" :style="styles" :class="dialogClasses">
<slot></slot>
</div>
<md-backdrop class="md-dialog-backdrop" :class="classes" v-if="mdBackdrop" ref="backdrop" @close="mdClickOutsideToClose && close()"></md-backdrop>
</div>
</template>
<style lang="scss" src="./mdDialog.scss"></style>
<script>
import transitionEndEventName from '../../core/utils/transitionEndEventName';
export default {
props: {
mdClickOutsideToClose: {
type: Boolean,
default: true
},
mdEscToClose: {
type: Boolean,
default: true
},
mdBackdrop: {
type: Boolean,
default: true
},
mdOpenFrom: String,
mdCloseTo: String,
mdFullscreen: {
type: Boolean,
default: false
}
},
data: () => ({
active: false,
transitionOff: false,
dialogTransform: '',
dialogTransformOrigin: ''
}),
computed: {
classes() {
return {
'md-fullscreen': this.mdFullscreen,
'md-active': this.active
};
},
dialogClasses() {
return {
'md-transition-off': this.transitionOff
};
},
styles() {
return {
transform: this.dialogTransform,
'transform-origin': this.dialogTransformOrigin
};
}
},
methods: {
removeDialog() {
this.$el.parentNode.removeChild(this.$el);
},
calculateDialogPos(ref) {
const reference = document.querySelector(ref);
if (reference) {
const openFromRect = reference.getBoundingClientRect();
const dialogRect = this.dialogInnerElement.getBoundingClientRect();
const topDistance = dialogRect.top - openFromRect.top;
const leftDistance = dialogRect.left - openFromRect.left;
const widthInScale = openFromRect.width / dialogRect.width;
const heightInScale = openFromRect.height / dialogRect.height;
this.dialogTransform = `translate3D(-${leftDistance}px, -${topDistance}px, 0) scale(${widthInScale}, ${heightInScale})`;
this.dialogTransformOrigin = 'top left';
}
},
open() {
this.$root.$el.appendChild(this.dialogElement);
this.transitionOff = true;
this.calculateDialogPos(this.mdOpenFrom);
window.setTimeout(() => {
this.dialogElement.focus();
this.transitionOff = false;
this.active = true;
});
},
close() {
if (this.$root.$el.contains(this.dialogElement)) {
let cleanElement = () => {
this.dialogInnerElement.removeEventListener(transitionEndEventName, cleanElement);
this.$root.$el.removeChild(this.dialogElement);
this.dialogTransform = '';
this.dialogTransformOrigin = '';
};
this.dialogTransform = '';
this.dialogTransformOrigin = '';
this.calculateDialogPos(this.mdCloseTo);
window.setTimeout(() => {
this.active = false;
this.dialogInnerElement.addEventListener(transitionEndEventName, cleanElement);
});
}
}
},
mounted() {
this.$nextTick(() => {
this.rootElement = this.$root.$el;
this.dialogElement = this.$el;
this.dialogInnerElement = this.$refs.dialog;
this.removeDialog();
});
},
beforeDestroy() {
this.removeDialog();
}
};
</script>