Replaced with the newer version

This commit is contained in:
euvl
2017-03-10 10:46:05 +00:00
parent 675e6cdcb7
commit c1913b0490
25 changed files with 802 additions and 432 deletions

250
Modal/Modal.vue Normal file
View File

@@ -0,0 +1,250 @@
<template>
<transition name="overlay-fade">
<div v-if="visibility.overlay"
class="nice-modal-overlay"
@mousedown.stop="toggle(false)">
<transition :name="transition">
<div v-if="visibility.modal"
v-bind:class="modalClass"
v-bind:style="modalStyle"
v-on:mousedown.stop
ref="modal">
<slot></slot>
<resizer v-if="resizable" @resize="resize"/>
</div>
</transition>
</div>
</transition>
</template>
<script>
import Vue from 'vue';
import Modal from './index';
import Resizer from './Resizer.vue';
export default {
name: 'Modal',
props: {
name: {
required: true,
type: [String, Number],
},
delay: {
type: Number,
default: 0,
},
resizable: {
type: Boolean,
default: false
},
adaptive: {
type: Boolean,
default: false
},
transition: {
type: String,
},
classes: {
type: [String, Array],
default: 'nice-modal',
},
width: {
type: Number,
default: 600
},
height: {
type: Number,
default: 300
},
minWidth: {
type: Number,
default: 0
},
minHeight: {
type: Number,
default: 0
}
},
components: {
Resizer
},
data() {
return {
visible: false,
visibility: {
modal: false,
overlay: false
},
modal: {
width: this.width,
height: this.height
},
window: {
width: window.innerWidth,
height: window.innerWidth
}
};
},
watch: {
visible(value) {
if (this.delay > 0) {
if (value) {
this.visibility.overlay = true;
setTimeout(() => this.visibility.modal = true, this.delay);
} else {
this.visibility.modal = false;
setTimeout(() => this.visibility.overlay = false, this.delay);
}
} else {
this.visibility.overlay = value;
Vue.nextTick(() => this.visibility.modal = value);
}
},
},
created() {
Modal.event.$on('toggle', (name, state, params) => {
if (name === this.name) {
this.toggle(!this.visible, params);
}
});
window.addEventListener('resize', this.onWindowResize);
},
beforeMount() {
this.onWindowResize();
},
computed: {
position() {
return {
left: (this.window.width - this.modal.width) / 2,
top: (this.window.height - this.modal.height) / 2
}
},
modalClass() {
return ['modal', this.classes];
},
modalStyle() {
return {
top: this.position.top + 'px',
left: this.position.left + 'px',
width: this.modal.width + 'px',
height: this.modal.height + 'px'
}
}
},
methods: {
onWindowResize() {
this.window.width = window.innerWidth;
this.window.height = window.innerHeight;
if (this.adaptive) {
this.modal.width = this.window.width > this.width
? this.width
: this.window.width
this.modal.height = this.window.height > this.height
? this.height
: this.window.height;
}
},
genEventObject(params) {
return Vue.util.extend(
{
name: this.name,
ref: this.$refs.modal,
timestamp: Date.now()
},
params || {});
},
resize(event) {
this.modal.width = event.size.width;
let resizeEvent = this.genEventObject({
size: this.modal
});
this.$emit('resize', resizeEvent);
},
toggle(state, params) {
const beforeEventName = this.visible ? 'before-close' : 'before-open';
const afterEventName = this.visible ? 'closed' : 'opened';
let stopEventExecution = false;
const beforeEvent = this.genEventObject({
stop: () => stopEventExecution = false,
state,
params
});
this.$emit(beforeEventName, beforeEvent);
if (!stopEventExecution) {
this.visible = !!state;
const afterEvent = this.genEventObject({
state,
params
});
this.$emit(afterEventName, afterEvent);
}
},
},
};
</script>
<style lang="scss" scoped>
.nice-modal-overlay {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.2);
z-index: 999;
opacity: 1;
.modal {
position: relative;
overflow: hidden;
box-sizing: border-box;
background-color: white;
}
}
.overlay-fade-enter-active, .overlay-fade-leave-active {
transition: all 0.2s;
}
.overlay-fade-enter, .overlay-fade-leave-active {
opacity: 0;
}
.nice-modal-fade-enter-active, .nice-modal-fade-leave-active {
transition: all 0.5s;
}
.nice-modal-fade-enter, .nice-modal-fade-leave-active {
opacity: 0;
transform: translateY(-20px);
}
.nice-modal {
background: white;
text-align: left;
border-radius: 3px;
box-shadow: 0 20px 60px -2px rgba(27, 33, 58, .4);
padding: 0;
&.nice-modal-fullscreen {
width: 100vw;
height: 100vh;
margin: 0;
left: 0;
top: 0;
}
}
</style>

0
Modal/README.md Normal file
View File

103
Modal/Resizer.vue Normal file
View File

@@ -0,0 +1,103 @@
<template>
<div :class="{'vue-modal-resizer': true, 'clicked': clicked}">
</div>
</template>
<script>
import util from '../util';
export default {
name: 'Resizer',
data() {
return {
clicked: false,
min: {
height: 50,
width: 0
},
size: {}
}
},
mounted() {
this.$el.addEventListener('mousedown', this.start, false);
},
methods: {
start(event) {
this.clicked = true;
window.addEventListener('mousemove', this.mousemove, false);
window.addEventListener('mouseup', this.stop, false);
util.stopEvent(event);
},
stop() {
this.clicked = false;
window.removeEventListener('mousemove', this.mousemove, false);
window.removeEventListener('mouseup', this.stop, false);
this.$emit('resize-stop', {
element: this.$el.parentElement,
size: this.size
});
},
mousemove(event) {
this.resize(event);
},
resize(event) {
var el = this.$el.parentElement;
if (event.clientX < window.innerWidth / 2) {
return;
}
if (el) {
var width = event.clientX - el.offsetLeft;
var height = event.clientY - el.offsetTop;
if (height < this.min.height) {
return;
}
this.size = {width, height};
el.style.width = width + 'px';
el.style.height = height + 'px';
this.$emit('resize', {
element: el,
size: this.size
});
}
}
}
}
</script>
<style lang="scss">
.vue-modal-resizer {
display: block;
overflow: hidden;
position: absolute;
width: 12px;
height: 12px;
right: 0;
bottom: 0;
z-index: 9999999;
background: transparent;
cursor: se-resize;
&:after {
display: block;
position: absolute;
content: '';
background: transparent;
left: 0;
top: 0;
width: 0;
height: 0;
border-bottom: 10px solid #ddd;
border-left: 10px solid transparent;
}
&.clicked:after {
border-bottom: 10px solid #369BE9;
}
}
</style>

30
Modal/index.js Normal file
View File

@@ -0,0 +1,30 @@
import Vue from 'vue';
import Modal from './Modal.vue';
const VueModal = {
install(Vue, options = {}) {
if (!this.hasOwnProperty("event")) {
this.event = new Vue();
}
const $modal = {
show(name, params) {
VueModal.event.$emit('toggle', name, true, params);
},
hide(name, params) {
VueModal.event.$emit('toggle', name, false, params);
}
};
Object.defineProperty(Vue.prototype, '$modal', {
get: () => $modal
});
Vue.component('nice-modal', Modal);
return null;
},
};
Vue.use(VueModal);
export default VueModal;