Skip to content

Instantly share code, notes, and snippets.

@andreasvirkus
Last active September 10, 2022 22:03
Show Gist options
  • Save andreasvirkus/7ec0e2abf28d70325824b1cd193527a6 to your computer and use it in GitHub Desktop.
Save andreasvirkus/7ec0e2abf28d70325824b1cd193527a6 to your computer and use it in GitHub Desktop.
Simple Vue modal component
<template>
<transition-fade :duration="200">
<div
v-if="show"
:class="$style.backdrop"
@click="$emit('close')"
@keydown.stop
@keyup.esc="handleEscape"
>
<dialog v-show="show" ref="dialog" :open="show" :class="$style.modal" tabindex="-1">
<div :class="$style.wrapper" @click.stop>
<slot />
</div>
</dialog>
</div>
</transition-fade>
</template>
<script setup lang="ts">
import { TransitionFade } from '@morev/vue-transitions'
const props = defineProps({ show: Boolean })
const emit = defineEmits(['close'])
const dialog = ref<HTMLDialogElement | null>(null)
const closeModal = () => {
emit('close')
}
const handleEscape = () => {
if (props.show) closeModal()
}
watch(
() => props.show,
async (val) => {
if (val) {
await nextTick()
dialog.value?.focus()
}
},
)
</script>
<style module>
.modal {
--modal-width: 40rem;
position: absolute;
right: 0;
left: 0;
display: flex;
min-height: 100%;
align-items: center;
margin: 0 auto;
padding: 0;
border: none;
background-color: transparent;
max-width: var(--modal-width);
width: 95%;
}
.wrapper {
display: flex;
position: relative;
flex-direction: column;
margin: 2rem auto 7rem;
padding: 2rem;
padding-bottom: 20px;
background-clip: padding-box;
border-radius: 0.3125rem;
transition: height 0.3s;
outline: 0;
}
.backdrop {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: #27334560;
z-index: 9;
overflow-y: auto;
backdrop-filter: blur(8px);
}
</style>
<modal :show="showModal" @close="showModal = false">
<iframe width="560"
height="315"
src="https://www.youtube.com/embed/QH2-TGUlwu4?controls=0"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen>
</iframe>
</modal>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment