Create simple custom modal component
This commit is contained in:
parent
5347bf0023
commit
f2666ce12c
43
components/SimpleModal.vue
Normal file
43
components/SimpleModal.vue
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
<template>
|
||||||
|
<Teleport to="body">
|
||||||
|
<div v-if="modelValue" class="fixed inset-0 z-50" @click.self="close">
|
||||||
|
<!-- Backdrop -->
|
||||||
|
<div class="fixed inset-0 bg-black/50" @click="close"></div>
|
||||||
|
|
||||||
|
<!-- Modal Panel -->
|
||||||
|
<div class="fixed inset-0 flex items-center justify-center p-4">
|
||||||
|
<div
|
||||||
|
class="bg-white rounded-lg shadow-xl max-w-[85vw] max-h-[85vh] overflow-auto relative"
|
||||||
|
:style="{ maxHeight }"
|
||||||
|
>
|
||||||
|
<!-- Close button -->
|
||||||
|
<button
|
||||||
|
@click="close"
|
||||||
|
class="absolute top-4 right-4 z-10 text-gray-500 hover:text-gray-700 text-2xl leading-none"
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Content -->
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Teleport>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: Boolean,
|
||||||
|
maxHeight: {
|
||||||
|
type: String,
|
||||||
|
default: '85vh'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
emit('update:modelValue', false)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -67,8 +67,8 @@
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<Modal v-model="modalStore.isOpen" :maxHeight="modalStore.type === 'image' && modalStore.soundcloudUrl ? 'calc(85vh + 60px)' : '85vh'">
|
<SimpleModal v-model="modalStore.isOpen" :maxHeight="modalStore.type === 'image' && modalStore.soundcloudUrl ? 'calc(85vh + 60px)' : '85vh'">
|
||||||
<div class="flex flex-col h-full overflow-hidden relative">
|
<div class="flex flex-col h-full overflow-hidden relative p-4">
|
||||||
<!-- Navigation buttons for images - fixed to modal -->
|
<!-- Navigation buttons for images - fixed to modal -->
|
||||||
<template v-if="modalStore.type === 'image' && modalStore.gallery && modalStore.gallery.length > 1">
|
<template v-if="modalStore.type === 'image' && modalStore.gallery && modalStore.gallery.length > 1">
|
||||||
<button @click="prevImage" class="absolute left-2 top-1/2 -translate-y-1/2 z-20 text-gray-600 hover:text-gray-900">
|
<button @click="prevImage" class="absolute left-2 top-1/2 -translate-y-1/2 z-20 text-gray-600 hover:text-gray-900">
|
||||||
|
|
@ -87,7 +87,7 @@
|
||||||
<iframe :src="modalStore.soundcloudUrl" class="w-64" height="20px" scrolling="no" frameborder="no" allow="autoplay"></iframe>
|
<iframe :src="modalStore.soundcloudUrl" class="w-64" height="20px" scrolling="no" frameborder="no" allow="autoplay"></iframe>
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="modalStore.type === 'video'" class="w-full flex items-center justify-center p-4">
|
<div v-if="modalStore.type === 'video'" class="w-full flex items-center justify-center">
|
||||||
<div class="w-full aspect-video">
|
<div class="w-full aspect-video">
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
<iframe
|
<iframe
|
||||||
|
|
@ -118,13 +118,13 @@
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="modalStore.type === 'pdf' || modalStore.type === 'image' || modalStore.type === 'document'" class="absolute bottom-0 right-0 p-4 z-10">
|
<div v-if="modalStore.type === 'pdf' || modalStore.type === 'image' || modalStore.type === 'document'" class="absolute bottom-4 right-4 z-10">
|
||||||
<a :href="modalStore.type === 'pdf' ? modalStore.pdfUrl : modalStore.type === 'image' ? '/' + modalStore.bucket + '/' + modalStore.gallery[0]?.image : modalStore.type === 'document' ? modalStore.iframeUrl : undefined" target="_blank" rel="noopener noreferrer" class="p-2 bg-gray-600 rounded-lg inline-flex items-center justify-center pointer-events-auto">
|
<a :href="modalStore.type === 'pdf' ? modalStore.pdfUrl : modalStore.type === 'image' ? '/' + modalStore.bucket + '/' + modalStore.gallery[0]?.image : modalStore.type === 'document' ? modalStore.iframeUrl : undefined" target="_blank" rel="noopener noreferrer" class="p-2 bg-gray-600 rounded-lg inline-flex items-center justify-center pointer-events-auto">
|
||||||
<Icon name="mdi:open-in-new" class="w-5 h-5 text-white" />
|
<Icon name="mdi:open-in-new" class="w-5 h-5 text-white" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</SimpleModal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue