sebin-reference/src/components/RefModal.vue
2023-04-03 00:55:28 +02:00

98 lines
1.6 KiB
Vue

<script setup lang="ts">
import { ref } from 'vue'
interface Props {
id: string
}
defineProps<Props>()
const modal = ref<HTMLDialogElement>()
const showModal = () => {
modal.value?.showModal()
document.body.inert = true
document.body.classList.add('scroll-lock')
}
const close = () => {
modal.value?.close()
document.body.inert = false
document.body.classList.remove('scroll-lock')
}
defineExpose({ showModal, close })
</script>
<template>
<dialog :id="id" class="modal" ref="modal">
<form method="dialog" class="modal__content">
<h2 class="modal__heading">
<slot name="heading"></slot>
</h2>
<div class="modal__message">
<slot name="message"></slot>
</div>
<div class="modal__buttons">
<slot name="buttons"></slot>
</div>
</form>
</dialog>
</template>
<style lang="scss">
.modal {
position: fixed;
background: var(--modal-background);
color: var(--color-text);
width: var(--modal-width);
margin: auto;
border: 0.25rem solid var(--color-modal-border);
border-radius: 1rem;
padding: 1rem;
overflow: auto;
animation: fade-in 1s;
&::backdrop {
backdrop-filter: blur(1rem);
background-color: rgba(0, 0, 0, 0.5);
animation: fade-in 1s;
}
&__content {
display: flex;
flex-flow: column nowrap;
justify-content: center;
text-align: center;
gap: 1.5rem;
> * {
flex: 1 1 auto;
}
}
&__heading {
margin: 1.875rem 0 0 0;
}
&__message {
flex: 1 1 100%;
}
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
}
</style>