This commit is contained in:
syuilo 2020-09-06 10:04:26 +09:00
parent 43069f856a
commit b31caeb7ca
3 changed files with 28 additions and 153 deletions

View File

@ -113,6 +113,9 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
.rrevdjwt { .rrevdjwt {
padding: 8px 0; padding: 8px 0;
background: var(--panel);
border-radius: 8px;
box-shadow: 0 3px 12px rgba(27, 31, 35, 0.15);
&.left { &.left {
> .item { > .item {

View File

@ -3,7 +3,7 @@
<transition :name="$store.state.device.animation ? 'bg-fade' : ''" appear> <transition :name="$store.state.device.animation ? 'bg-fade' : ''" appear>
<div class="bg _modalBg" v-if="showing" @click="$emit('click')"></div> <div class="bg _modalBg" v-if="showing" @click="$emit('click')"></div>
</transition> </transition>
<div class="content" @click.self="$emit('click')"> <div class="content" :class="{ popup, fixed }" @click.self="$emit('click')" ref="content">
<transition :name="$store.state.device.animation ? 'modal' : ''" appear @after-leave="$emit('closed')"> <transition :name="$store.state.device.animation ? 'modal' : ''" appear @after-leave="$emit('closed')">
<slot v-if="showing"></slot> <slot v-if="showing"></slot>
</transition> </transition>
@ -28,16 +28,29 @@ export default defineComponent({
required: false, required: false,
default: true, default: true,
}, },
sourceEl: { // TODO:
noCenter: {
type: Boolean,
required: false
},
source: {
required: false, required: false,
} }
}, },
data() {
return {
fixed: false,
};
},
computed: { computed: {
keymap(): any { keymap(): any {
return { return {
'esc': () => this.$emit('esc'), 'esc': () => this.$emit('esc'),
}; };
}, },
popup(): boolean {
return this.source != null;
}
}, },
mounted() { mounted() {
this.$nextTick(() => { this.$nextTick(() => {
@ -122,7 +135,7 @@ export default defineComponent({
z-index: 10000; z-index: 10000;
} }
> .content { > .content:not(.popup) {
position: fixed; position: fixed;
z-index: 10000; z-index: 10000;
top: 0; top: 0;
@ -137,5 +150,14 @@ export default defineComponent({
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
> .content.popup {
position: absolute;
z-index: 10000;
&.fixed {
position: fixed;
}
}
} }
</style> </style>

View File

@ -1,150 +0,0 @@
// popupmodal
<template>
<div class="mk-popup" v-hotkey.global="keymap">
<transition :name="$store.state.device.animation ? 'bg-fade' : ''" appear>
<div class="bg _modalBg" ref="bg" @click="close()" v-if="show"></div>
</transition>
<transition :name="$store.state.device.animation ? 'popup' : ''" appear @after-leave="() => { $emit('closed'); destroyDom(); }">
<div class="content" :class="{ fixed }" ref="content" v-if="show" :style="{ width: width ? width + 'px' : 'auto' }"><slot></slot></div>
</transition>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
props: {
source: {
required: true
},
noCenter: {
type: Boolean,
required: false
},
fixed: {
type: Boolean,
required: false
},
width: {
type: Number,
required: false
}
},
data() {
return {
show: true,
};
},
computed: {
keymap(): any {
return {
'esc': this.close,
};
},
},
mounted() {
this.$nextTick(() => {
const popover = this.$refs.content as any;
const rect = this.source.getBoundingClientRect();
const width = popover.offsetWidth;
const height = popover.offsetHeight;
let left;
let top;
if (this.$root.isMobile && !this.noCenter) {
const x = rect.left + (this.fixed ? 0 : window.pageXOffset) + (this.source.offsetWidth / 2);
const y = rect.top + (this.fixed ? 0 : window.pageYOffset) + (this.source.offsetHeight / 2);
left = (x - (width / 2));
top = (y - (height / 2));
popover.style.transformOrigin = 'center';
} else {
const x = rect.left + (this.fixed ? 0 : window.pageXOffset) + (this.source.offsetWidth / 2);
const y = rect.top + (this.fixed ? 0 : window.pageYOffset) + this.source.offsetHeight;
left = (x - (width / 2));
top = y;
}
if (this.fixed) {
if (left + width > window.innerWidth) {
left = window.innerWidth - width;
popover.style.transformOrigin = 'center';
}
if (top + height > window.innerHeight) {
top = window.innerHeight - height;
popover.style.transformOrigin = 'center';
}
} else {
if (left + width - window.pageXOffset > window.innerWidth) {
left = window.innerWidth - width + window.pageXOffset;
popover.style.transformOrigin = 'center';
}
if (top + height - window.pageYOffset > window.innerHeight) {
top = window.innerHeight - height + window.pageYOffset;
popover.style.transformOrigin = 'center';
}
}
if (top < 0) {
top = 0;
}
if (left < 0) {
left = 0;
}
popover.style.left = left + 'px';
popover.style.top = top + 'px';
});
},
methods: {
close() {
this.show = false;
if (this.$refs.bg) (this.$refs.bg as any).style.pointerEvents = 'none';
if (this.$refs.content) (this.$refs.content as any).style.pointerEvents = 'none';
}
}
});
</script>
<style lang="scss" scoped>
.popup-enter-active, .popup-leave-active {
transition: opacity 0.3s, transform 0.3s !important;
}
.popup-enter, .popup-leave-to {
opacity: 0;
transform: scale(0.9);
}
.bg-fade-enter-active, .bg-fade-leave-active {
transition: opacity 0.3s !important;
}
.bg-fade-enter, .bg-fade-leave-to {
opacity: 0;
}
.mk-popup {
> .bg {
z-index: 10000;
}
> .content {
position: absolute;
z-index: 10001;
background: var(--panel);
border-radius: 8px;
box-shadow: 0 3px 12px rgba(27, 31, 35, 0.15);
overflow: hidden;
transform-origin: center top;
&.fixed {
position: fixed;
}
}
}
</style>