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:
vue
<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
.
vue
<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 tofalse
to hide the modal header. - You can also use
header
slot to take full control of the modal header. Notice that this slot will overridetitle
slot since it is a completely replacement
vue
<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>
Custom footer
- Use
footer
slot to customize the modal footer. - Set
footer
prop tofalse
to hide the modal footer.
vue
<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
andcancel-text
to customize button texts - Use
ok-type
andcancel-type
to customize button types
vue
<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.
vue
<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.
vue
<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:
vue
<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:
vue
<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
Modal
Props
Name | Type | Default | Required | Description |
---|---|---|---|---|
v-model | Boolean | false | ✔ | Show / hide the modal. |
title | String | The modal title (will be override if title slot exist). | ||
size | String | The alternative modal size. Support lg / sm . | ||
backdrop | Boolean | true | Dismiss the modal by backdrop click. | |
footer | Boolean | true | Show modal footer. | |
header | Boolean | true | Show modal header. | |
dismiss-btn | Boolean | true | Display the dismiss button in header. | |
cancel-text | String | Override the text of cancel button. | ||
cancel-type | String | default | Button type of cancel button. | |
ok-text | String | Override the text of ok button. | ||
ok-type | String | primary | Button type of ok button. | |
transition | Number | 150 | Transition time of the modal, set to 0 to disable animation. | |
auto-focus | Boolean | false | Focus on the button that has data-action="auto-focus" attribute after modal open, the OK button by default. | |
keyboard | Boolean | true | Close the modal after esc key pressed. | |
append-to-body | Boolean | false | Append the modal element to <body> . | |
before-close | Function | Call with the msg param, return false to interrupt the modal hiding process. Promise supported. |
Slots
Name | Description |
---|---|
title | Replace as the modal title. |
default | Replace as the modal body. |
header | Replace as the modal header. Note: this slot will override title slot since it is a completely replacement of header. |
footer | Replace as the modal footer. |
Events
Name | Params | Description |
---|---|---|
show | Fire after modal show. | |
hide | msg | Fire after modal dismiss with message (if exist). |