feat: migrate to native dialog element for modal component

This commit is contained in:
Sebin Nyshkim 2023-04-02 17:28:48 +02:00
parent b9fe7113ed
commit d0f9434700
2 changed files with 71 additions and 66 deletions

View file

@ -1,100 +1,101 @@
<script setup lang="ts"> <script setup lang="ts">
import { inject } from "vue"; import { ref, inject } from "vue";
import { modalResultKey } from "@/keys"; import { modalResultKey } from "@/keys";
import Button from "@/components/RefButton.vue";
const modalResult = inject(modalResultKey, Function); const modalResult = inject(modalResultKey, Function);
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> </script>
<template> <template>
<div class="modal"> <dialog :id="id" class="modal" ref="modal">
<div class="modal__background"></div> <form method="dialog" class="modal__content">
<div class="modal__message"> <h2 class="modal__heading">
<div> <slot name="heading"></slot>
<h2><slot name="heading"></slot></h2> </h2>
<p><slot name="message"></slot></p>
<div class="modal__buttons"> <div class="modal__message">
<Button <slot name="message"></slot>
class="modal__button positive"
@click.prevent="modalResult(true)"
>
<slot name="yes"></slot>
</Button>
<Button
class="modal__button negative"
@click.prevent="modalResult(false)"
>
<slot name="no"></slot>
</Button>
</div>
</div> </div>
</div>
</div> <div class="modal__buttons">
<slot name="buttons"></slot>
</div>
</form>
</dialog>
</template> </template>
<style lang="scss"> <style lang="scss">
.modal { .modal {
display: flex;
flex-flow: row nowrap;
justify-content: center;
position: fixed; position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
text-align: center; background: var(--modal-background);
color: var(--color-text);
padding: 2rem; width: var(--modal-width);
backdrop-filter: blur(1rem); margin: auto;
background-color: rgba(0, 0, 0, 0.5); border: 0.25rem solid var(--color-modal-border);
border-radius: 1rem;
padding: 1rem;
overflow: auto; overflow: auto;
z-index: 9001;
&__background { animation: fade-in 1s;
position: absolute;
top: 0; &::backdrop {
right: 0; backdrop-filter: blur(1rem);
bottom: 0; background-color: rgba(0, 0, 0, 0.5);
left: 0; animation: fade-in 1s;
} }
&__message { &__content {
flex: 0 1 30rem;
display: flex; display: flex;
flex-flow: row wrap; flex-flow: column nowrap;
justify-content: center; justify-content: center;
align-content: center; text-align: center;
gap: 1.5rem;
background: var(--modal-background);
margin: auto;
border: 0.25rem solid var(--color-modal-border);
border-radius: 1rem;
padding: 1rem;
z-index: 9002;
> * { > * {
flex: 0 1 100%; flex: 1 1 auto;
} }
} }
&__buttons { &__heading {
display: flex; margin: 1.875rem 0 0 0;
flex-flow: row wrap;
justify-content: space-around;
align-items: center;
} }
&__button { &__message {
flex: 0 1 100%; flex: 1 1 100%;
margin: 0.75em 0; }
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
} }
} }
</style> </style>

View file

@ -133,6 +133,7 @@
--navigation-justify-content: flex-start; --navigation-justify-content: flex-start;
--quickfacts-background: var(--theme-b-page-background-light); --quickfacts-background: var(--theme-b-page-background-light);
--modal-background: var(--theme-b-modal-background-light); --modal-background: var(--theme-b-modal-background-light);
--modal-width: 100%;
--welcome-header-headings-flex-basis: 100%; --welcome-header-headings-flex-basis: 100%;
--welcome-header-headings-margin: 1.5rem 0 0 0; --welcome-header-headings-margin: 1.5rem 0 0 0;
--welcome-header-mainline-font-size: 2rem; --welcome-header-mainline-font-size: 2rem;
@ -207,6 +208,9 @@
--font-size-h2: 2.25rem; --font-size-h2: 2.25rem;
--font-size-h3: 1.5rem; --font-size-h3: 1.5rem;
--navigation-justify-content: center; --navigation-justify-content: center;
--modal-width: 30rem;
--welcome-header-headings-flex-basis: 23rem; --welcome-header-headings-flex-basis: 23rem;
--welcome-header-headings-margin: 0; --welcome-header-headings-margin: 0;
--welcome-header-mainline-font-size: var(--font-size-h1); --welcome-header-mainline-font-size: var(--font-size-h1);