Files
web-temp/layers/components/atoms/modal/YouTube.vue
2025-10-29 17:55:14 +09:00

89 lines
2.1 KiB
Vue

<script setup lang="ts">
import { getYouTubeEmbedUrl } from '@/layers/utils/youtubeUtil'
interface Props {
youtubeUrl: string
isOutsideClose?: boolean
modalName?: string
}
const props = withDefaults(defineProps<Props>(), {
youtubeUrl: '',
isOutsideClose: false,
})
const emit = defineEmits(['closeButtonEvent'])
const isOpen = defineModel<boolean>('isOpen', { default: false })
const embedUrl = computed(() => {
return getYouTubeEmbedUrl(props.youtubeUrl)
})
const handleCloseModal = () => {
isOpen.value = false
emit('closeButtonEvent')
}
const handleKeydown = (event: KeyboardEvent) => {
if (event.key === 'Escape' && isOpen.value) {
handleCloseModal()
}
}
const handleOutsideClick = () => {
if (props.isOutsideClose) {
handleCloseModal()
}
}
// 키보드 이벤트 리스너 등록/해제
onMounted(() => {
document.addEventListener('keydown', handleKeydown)
})
onUnmounted(() => {
document.removeEventListener('keydown', handleKeydown)
})
</script>
<template>
<Transition name="fade">
<div
v-if="isOpen"
class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-75 z-[800]"
:class="props.modalName"
@click="handleOutsideClick"
>
<div
class="relative mx-4 my-4"
style="
width: min(896px, 90vw, calc((90vh - 2rem) * 16 / 9));
aspect-ratio: 16/9;
"
@click.stop
>
<!-- 헤더 -->
<div class="flex justify-end mb-3 md:mb-4">
<button type="button" @click="handleCloseModal">
<AtomsIconsCloseLine />
</button>
</div>
<!-- 유튜브 영상 컨테이너 -->
<div class="relative w-full h-full">
<iframe
v-if="embedUrl"
:src="embedUrl"
class="absolute top-0 left-0 w-full h-full"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
title="YouTube video player"
/>
</div>
</div>
</div>
</Transition>
</template>