overlays

Display a modal within your application.

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