167 lines
4.1 KiB
Vue
167 lines
4.1 KiB
Vue
<template>
|
|
<transition id="modal" name="modal">
|
|
<div class="modal-mask">
|
|
<div
|
|
class="modal-wrapper"
|
|
>
|
|
<div
|
|
class="modal-container bg-gray-500 dark:bg-gray-600 shadow-inner rounded border border-gray-500 dark:border-gray-400"
|
|
:style="`${cssStyle}`"
|
|
>
|
|
<div class="relative">
|
|
<div
|
|
class="absolute top-0 right-2 h-8 w-8 p-2"
|
|
>
|
|
<button
|
|
class="rounded-md text-gray-300 hover:text-white
|
|
focus:outline-none focus:ring-2 focus:ring-white
|
|
dark:focus:ring-black dark:bg-cool-gray-600 dark:text-white"
|
|
@click="OnCloseButton"
|
|
>
|
|
<span class="sr-only">Close panel</span>
|
|
<!-- Heroicon name: outline/x -->
|
|
<svg
|
|
class="h-6 w-6 dark:text-white dark:hover:text-gray-400"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
aria-hidden="true"
|
|
>
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="modal-header p-4">
|
|
<slot name="header">
|
|
</slot>
|
|
</div>
|
|
<div class="modal-body pl-4">
|
|
<slot name="body">
|
|
</slot>
|
|
</div>
|
|
<div class="modal-footer p-4">
|
|
<slot name="footer">
|
|
<button
|
|
class="modal-default-button rounded border p-1 text-gray-400 dark:text-gray-200 hover:text-black focus:outline-none focus:ring-2 focus:ring-black dark:hover:text-white dark:focus:ring-white"
|
|
@click="OnCloseButton"
|
|
>
|
|
OK
|
|
</button>
|
|
</slot>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</transition>
|
|
</template>
|
|
<script setup lang="ts">
|
|
import { onMounted, onUnmounted, ref, computed } from 'vue'
|
|
import { useI18n } from 'vue-i18n'
|
|
import useState from '~/hooks/useState'
|
|
const { t } = useI18n()
|
|
const props = defineProps({
|
|
cssStyle: {
|
|
type: String,
|
|
required: false,
|
|
default: () => '',
|
|
},
|
|
})
|
|
|
|
const emit = defineEmits(['onCloseModal'])
|
|
|
|
const OnCloseButton = () => {
|
|
useState().showModal.value = false
|
|
emit('onCloseModal')
|
|
}
|
|
|
|
const OnModalMask = (ev: any) => {
|
|
}
|
|
const OnKeydownEsc = (event: any) => {
|
|
switch (event.key) {
|
|
case 'Escape':
|
|
if (document.getElementById('modal') && useState().showModal.value) {
|
|
event.preventDefault()
|
|
event.stopImmediatePropagation()
|
|
event.stopPropagation()
|
|
useState().showModal.value = false
|
|
emit('onCloseModal')
|
|
}
|
|
break
|
|
}
|
|
}
|
|
onMounted(async() => {
|
|
document.addEventListener('keydown', OnKeydownEsc)
|
|
})
|
|
onUnmounted(async() => {
|
|
document.removeEventListener('keydown', OnKeydownEsc)
|
|
})
|
|
|
|
</script>
|
|
<style scoped>
|
|
.modal-mask {
|
|
position: fixed;
|
|
z-index: 9998;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: rgba(0, 0, 0, 0.75);
|
|
display: table;
|
|
transition: opacity 0.3s ease;
|
|
}
|
|
|
|
.modal-wrapper {
|
|
display: table-cell;
|
|
vertical-align: middle;
|
|
}
|
|
|
|
.modal-container {
|
|
margin: 0px auto;
|
|
/* padding: 20px 30px; */
|
|
/* border-radius: 2px; */
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
|
|
transition: all 0.3s ease;
|
|
font-family: Helvetica, Arial, sans-serif;
|
|
}
|
|
|
|
.modal-header h3 {
|
|
margin-top: 0;
|
|
/* color: #42b983; */
|
|
}
|
|
|
|
.modal-body {
|
|
margin: 20px 0;
|
|
}
|
|
|
|
.modal-default-button {
|
|
display: block;
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
/*
|
|
* The following styles are auto-applied to elements with
|
|
* transition="modal" when their visibility is toggled
|
|
* by Vue.js.
|
|
*
|
|
* You can easily play with the modal transition by editing
|
|
* these styles.
|
|
*/
|
|
|
|
.modal-enter {
|
|
opacity: 0;
|
|
}
|
|
|
|
.modal-leave-active {
|
|
opacity: 0;
|
|
}
|
|
|
|
.modal-enter .modal-container,
|
|
.modal-leave-active .modal-container {
|
|
-webkit-transform: scale(1.1);
|
|
transform: scale(1.1);
|
|
}
|
|
|
|
</style>
|