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>
  <section class="uiv">
    <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>
  </section>
</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>
  <section class="uiv">
    <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>
  </section>
</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>
  <section class="uiv">
    <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>
  </section>
</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>
  <section class="uiv">
    <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>
  </section>
</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>
  <section class="uiv">
    <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>
  </section>
</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>
  <section class="uiv">
    <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>
  </section>
</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>
  <section class="uiv">
    <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>
  </section>
</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>
  <section class="uiv">
    <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>
  </section>
</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>
  <section class="uiv">
    <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>
  </section>
</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 action button that has data-action="auto-focus" attribute after modal open, by default it is the OK button.
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 since 0.34.1.

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).