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"
}
}