You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
223 lines
4.7 KiB
223 lines
4.7 KiB
<template>
|
|
<Teleport>
|
|
<Transition name="fade">
|
|
<div :class="['mask-layer', { 'none-mask': noneMask }]" v-if="modelVisible">
|
|
<BackgroundClip class="dialog"
|
|
clipPath="polygon(calc(100% - var(--clip-width)) 0, 100% var(--clip-width), 100% 100%, var(--clip-width) 100%, 0 calc(100% - var(--clip-width)), 0 0)"
|
|
borderColor="linear-gradient(180deg, rgba(78, 174, 204, .9), rgba(78, 174, 204, 0))"
|
|
bgColor="linear-gradient(180deg, rgba(14, 69, 92, 0.9) 0%, rgba(20, 89, 119, 0.9) 100%)"
|
|
ref="DialogContentRef" :width="width" :top="top" :right="right">
|
|
<div class="dialog-title">
|
|
<img class="title-icon" src="@screen/images/dialog/title-icon.svg" />
|
|
<span>{{ title }}</span>
|
|
<img class="icon-close" @click.stop="modelVisible = false" src="@screen/images/dialog/icon-close.svg" />
|
|
</div>
|
|
|
|
<div class="dialog-content">
|
|
<slot />
|
|
</div>
|
|
|
|
<img class="bottom-right" src="@screen/images/dialog/right-bottom.svg" />
|
|
|
|
<div class="footer" v-if="$slots.footer">
|
|
<slot name="footer"></slot>
|
|
</div>
|
|
</BackgroundClip>
|
|
</div>
|
|
</Transition>
|
|
</Teleport>
|
|
</template>
|
|
|
|
<script>
|
|
import Teleport from "../Teleport.vue";
|
|
import BackgroundClip from "@screen/components/Decorations/BackgroundClip.vue";
|
|
import { moveable, stopPropagation } from "./utils";
|
|
|
|
export default {
|
|
components: {
|
|
Teleport,
|
|
BackgroundClip,
|
|
},
|
|
model: {
|
|
prop: "visible",
|
|
event: "update:value",
|
|
},
|
|
name: "Dialog",
|
|
props: {
|
|
width: {
|
|
type: String,
|
|
default: null,
|
|
},
|
|
top: {
|
|
type: String,
|
|
default: null,
|
|
},
|
|
right: {
|
|
type: String,
|
|
default: null,
|
|
},
|
|
title: {
|
|
type: String,
|
|
},
|
|
visible: Boolean,
|
|
noneMask: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
},
|
|
watch: {
|
|
visible: {
|
|
deep: true,
|
|
handler(bool) {
|
|
this.$nextTick(() => {
|
|
if (!bool) return this.destroyMoveable?.();
|
|
|
|
const container = this.$refs.DialogContentRef.$el;
|
|
|
|
this.destroyMoveable = moveable(container, {
|
|
target: container.querySelector(".dialog-title"),
|
|
});
|
|
|
|
stopPropagation(container.querySelector(".dialog-title").lastChild);
|
|
|
|
this.$once("hook:beforeDestroy", () => this.destroyMoveable?.());
|
|
});
|
|
},
|
|
},
|
|
},
|
|
methods: {
|
|
updateDialogVisible(bool) {
|
|
this.modelVisible = bool;
|
|
},
|
|
},
|
|
mounted() {
|
|
this.emitter.on("updateDialogVisible", this.updateDialogVisible);
|
|
},
|
|
computed: {
|
|
modelVisible: {
|
|
get() {
|
|
return this.visible;
|
|
},
|
|
set(val) {
|
|
this.$emit("update:value", val);
|
|
},
|
|
},
|
|
},
|
|
beforeDestroy() {
|
|
this.modelVisible = false;
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.mask-layer {
|
|
position: fixed;
|
|
top: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: rgba(0, 0, 0, 0.36);
|
|
border-radius: 0px 0px 0px 0px;
|
|
z-index: 1100;
|
|
// display: flex;
|
|
// align-items: center;
|
|
// justify-content: center;
|
|
|
|
--border-width: 1px;
|
|
--clip-width-num: 24;
|
|
--clip-width: calc(var(--clip-width-num) * 1px);
|
|
}
|
|
|
|
.none-mask {
|
|
background: rgba(0, 0, 0, 0);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.fade-enter-active,
|
|
.fade-leave-active {
|
|
transition: opacity 0.24s;
|
|
}
|
|
|
|
.fade-enter,
|
|
.fade-leave-to {
|
|
opacity: 0;
|
|
}
|
|
|
|
.dialog {
|
|
max-width: 72vw;
|
|
opacity: 1;
|
|
background-clip: padding-box;
|
|
position: relative;
|
|
box-sizing: border-box;
|
|
top: 20%;
|
|
// margin: auto;
|
|
padding-bottom: 20px;
|
|
// margin: calc(var(--border-width) / 2);
|
|
|
|
pointer-events: all;
|
|
|
|
.dialog-title {
|
|
position: relative;
|
|
width: calc(100% - 2px);
|
|
height: 51px;
|
|
display: flex;
|
|
padding-top: 3px;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
background: linear-gradient(90deg, #267494 0%, rgba(38, 116, 148, 0) 100%);
|
|
font-size: 19px;
|
|
font-family: PingFang SC, PingFang SC;
|
|
font-weight: 500;
|
|
color: #3de8ff;
|
|
|
|
.title-icon {
|
|
position: absolute;
|
|
top: -1px;
|
|
left: -1px;
|
|
height: 6px;
|
|
}
|
|
|
|
.icon-close {
|
|
cursor: pointer;
|
|
margin-right: 21px;
|
|
}
|
|
|
|
span {
|
|
margin-left: 20px;
|
|
height: 48px;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
}
|
|
|
|
.dialog-content {
|
|
padding: 9px 21px 27px 21px;
|
|
max-height: 75vh;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.bottom-right {
|
|
position: absolute;
|
|
right: 0;
|
|
bottom: 0;
|
|
}
|
|
|
|
.footer {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 9px;
|
|
width: 100%;
|
|
justify-content: flex-end;
|
|
margin-bottom: 21px;
|
|
padding: 0 27px;
|
|
|
|
::v-deep {
|
|
>div {
|
|
min-width: 96px;
|
|
}
|
|
}
|
|
|
|
// padding: 21px 36px;
|
|
// padding-top: 9px;
|
|
}
|
|
}
|
|
</style>
|
|
|