Skip to content

Modal

Modals display temporary content above the current page. They support <Teleport>, scroll-lock, ESC interception, and backdrop click to close.

Basic Usage

Control visibility with v-model. A modal includes a header (title + close button), content area, and an optional footer.

Show Code
vue
<script setup lang="ts">
import { ref } from 'vue'
const visible = ref(false)
</script>

<template>
  <button class="btn btn-primary" @click="visible = true">Open Modal</button>
  <TModal v-model="visible" title="Basic Modal">
    <p>Modal content</p>
    <template #footer>
      <button class="btn btn-link link-secondary" @click="visible = false">Cancel</button>
      <button class="btn btn-primary ms-auto" @click="visible = false">Confirm</button>
    </template>
  </TModal>
</template>

Centered Modal

Set centered to vertically center the modal in the viewport.

vue
<TModal v-model="visible" title="Centered Modal" centered>
  <p>This modal is vertically centered on screen.</p>
</TModal>

Sizes

Use the size prop to control modal width. Supports sm, lg, and xl.

Show Code
vue
<script setup lang="ts">
const sizeRef = ref<'sm' | 'lg' | 'xl'>('sm')
</script>

<template>
  <button class="btn btn-secondary" @click="sizeRef = 'sm'; visible = true">Small (sm)</button>
  <button class="btn btn-secondary" @click="sizeRef = 'lg'; visible = true">Large (lg)</button>
  <button class="btn btn-secondary" @click="sizeRef = 'xl'; visible = true">Extra Large (xl)</button>
  <TModal v-model="visible" :size="sizeRef" centered>...</TModal>
</template>

Full Width

Set fullWidth to remove the max-width constraint, letting the modal stretch nearly across the viewport.

vue
<TModal v-model="visible" title="Full-Width Modal" fullWidth centered>
  <p>This modal has max-width: none.</p>
</TModal>

Scrollable Content

Set scrollable to keep the header and footer fixed while the body scrolls.

vue
<TModal v-model="visible" title="Scrollable Modal" scrollable>
  <p v-for="i in 20" :key="i">Line {{ i }}</p>
  <template #footer>
    <button class="btn btn-primary" @click="visible = false">Close</button>
  </template>
</TModal>

Form Modal

Place forms inside the modal.

Show Code
vue
<TModal v-model="visible" title="Login Form" centered>
  <div class="mb-3">
    <label class="form-label">Username</label>
    <input v-model="username" type="text" class="form-control">
  </div>
  <template #footer>
    <button class="btn btn-primary ms-auto" @click="visible = false">Submit</button>
  </template>
</TModal>

Status Bar

Add a colored status bar at the top via the status prop (accepts any TablerColor value).

vue
<TModal v-model="visible" title="Operation Successful" centered status="success">
  <p>The operation completed successfully.</p>
</TModal>

Blur Backdrop

Set blur to apply a frosted-glass effect to the backdrop overlay.

vue
<TModal v-model="visible" title="Blur Effect" centered blur>
  <p>The backdrop has a frosted-glass blur effect.</p>
</TModal>

API

Props

PropTypeDefaultDescription
modelValuebooleanfalsev-model binding, controls show/hide
titlestringModal title
size'sm' | 'lg' | 'xl' | 'fullscreen'Modal size preset
fullWidthbooleanfalseFull-width mode (max-width: none)
centeredbooleanfalseVertically center the modal
scrollablebooleanfalseMake the body area scrollable
closablebooleantrueShow the close (X) button
closeOnBackdropbooleantrueClose when clicking the backdrop
closeOnEscbooleantrueClose when pressing the ESC key
statusTablerColorStatus bar color at the top
blurbooleanfalseEnable frosted-glass backdrop blur
teleportTostring'body'<Teleport> target selector

Slots

SlotDescription
defaultModal body content
titleCustom title area
headerCustom entire header (replaces default title + close button)
footerBottom action bar
statusCustom status bar

Emits

EventPayloadDescription
update:modelValue(value: boolean)v-model update event
openFires when the modal starts opening
openedFires after the open transition completes
closeFires when the modal starts closing
closedFires after the close transition completes