# Modal
The CModal
component can be used to render modals/dialogs. CModal
is highly customizable. By default only minimal styles are applied.
# Installation
The @vue-cdk/modal
package can be installed via NPM/Yarn:
$ npm install @vue-cdk/modal --save
# Usage
@vue-cdk/modal
exposes a Vue plugin that you can use like this:
import Modal from '@vue-cdk/modal'
import Vue from 'vue'
Vue.use(Modal)
The plugin makes two components globally available:
CModal
: Use this component to render a modal. Modals are hidden/inactive by default.CModalOverlay
: This component is rendered behind every modal. By default is renders a dark, translucent background. Usually you never have to interact withCModalOverlay
.CModalOverlay
exists in order to customize the overlay used for modals.
# Import the required Styles
Modals require CSS to work properly. @vue-cdk/modal
ships with CSS that you have to import:
import '@vue-cdk/modal/style/index.css'
Styles are REQUIRED
Make sure to import @vue-cdk/modal/style/index.css
. Otherwise your modals will not work properly.
# Examples
Modals can be used in many different ways. Each example highlights a different aspect of the modal package.
# Simple Modal
The following example shows how a default modal looks like.
Show Code
<template>
<div>
<div>outside</div>
<input tabindex="0" />
<button @click="open = true">Open Modal</button>
<CModal :open.sync="open">
<template #default="{ close }">
<div style="background-color: white">
<div>modal</div>
<button @click="close">close</button>
<div>
<input />
</div>
</div>
</template>
</CModal>
<div>outside</div>
<input tabindex="0" />
</div>
</template>
<script>
import CModal from '@vue-cdk/modal'
import '@vue-cdk/modal/style/index.css'
export default {
mixins: [CModal()],
data() {
return {
open: false,
}
},
}
</script>
# Nested Modals
Modals can be nested.
Show Code
<template>
<div>
<div>outside</div>
<input tabindex="0" />
<button @click="open = true">Open Modal</button>
<CModal :open.sync="open">
<template #default="{ close }">
<div style="background-color: white">
<div>modal</div>
<button @click="close">Close</button>
<button @click="nestedOpen = true">Open Nested Modal</button>
<div>
<input />
</div>
</div>
</template>
</CModal>
<CModal :open.sync="nestedOpen">
<template #default="{ close }">
<div style="background-color: white">
<div>modal</div>
<button @click="close">close</button>
<button @keydown.esc="close">x</button>
<div>
<input />
</div>
</div>
</template>
</CModal>
<div>outside</div>
<input tabindex="0" />
</div>
</template>
<script>
import CModal from '@vue-cdk/modal'
import '@vue-cdk/modal/style/index.css'
export default {
mixins: [CModal()],
data() {
return {
open: false,
nestedOpen: false,
}
},
}
</script>
# Custom Overlay
You can customize the overlay by proviing an overlay
–slot. If you just want to customize the styling adding your own class is all you need to do.
Lazily render CModalOverlay
Make sure to use v-if="open"
on CModalOverlay
. Otherwise the modal and overlay are not rendered lazily. This is not an issue per se but if you have many modals (for example in a long list/table) you may experience performance issues.
Show Code
<template>
<div>
<button @click="open = true">Open Modal</button>
<CModal :open.sync="open">
<template #overlay>
<CModalOverlay v-if="open" class="custom-overlay">
<div style="background-color: white">
<div>modal</div>
<button @click="open = false">close</button>
<div>
<input />
</div>
</div>
</CModalOverlay>
</template>
</CModal>
</div>
</template>
<script>
import CModal from '@vue-cdk/modal'
import '@vue-cdk/modal/style/index.css'
export default {
mixins: [CModal()],
data() {
return {
open: false,
}
},
}
</script>
<style scoped>
.custom-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: radial-gradient(circle at 100%, #333, #333 50%, #eee 75%, #333 75%);
display: flex;
justify-content: center;
align-items: center;
z-index: 1001 !important;
}
</style>
# Nice Modal
You may have noticed that modals look kind of ugly by default. This does not have to be that way. Simply style the modal and its content as you wish to make it nicer.
Show Code
<template>
<div>
<button @click="open = true">Open Modal</button>
<CModal :open.sync="open">
<div class="modal">
<div class="modal-title">Delete Account?</div>
<div class="modal-content">
Are you sure to delete your account? You can also just deactivate your account and
activate it later on if you just want to get a little break.
</div>
<div class="modal-actions">
<button class="modal-action modal-confirm" @click="open = false">
<span class="modal-action__title">Delete</span>
</button>
<button class="modal-action modal-cancel" @click="open = false">
<span class="modal-action__title">Cancel</span>
</button>
</div>
</div>
</CModal>
</div>
</template>
<script>
import CModal from '@vue-cdk/modal'
import '@vue-cdk/modal/style/index.css'
export default {
mixins: [CModal()],
data() {
return {
open: false,
}
},
}
</script>
<style scoped>
.modal {
max-width: 30vw;
background-color: white;
padding: 2rem 1.5rem;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
'Noto Color Emoji';
border-radius: 0.2rem;
}
.modal {
box-shadow: 0px 0px 68px -15px rgba(0, 0, 0, 0.8);
transition: box-shadow 0.3s ease-in-out;
}
.modal:hover {
box-shadow: 0px 10px 68px -10px rgba(0, 0, 0, 1);
}
.modal-title {
font-size: 1.3rem;
font-weight: 500;
margin-bottom: 1rem;
}
.modal-content {
font-size: 1rem;
margin: 1rem 0rem;
line-height: 1.7rem;
}
.modal-actions {
display: flex;
justify-content: flex-end;
}
.modal-action {
margin-left: 1rem;
font-size: 1rem;
padding: 0.9rem 1.2rem;
border-radius: 0.33rem;
color: white;
cursor: pointer;
outline: none;
transition: background-color 0.3s ease-in-out;
}
.modal-confirm {
border: 1px solid rgb(84, 119, 0);
color: rgb(84, 119, 0);
background-color: rgb(245, 255, 221);
}
.modal-confirm:hover {
background-color: rgb(224, 255, 151);
}
.modal-confirm:focus {
box-shadow: 0px 0px 5px 0px rgba(84, 119, 0, 150);
}
.modal-cancel {
border: 1px solid rgb(119, 24, 0);
color: rgb(119, 24, 0);
background-color: rgb(255, 225, 221);
}
.modal-cancel:hover {
background-color: rgb(255, 189, 180);
}
.modal-cancel:focus {
box-shadow: 0px 0px 5px 0px rgba(201, 131, 122, 200);
}
</style>