Usage
Use a v-model
to control the Modal state.
<script setup>const isOpen = ref(false)</script><template> <div> <UButton label="Open" @click="isOpen = true" /> <UModal v-model="isOpen"> <!-- Content --> </UModal> </div></template>
You can put a Card component inside your Modal to handle forms and take advantage of header
and footer
slots:
<script setup>const isOpen = ref(false)</script><template> <div> <UButton label="Open" @click="isOpen = true" /> <UModal v-model="isOpen"> <UCard :ui="{ divide: 'divide-y divide-gray-100 dark:divide-gray-800' }"> <template #header> <!-- Content --> </template> <!-- Content --> <template #footer> <!-- Content --> </template> </UCard> </UModal> </div></template>
Disable overlay
Set the overlay
prop to false
to disable it.
<script setup>const isOpen = ref(false)</script><template> <div> <UButton label="Open" @click="isOpen = true" /> <UModal v-model="isOpen" :overlay="false"> <div class="p-4"> <Placeholder class="h-48" /> </div> </UModal> </div></template>
Disable transition
Set the transition
prop to false
to disable it.
<script setup>const isOpen = ref(false)</script><template> <div> <UButton label="Open" @click="isOpen = true" /> <UModal v-model="isOpen" :transition="false"> <div class="p-4"> <Placeholder class="h-48" /> </div> </UModal> </div></template>
Prevent close
Use the prevent-close
prop to disable the outside click alongside the esc
keyboard shortcut.
<script setup>const isOpen = ref(false)</script><template> <div> <UButton label="Open" @click="isOpen = true" /> <UModal v-model="isOpen" prevent-close> <UCard :ui="{ ring: '', divide: 'divide-y divide-gray-100 dark:divide-gray-800' }"> <template #header> <div class="flex items-center justify-between"> <h3 class="text-base font-semibold leading-6 text-gray-900 dark:text-white"> Modal </h3> <UButton color="gray" variant="ghost" icon="i-heroicons-x-mark-20-solid" class="-my-1" @click="isOpen = false" /> </div> </template> <Placeholder class="h-32" /> </UCard> </UModal> </div></template>
You can still handle the esc
shortcut yourself by using our defineShortcuts composable.
<script setup>const isOpen = ref(false)defineShortcuts({ escape: { usingInput: true, whenever: [isOpen], handler: () => { isOpen.value = false } }})</script>
Fullscreen
Set the fullscreen
prop to true
to enable it.
<script setup>const isOpen = ref(false)</script><template> <div> <UButton label="Open" @click="isOpen = true" /> <UModal v-model="isOpen" fullscreen> <UCard :ui="{ base: 'h-full flex flex-col', rounded: '', divide: 'divide-y divide-gray-100 dark:divide-gray-800', body: { base: 'grow' } }" > <template #header> <div class="flex items-center justify-between"> <h3 class="text-base font-semibold leading-6 text-gray-900 dark:text-white"> Modal </h3> <UButton color="gray" variant="ghost" icon="i-heroicons-x-mark-20-solid" class="-my-1" @click="isOpen = false" /> </div> </template> <Placeholder class="h-full" /> </UCard> </UModal> </div></template>
Props
ui
any
undefined
transition
boolean
true
modelValue
boolean
false
appear
boolean
false
overlay
boolean
true
preventClose
boolean
false
fullscreen
boolean
false
Preset
UModal.vue
{ "wrapper": "relative z-50", "inner": "fixed inset-0 overflow-y-auto", "container": "flex min-h-full items-end sm:items-center justify-center text-center", "padding": "p-4 sm:p-0", "margin": "sm:my-8", "base": "relative text-left rtl:text-right overflow-hidden w-full flex flex-col", "overlay": { "base": "fixed inset-0 transition-opacity", "background": "bg-gray-200/75 dark:bg-gray-800/75", "transition": { "enter": "ease-out duration-300", "enterFrom": "opacity-0", "enterTo": "opacity-100", "leave": "ease-in duration-200", "leaveFrom": "opacity-100", "leaveTo": "opacity-0" } }, "background": "bg-white dark:bg-gray-900", "ring": "", "rounded": "rounded-lg", "shadow": "shadow-xl", "width": "sm:max-w-lg", "height": "", "transition": { "enter": "ease-out duration-300", "enterFrom": "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95", "enterTo": "opacity-100 translate-y-0 sm:scale-100", "leave": "ease-in duration-200", "leaveFrom": "opacity-100 translate-y-0 sm:scale-100", "leaveTo": "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" }}