Skip to content

Instantly share code, notes, and snippets.

@Sugavanas
Last active May 11, 2021 01:52
Show Gist options
  • Save Sugavanas/eabbc3a260c488d4b403321883bbaa4e to your computer and use it in GitHub Desktop.
Save Sugavanas/eabbc3a260c488d4b403321883bbaa4e to your computer and use it in GitHub Desktop.
Vue3 Modal Componenet
<template>
<Modal :dismissible="true" v-model:open="show">
<div class="p-4">
<h3 class="text-lg font-medium leading-6 text-gray-900">
{{ title }}
</h3>
<div class="mt-2">
<p class="text-sm text-gray-500">
{{ description }}
</p>
</div>
<div class="mt-4 sm:flex justify-center">
<input
type="button"
class="sm:ml-2 w-24 inline-flex justify-center px-4 py-2 text-sm font-medium text-white bg-blue-700 opacity-70 border border-transparent rounded-md hover:bg-green-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-green-500"
@click="clickOk"
:value="ok"/>
</div>
</div>
</Modal>
</template>
<script>
import Modal from "@/components/Modal";
export default {
props: {
'title': {
type: String
},
'description': {
type: String
},
'ok': {
type: String,
default: 'Ok'
},
'callback': {
type: Function,
default: function(){}
}
},
data: function() {
return {
show: true
}
},
components: {
Modal
},
methods: {
clickOk: function () {
this.show = false;
}
},
watch: {
show: function(val) {
//Value changed so do anything here
}
}
};
</script>
<template>
<TransitionRoot appear as="div" :show="open" @close="close">
<div class="fixed z-10 inset-0 overflow-y-auto">
<TransitionChild
as="div"
enter="duration-300 ease-out"
enter-from="opacity-0"
enter-to="opacity-100"
leave="duration-200 ease-in"
leave-from="opacity-100"
leave-to="opacity-0"
>
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity"></div>
</TransitionChild>
<TransitionChild
as="div"
class="absolute h-screen w-screen"
enter="duration-300 ease-out"
enter-from="opacity-0 scale-95"
enter-to="opacity-100 scale-100"
leave="duration-200 ease-in"
leave-from="opacity-100 scale-100"
leave-to="opacity-0 scale-95"
>
<div class="flex w-full h-full justify-center items-center m-auto antialiased">
<div
class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
<div style="min-height: 8rem;">
<slot></slot>
</div>
</div>
</div>
</TransitionChild>
</div>
</TransitionRoot>
</template>
<script>
import {TransitionRoot, TransitionChild,} from "@headlessui/vue";
export default {
emits: ['update:open'],
model: {
prop: 'open',
event: 'change',
},
props: {
dismissible: {
type: Boolean,
default: true
},
open: {
type: Boolean,
default: true
}
},
methods: {
dismiss: function () {
if (this.dismissible)
this.close();
},
close: function() {
this.$emit('update:open', false);
}
},
components: {
TransitionChild,
TransitionRoot
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment