laravel-vue-file-share/resources/js/Components/Modal.vue
2023-10-08 14:20:03 -07:00

98 lines
2.8 KiB
Vue

<script setup>
import { computed, onMounted, onUnmounted, watch } from "vue";
const props = defineProps({
show: {
type: Boolean,
default: false,
},
maxWidth: {
type: String,
default: "2xl",
},
closeable: {
type: Boolean,
default: true,
},
});
const emit = defineEmits(["close", "active"]);
watch(
() => props.show,
() => {
if (props.show) {
emit("active");
document.body.style.overflow = "hidden";
} else {
document.body.style.overflow = null;
}
}
);
const close = () => {
if (props.closeable) {
emit("close");
}
};
const closeOnEscape = (e) => {
if (e.key === "Escape" && props.show) {
close();
}
};
onMounted(() => document.addEventListener("keydown", closeOnEscape));
onUnmounted(() => {
document.removeEventListener("keydown", closeOnEscape);
document.body.style.overflow = null;
});
const maxWidthClass = computed(() => {
return {
sm: "sm:max-w-sm",
md: "sm:max-w-md",
lg: "sm:max-w-lg",
xl: "sm:max-w-xl",
"2xl": "sm:max-w-2xl",
}[props.maxWidth];
});
</script>
<template>
<Teleport to="body">
<Transition leave-active-class="duration-200">
<div
v-show="show"
class="fixed inset-0 overflow-y-auto px-4 py-6 sm:px-0 z-50"
scroll-region
>
<Transition
enter-active-class="ease-out duration-300"
enter-from-class="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enter-to-class="opacity-100 translate-y-0 sm:scale-100"
leave-active-class="ease-in duration-200"
leave-from-class="opacity-100 translate-y-0 sm:scale-100"
leave-to-class="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<div
v-show="show"
class="text-gray-100 border border-sky-600 mb-6 rounded-lg overflow-hidden transform transition-all sm:w-full sm:mx-auto backdrop-blur p-5 flex flex-col"
:class="maxWidthClass"
>
<div class="flex justify-end align-center">
<button
@click="close"
class="px-4 py-2 border border-sky-600 rounded hover:bg-red-800 flex items-center justify-center"
>
&#x1F5D9;
</button>
</div>
<slot v-if="show" />
</div>
</Transition>
</div>
</Transition>
</Teleport>
</template>