mirror of
https://github.com/Hopiu/vue-material.git
synced 2026-05-17 19:51:06 +00:00
125 lines
3.6 KiB
Vue
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>
|