Modal

Modals are streamlined, but flexible, dialog prompts with the minimum required functionality and smart defaults.

Example

Toggle a modal by clicking the button below. It will slide down and fade in from the top of the page.

A simple modal example with callback:

<template>
  <Btn type="primary" @click="open = true">Launch Demo Modal</Btn>
  <Modal
    id="modal-demo"
    ref="modal"
    v-model="open"
    title="Modal 1"
    @hide="callback"
  >
    <h4>Text in a modal</h4>
    <p>Duis mollis, est non commodo luctus, nisi erat porttitor ligula.</p>
    <h4>Popover in a modal</h4>
    <p>
      This
      <btn
        v-popover:modal-demo="{
          title: 'Title',
          content: 'Some popover content...',
        }"
        >button</btn
      >
      should trigger a popover on click.
    </p>
    <h4>Tooltips in a modal</h4>
    <p>
      <a v-tooltip:modal-demo="'Tooltip'" role="button">This link</a>
      <span>and</span>
      <a v-tooltip:modal-demo="'Tooltip'" role="button">that link</a>
      <span>should have tooltips on hover.</span>
    </p>
    <hr />
    <h4>Overflowing text to show scroll behavior</h4>
    <p>
      Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus
      ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur
      ac, vestibulum at eros.
    </p>
    <p>
      Praesent commodo cursus magna, vel scelerisque nisl consectetur et.
      Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.
    </p>
    <p>
      Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus
      magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec
      ullamcorper nulla non metus auctor fringilla.
    </p>
    <p>
      Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus
      ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur
      ac, vestibulum at eros.
    </p>
    <p>
      Praesent commodo cursus magna, vel scelerisque nisl consectetur et.
      Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.
    </p>
    <p>
      Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus
      magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec
      ullamcorper nulla non metus auctor fringilla.
    </p>
    <p>
      Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus
      ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur
      ac, vestibulum at eros.
    </p>
    <p>
      Praesent commodo cursus magna, vel scelerisque nisl consectetur et.
      Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.
    </p>
    <p>
      Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus
      magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec
      ullamcorper nulla non metus auctor fringilla.
    </p>
  </Modal>
</template>

<script setup>
import {
  Modal,
  Btn,
  Notification,
  popover as vPopover,
  tooltip as vTooltip,
} from 'uiv';
import { ref } from 'vue';

const open = ref(false);

function callback(msg) {
  Notification.notify(`Modal dismissed with msg '${msg}'.`);
}
</script>

Optional sizes

Modals have two optional sizes: lg and sm.

<template>
  <Btn type="primary" @click="open1 = true">Large Modal</Btn>
  <Btn type="primary" @click="open2 = true">Small Modal</Btn>
  <Modal v-model="open1" title="Modal Title" size="lg">
    <p>This is a large modal.</p>
  </Modal>
  <Modal v-model="open2" title="Modal Title" size="sm">
    <p>This is a small modal.</p>
  </Modal>
</template>

<script setup>
import { Modal, Btn } from 'uiv';
import { ref } from 'vue';

const open1 = ref(false);
const open2 = ref(false);
</script>

Custom header

  • Use title slot to customize the modal title.
  • Set header prop to false to hide the modal header.
  • You can also use header slot to take full control of the modal header. Notice that this slot will override title slot since it is a completely replacement
<template>
  <Btn type="primary" @click="open1 = true">HTML Title</Btn>
  <Btn type="primary" @click="open2 = true">No Header</Btn>
  <Modal v-model="open1">
    <template #title>
      <span><i class="glyphicon glyphicon-heart"></i> Modal Title</span>
    </template>
    <p>This is a modal with HTML title.</p>
  </Modal>
  <Modal v-model="open2" :header="false">
    <p>This is a modal with no header.</p>
  </Modal>
</template>

<script setup>
import { Modal, Btn } from 'uiv';
import { ref } from 'vue';

const open1 = ref(false);
const open2 = ref(false);
</script>
  • Use footer slot to customize the modal footer.
  • Set footer prop to false to hide the modal footer.
<template>
  <Btn type="primary" @click="open1 = true">Custom Footer</Btn>
  <Btn type="primary" @click="open2 = true">No Footer</Btn>
  <Modal v-model="open1" title="Modal Title">
    <p>This is a modal with custom footer.</p>
    <template #footer>
      <div>
        <Btn @click="open1 = false">Cancel</Btn>
        <Btn type="warning">Warning Action</Btn>
        <Btn type="danger">Danger Action</Btn>
      </div>
    </template>
  </Modal>
  <Modal v-model="open2" title="Modal Title" :footer="false">
    <p>This is a modal with no footer.</p>
  </Modal>
</template>

<script setup>
import { Modal, Btn } from 'uiv';
import { ref } from 'vue';

const open1 = ref(false);
const open2 = ref(false);
</script>

Custom button texts and types

  • Use ok-text and cancel-text to customize button texts
  • Use ok-type and cancel-type to customize button types
<template>
  <Btn type="primary" @click="open = true">Custom Button Text and Type</Btn>
  <Modal
    v-model="open"
    title="Are you sure?"
    ok-text="Yes, please"
    cancel-text="No way!"
    ok-type="danger"
    cancel-type="warning"
  >
    <p>Do you really want to destroy this item?</p>
  </Modal>
</template>

<script setup>
import { Modal, Btn } from 'uiv';
import { ref } from 'vue';

const open = ref(false);
</script>

Auto focus

Auto focus on footer button with data-action="auto-focus" attribute after modal open. By default it is the OK button.

Disable backdrop

Set backdrop prop to false to disable the modal dismiss action on backdrop click.

<template>
  <Btn type="primary" @click="open = true">Disable Backdrop</Btn>
  <Modal v-model="open" title="Modal Title" :backdrop="false">
    <p>This is a modal that can not close by backdrop click.</p>
  </Modal>
</template>

<script setup>
import { Modal, Btn } from 'uiv';
import { ref } from 'vue';

const open = ref(false);
</script>

Disable animation

Set transition to 0 to disable modal animations.

<template>
  <Btn type="primary" @click="open = true">Disable Animation</Btn>
  <Modal v-model="open" title="Modal Title" :transition="0">
    <p>This is a modal that has no transition effect.</p>
  </Modal>
</template>

<script setup>
import { Modal, Btn } from 'uiv';
import { ref } from 'vue';

const open = ref(false);
</script>

Nested modals

Note that if you want modals to be real nested to each other, you have to add append-to-body prop to them. For example:

<template>
  <Btn type="primary" @click="open1 = true">Open set of nested modals</Btn>
  <!-- `append-to-body` not required here -->
  <Modal ref="modal1" v-model="open1" title="Modal 1" size="lg">
    <p>This is a simple large modal.</p>
    <p>Click on the button below to open a nested modal.</p>
    <Btn type="info" @click="open2 = true">Open Modal 2</Btn>
    <!-- `append-to-body` required, because this is a nested modal -->
    <Modal ref="modal2" v-model="open2" title="Modal 2" append-to-body>
      <p>This is a nested modal.</p>
      <Btn type="info" @click="open3 = true">Open Modal 3</Btn>
      <!-- `append-to-body` required, because this is a nested modal -->
      <Modal
        ref="modal3"
        v-model="open3"
        title="Modal 3"
        size="sm"
        append-to-body
      >
        <p>This is another nested modal.</p>
      </Modal>
    </Modal>
  </Modal>
</template>

<script setup>
import { Modal, Btn } from 'uiv';
import { ref } from 'vue';

const open1 = ref(false);
const open2 = ref(false);
const open3 = ref(false);
</script>

Otherwise, you can simply nest them logically, without any extra settings:

<template>
  <Btn type="primary" @click="open1 = true"
    >Open set of nested modals (logically)</Btn
  >
  <Modal v-model="open1" title="Modal 1" size="lg">
    <p>This is a simple large modal.</p>
    <p>Click on the button below to open a nested modal.</p>
    <Btn type="info" @click="open2 = true">Open Modal 2</Btn>
  </Modal>
  <Modal v-model="open2" title="Modal 2">
    <p>This is a nested modal.</p>
    <Btn type="info" @click="open3 = true">Open Modal 3</Btn>
  </Modal>
  <Modal v-model="open3" title="Modal 3" size="sm">
    <p>This is another nested modal.</p>
  </Modal>
</template>

<script setup>
import { Modal, Btn } from 'uiv';
import { ref } from 'vue';

const open1 = ref(false);
const open2 = ref(false);
const open3 = ref(false);
</script>

API Reference

Props

NameTypeDefaultRequiredDescription
v-modelBooleanfalseShow / hide the modal.
titleStringThe modal title (will be override if title slot exist).
sizeStringThe alternative modal size. Support lg / sm.
backdropBooleantrueDismiss the modal by backdrop click.
footerBooleantrueShow modal footer.
headerBooleantrueShow modal header.
dismiss-btnBooleantrueDisplay the dismiss button in header.
cancel-textStringOverride the text of cancel button.
cancel-typeStringdefaultButton type of cancel button.
ok-textStringOverride the text of ok button.
ok-typeStringprimaryButton type of ok button.
transitionNumber150Transition time of the modal, set to 0 to disable animation.
auto-focusBooleanfalseFocus on the button that has data-action="auto-focus" attribute after modal open, the OK button by default.
keyboardBooleantrueClose the modal after esc key pressed.
append-to-bodyBooleanfalseAppend the modal element to <body>.
before-closeFunctionCall with the msg param, return false to interrupt the modal hiding process. Promise supported.

Slots

NameDescription
titleReplace as the modal title.
defaultReplace as the modal body.
headerReplace as the modal header. Note: this slot will override title slot since it is a completely replacement of header.
footerReplace as the modal footer.

Events

NameParamsDescription
showFire after modal show.
hidemsgFire after modal dismiss with message (if exist).