refactor: mount modal to body node

Signed-off-by: Ryan Wang <i@ryanc.cc>
pull/581/head
Ryan Wang 2022-04-27 11:21:38 +08:00
parent 8df46e45f2
commit c39e13350e
3 changed files with 59 additions and 36 deletions

View File

@ -5,17 +5,35 @@ import { VModal } from "@/components/base/modal";
function initState() { function initState() {
return { return {
visible: false, visible: false,
fullscreen: false,
width: 500,
title: "测试",
}; };
} }
</script> </script>
<template> <template>
<Story title="Modal" :init-state="initState"> <Story :init-state="initState" title="Modal">
<template #default="{ state }"> <template #default="{ state }">
<VButton type="secondary" @click="state.visible = true">打开</VButton> <VButton type="secondary" @click="state.visible = true">打开</VButton>
<VModal v-model:visible="state.visible" title="测试"> <VModal
Hello World v-model:visible="state.visible"
:fullscreen="state.fullscreen"
:title="state.title"
:width="state.width"
>
<div class="flex flex-col">
<img src="https://ryanc.cc/avatar" class="w-full" />
<img src="https://ryanc.cc/avatar" class="w-full" />
<img src="https://halo.run/logo" class="w-full" />
</div>
<VButton type="secondary" @click="state.visible = false">关闭</VButton> <VButton type="secondary" @click="state.visible = false">关闭</VButton>
</VModal> </VModal>
</template> </template>
<template #controls="{ state }">
<HstCheckbox v-model="state.visible" title="Visible" />
<HstText v-model="state.title" title="Title" />
<HstNumber v-model="state.width" title="Width" />
<HstCheckbox v-model="state.fullscreen" title="Fullscreen" />
</template>
</Story> </Story>
</template> </template>

View File

@ -41,44 +41,46 @@ function handleClose() {
} }
</script> </script>
<template> <template>
<transition <Teleport to="body">
enter-active-class="ease-out" <transition
enter-from-class="opacity-0" enter-active-class="ease-out"
enter-to-class="opacity-100" enter-from-class="opacity-0"
leave-active-class="ease-in" enter-to-class="opacity-100"
leave-from-class="opacity-100" leave-active-class="ease-in"
leave-to-class="opacity-0" leave-from-class="opacity-100"
> leave-to-class="opacity-0"
<div
v-show="visible"
:class="wrapperClasses"
aria-modal="true"
class="modal-wrapper transform transition-all duration-200"
role="dialog"
tabindex="0"
@keyup.esc="handleClose()"
> >
<div class="modal-layer" @click="handleClose()" /> <div
<div :style="contentStyles" class="modal-content"> v-show="visible"
<div class="modal-header"> :class="wrapperClasses"
<div class="modal-header-title">{{ title }}</div> aria-modal="true"
<div class="modal-header-actions"> class="modal-wrapper transform transition-all duration-200"
<div class="modal-header-action" @click="handleClose()"> role="dialog"
<IconClose /> tabindex="0"
@keyup.esc="handleClose()"
>
<div class="modal-layer" @click="handleClose()" />
<div :style="contentStyles" class="modal-content">
<div class="modal-header">
<div class="modal-header-title">{{ title }}</div>
<div class="modal-header-actions">
<div class="modal-header-action" @click="handleClose()">
<IconClose />
</div>
</div> </div>
</div> </div>
</div> <div class="modal-body">
<div class="modal-body"> <slot />
<slot /> </div>
</div> <div class="modal-footer">
<div class="modal-footer"> <slot name="footer">
<slot name="footer"> <VButton @click="handleClose"></VButton>
<VButton @click="handleClose"></VButton> </slot>
</slot> </div>
</div> </div>
</div> </div>
</div> </transition>
</transition> </Teleport>
</template> </template>
<style lang="scss"> <style lang="scss">
@ -138,6 +140,7 @@ function handleClose() {
.modal-body { .modal-body {
@apply overflow-x-hidden overflow-y-auto; @apply overflow-x-hidden overflow-y-auto;
@apply flex-1;
word-wrap: break-word; word-wrap: break-word;
padding: 12px 16px; padding: 12px 16px;
} }

View File

@ -9,6 +9,7 @@
<VButton type="secondary" @click="visible = true">打开</VButton> <VButton type="secondary" @click="visible = true">打开</VButton>
</div> </div>
</div> </div>
<p></p>
</VModal> </VModal>
<VButton type="secondary" @click="visible = true">打开</VButton> <VButton type="secondary" @click="visible = true">打开</VButton>
</FilledLayout> </FilledLayout>
@ -18,5 +19,6 @@ import { FilledLayout } from "@/layouts";
import { VModal } from "@/components/base/modal"; import { VModal } from "@/components/base/modal";
import { VButton } from "@/components/base/button"; import { VButton } from "@/components/base/button";
import { ref } from "vue"; import { ref } from "vue";
const visible = ref(false); const visible = ref(false);
</script> </script>