2019-01-31 12:15:32 +00:00
|
|
|
<template>
|
2020-01-20 10:54:26 +00:00
|
|
|
<div ref="mask" :class="wrapperClass" v-if="isMaskVisible">
|
|
|
|
<transition name="p-dialog" @before-enter="onBeforeEnter" @enter="onEnter" @leave="onLeave" @after-leave="onAfterLeave" @appear="onAppear">
|
|
|
|
<div ref="container" :class="containerClass" :style="containerStyle" v-if="visible" v-bind="$attrs" v-on="listeners" role="dialog" :aria-labelledby="ariaLabelledById" :aria-modal="modal">
|
2020-01-08 10:51:56 +00:00
|
|
|
<div class="p-dialog-titlebar" v-if="showHeader">
|
|
|
|
<slot name="header">
|
|
|
|
<span :id="ariaLabelledById" class="p-dialog-title" v-if="header" >{{header}}</span>
|
|
|
|
</slot>
|
|
|
|
<div class="p-dialog-titlebar-icons">
|
2020-01-13 10:06:08 +00:00
|
|
|
<button class="p-dialog-titlebar-icon p-dialog-titlebar-close p-link" @click="close" v-if="closable" :aria-label="ariaCloseLabel" type="button">
|
2020-01-08 10:51:56 +00:00
|
|
|
<span class="p-dialog-titlebar-close-icon pi pi-times"></span>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="p-dialog-content" :style="contentStyle">
|
|
|
|
<slot></slot>
|
|
|
|
</div>
|
|
|
|
<div class="p-dialog-footer" v-if="footer || $slots.footer">
|
|
|
|
<slot name="footer">{{footer}}</slot>
|
2019-01-31 12:15:32 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
2020-01-08 10:51:56 +00:00
|
|
|
</transition>
|
|
|
|
</div>
|
2019-01-31 12:15:32 +00:00
|
|
|
</template>
|
|
|
|
<script>
|
2019-12-26 11:24:53 +00:00
|
|
|
import UniqueComponentId from '../utils/UniqueComponentId';
|
2019-01-31 12:15:32 +00:00
|
|
|
import DomHandler from '../utils/DomHandler';
|
|
|
|
export default {
|
2020-01-08 10:51:56 +00:00
|
|
|
inheritAttrs: false,
|
2019-01-31 12:15:32 +00:00
|
|
|
props: {
|
2020-01-20 10:54:26 +00:00
|
|
|
header: null,
|
|
|
|
footer: null,
|
2019-01-31 12:15:32 +00:00
|
|
|
visible: Boolean,
|
|
|
|
modal: Boolean,
|
2020-01-20 10:54:26 +00:00
|
|
|
contentStyle: null,
|
2019-01-31 12:15:32 +00:00
|
|
|
rtl: Boolean,
|
|
|
|
closable: {
|
|
|
|
type: Boolean,
|
|
|
|
default: true
|
|
|
|
},
|
|
|
|
showHeader: {
|
|
|
|
type: Boolean,
|
|
|
|
default: true
|
|
|
|
},
|
|
|
|
baseZIndex: {
|
|
|
|
type: Number,
|
|
|
|
default: 0
|
|
|
|
},
|
|
|
|
autoZIndex: {
|
|
|
|
type: Boolean,
|
|
|
|
default: true
|
2019-12-26 11:24:53 +00:00
|
|
|
},
|
|
|
|
ariaCloseLabel: {
|
|
|
|
type: String,
|
|
|
|
default: 'close'
|
2019-01-31 15:42:58 +00:00
|
|
|
}
|
2019-01-31 12:15:32 +00:00
|
|
|
},
|
2020-01-08 10:51:56 +00:00
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
dialogClasses: null,
|
2020-01-17 13:27:16 +00:00
|
|
|
dialogStyles: null,
|
2020-01-20 10:54:26 +00:00
|
|
|
isMaskVisible: this.visible
|
2020-01-08 10:51:56 +00:00
|
|
|
}
|
|
|
|
},
|
2019-11-01 08:30:06 +00:00
|
|
|
documentKeydownListener: null,
|
2020-01-08 10:51:56 +00:00
|
|
|
updated() {
|
|
|
|
if (this.$refs.mask) {
|
|
|
|
this.dialogClasses = this.$vnode.data.class;
|
|
|
|
this.dialogStyles = this.$vnode.data.style;
|
|
|
|
DomHandler.removeClass(this.$refs.mask, this.$vnode.data.class);
|
|
|
|
if (this.$vnode.data.style) {
|
|
|
|
Object.keys(this.$vnode.data.style).forEach((key) => {
|
|
|
|
this.$refs.mask.style[key] = '';
|
|
|
|
});
|
|
|
|
}
|
2019-11-01 08:32:32 +00:00
|
|
|
}
|
2020-01-20 10:54:26 +00:00
|
|
|
|
|
|
|
if (this.visible && !this.isMaskVisible) {
|
|
|
|
this.isMaskVisible = true;
|
|
|
|
}
|
2019-11-01 08:30:06 +00:00
|
|
|
},
|
2020-01-08 10:51:56 +00:00
|
|
|
beforeDestroy() {
|
|
|
|
this.disableModality();
|
|
|
|
},
|
2019-01-31 12:15:32 +00:00
|
|
|
methods: {
|
2019-01-31 15:42:58 +00:00
|
|
|
close() {
|
2020-01-20 10:54:26 +00:00
|
|
|
this.$emit('update:visible', false);
|
2019-01-31 12:15:32 +00:00
|
|
|
},
|
2020-01-20 10:54:26 +00:00
|
|
|
onBeforeEnter(el) {
|
2019-01-31 12:15:32 +00:00
|
|
|
if (this.autoZIndex) {
|
2020-01-20 10:54:26 +00:00
|
|
|
el.style.zIndex = String(this.baseZIndex + DomHandler.generateZIndex());
|
2019-01-31 12:15:32 +00:00
|
|
|
}
|
2020-01-20 10:54:26 +00:00
|
|
|
},
|
|
|
|
onEnter() {
|
|
|
|
this.$refs.mask.style.zIndex = String(parseInt(this.$refs.container.style.zIndex, 10) - 1);
|
2020-01-08 10:51:56 +00:00
|
|
|
|
2020-01-20 10:54:26 +00:00
|
|
|
this.$emit('show');
|
|
|
|
this.focus();
|
2020-01-08 10:51:56 +00:00
|
|
|
this.enableModality();
|
2019-01-31 12:15:32 +00:00
|
|
|
},
|
2020-01-20 10:54:26 +00:00
|
|
|
onLeave(el, done) {
|
2019-01-31 12:15:32 +00:00
|
|
|
this.$emit('hide');
|
|
|
|
|
2020-01-20 10:54:26 +00:00
|
|
|
done();
|
|
|
|
},
|
|
|
|
onAfterLeave() {
|
|
|
|
this.isMaskVisible = false;
|
2020-01-08 10:51:56 +00:00
|
|
|
this.disableModality();
|
2019-01-31 12:15:32 +00:00
|
|
|
},
|
2019-12-09 14:48:23 +00:00
|
|
|
onAppear() {
|
2020-01-20 10:54:26 +00:00
|
|
|
if (this.visible) {
|
2019-12-09 14:48:23 +00:00
|
|
|
this.onEnter();
|
|
|
|
}
|
|
|
|
},
|
2019-01-31 12:15:32 +00:00
|
|
|
focus() {
|
|
|
|
let focusable = DomHandler.findSingle(this.$refs.container, 'input,button');
|
|
|
|
if (focusable) {
|
|
|
|
focusable.focus();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
enableModality() {
|
2020-01-08 10:51:56 +00:00
|
|
|
if (this.modal) {
|
2019-01-31 12:15:32 +00:00
|
|
|
DomHandler.addClass(document.body, 'p-overflow-hidden');
|
2019-11-01 08:30:06 +00:00
|
|
|
this.bindDocumentKeydownListener();
|
2019-01-31 12:15:32 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
disableModality() {
|
2020-01-08 10:51:56 +00:00
|
|
|
if (this.modal) {
|
2019-01-31 12:15:32 +00:00
|
|
|
DomHandler.removeClass(document.body, 'p-overflow-hidden');
|
2019-11-01 08:30:06 +00:00
|
|
|
this.unbindDocumentKeydownListener();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
onKeyDown(event) {
|
|
|
|
if (event.which === 9) {
|
|
|
|
event.preventDefault();
|
|
|
|
let focusableElements = DomHandler.getFocusableElements(this.$refs.container);
|
|
|
|
if (focusableElements && focusableElements.length > 0) {
|
|
|
|
if (!document.activeElement) {
|
|
|
|
focusableElements[0].focus();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
let focusedIndex = focusableElements.indexOf(document.activeElement);
|
|
|
|
if (event.shiftKey) {
|
|
|
|
if (focusedIndex == -1 || focusedIndex === 0)
|
|
|
|
focusableElements[focusableElements.length - 1].focus();
|
|
|
|
else
|
|
|
|
focusableElements[focusedIndex - 1].focus();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (focusedIndex == -1 || focusedIndex === (focusableElements.length - 1))
|
|
|
|
focusableElements[0].focus();
|
|
|
|
else
|
|
|
|
focusableElements[focusedIndex + 1].focus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
bindDocumentKeydownListener() {
|
|
|
|
if (!this.documentKeydownListener) {
|
|
|
|
this.documentKeydownListener = this.onKeyDown.bind(this);
|
|
|
|
window.document.addEventListener('keydown', this.documentKeydownListener);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
unbindDocumentKeydownListener() {
|
|
|
|
if (this.documentKeydownListener) {
|
|
|
|
window.document.removeEventListener('keydown', this.documentKeydownListener);
|
|
|
|
this.documentKeydownListener = null;
|
2019-01-31 12:15:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
computed: {
|
2020-01-08 10:51:56 +00:00
|
|
|
listeners() {
|
|
|
|
return {
|
|
|
|
...this.$listeners
|
|
|
|
};
|
|
|
|
},
|
|
|
|
wrapperClass() {
|
|
|
|
return ['p-dialog-wrapper', {
|
|
|
|
'p-component-overlay p-dialog-mask p-fadein': this.modal
|
|
|
|
}];
|
|
|
|
},
|
2019-01-31 12:15:32 +00:00
|
|
|
containerClass() {
|
|
|
|
return ['p-dialog p-component', {
|
|
|
|
'p-dialog-rtl': this.rtl
|
2020-01-08 10:51:56 +00:00
|
|
|
}, this.dialogClasses];
|
|
|
|
},
|
|
|
|
containerStyle() {
|
|
|
|
return this.dialogStyles;
|
2019-12-26 11:24:53 +00:00
|
|
|
},
|
|
|
|
ariaId() {
|
|
|
|
return UniqueComponentId();
|
|
|
|
},
|
|
|
|
ariaLabelledById() {
|
|
|
|
return this.header != null ? this.ariaId + '_header' : null;
|
2019-01-31 12:15:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
2019-05-25 21:13:31 +00:00
|
|
|
<style>
|
2020-01-08 10:51:56 +00:00
|
|
|
.p-dialog-wrapper {
|
|
|
|
position: fixed;
|
|
|
|
top: 0;
|
|
|
|
left: 0;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
display: flex;
|
|
|
|
justify-content: center;
|
|
|
|
align-items: center;
|
|
|
|
pointer-events: none;
|
|
|
|
}
|
|
|
|
.p-dialog-wrapper.p-dialog-mask {
|
|
|
|
pointer-events: auto;
|
|
|
|
}
|
2019-05-25 21:13:31 +00:00
|
|
|
.p-dialog {
|
|
|
|
position: fixed;
|
|
|
|
padding: 0;
|
2020-01-08 10:51:56 +00:00
|
|
|
pointer-events: auto;
|
2019-05-25 21:13:31 +00:00
|
|
|
}
|
|
|
|
.p-dialog .p-dialog-titlebar {
|
2020-01-20 10:54:26 +00:00
|
|
|
padding: .5em .75em;
|
2019-05-25 21:13:31 +00:00
|
|
|
position: relative;
|
|
|
|
border: 0;
|
|
|
|
}
|
|
|
|
.p-dialog .p-dialog-content {
|
|
|
|
position: relative;
|
|
|
|
border: 0;
|
|
|
|
padding: .5em .75em;
|
|
|
|
background: none;
|
|
|
|
zoom: 1;
|
|
|
|
}
|
|
|
|
.p-dialog-resizable .p-dialog-content {
|
|
|
|
overflow: auto;
|
|
|
|
}
|
|
|
|
.p-dialog .p-resizable-handle {
|
|
|
|
width: 14px;
|
|
|
|
height: 14px;
|
|
|
|
right: 3px;
|
|
|
|
bottom: 3px;
|
|
|
|
position: absolute;
|
|
|
|
font-size: .1px;
|
|
|
|
display: block;
|
|
|
|
cursor: se-resize;
|
|
|
|
}
|
|
|
|
.p-draggable .p-dialog-titlebar {
|
|
|
|
cursor: move;
|
|
|
|
}
|
|
|
|
.p-dialog .p-dialog-titlebar-icons {
|
|
|
|
float: right;
|
|
|
|
}
|
|
|
|
.p-dialog .p-dialog-titlebar-icons:after {
|
|
|
|
content: "";
|
|
|
|
display: table;
|
|
|
|
clear: both;
|
|
|
|
}
|
|
|
|
.p-dialog .p-dialog-titlebar-icon {
|
|
|
|
text-decoration: none;
|
|
|
|
padding: .125em;
|
|
|
|
cursor: pointer;
|
|
|
|
display: inline-block;
|
|
|
|
vertical-align: middle;
|
|
|
|
border: 1px solid transparent;
|
|
|
|
}
|
|
|
|
.p-dialog .p-dialog-titlebar-icon span {
|
|
|
|
display: block;
|
|
|
|
margin: 0;
|
|
|
|
}
|
|
|
|
.p-dialog-footer {
|
|
|
|
padding: 1em;
|
|
|
|
text-align: right;
|
|
|
|
}
|
|
|
|
/* ConfirmDialog */
|
|
|
|
.p-confirmdialog {
|
|
|
|
width: 30em;
|
|
|
|
}
|
|
|
|
.p-confirmdialog.p-dialog .p-dialog-content {
|
|
|
|
padding: 1em 2em;
|
|
|
|
}
|
|
|
|
.p-confirmdialog .p-dialog-content .p-confirmdialog-icon {
|
|
|
|
font-size: 1.5em;
|
|
|
|
vertical-align: middle;
|
|
|
|
margin-right: .5em;
|
|
|
|
}
|
|
|
|
.p-confirmdialog .p-dialog-content .p-confirmdialog-message {
|
|
|
|
vertical-align: middle;
|
|
|
|
}
|
|
|
|
/* Fluid */
|
|
|
|
.p-fluid .p-dialog-footer .p-button {
|
|
|
|
width: auto;
|
|
|
|
}
|
|
|
|
/* RTL */
|
|
|
|
.p-rtl .p-dialog .p-dialog-titlebar-close {
|
|
|
|
float: left;
|
|
|
|
}
|
|
|
|
.p-rtl .p-dialog .p-dialog-footer {
|
|
|
|
text-align: left;
|
|
|
|
}
|
|
|
|
@media screen and (max-width: 40em) {
|
|
|
|
.p-confirmdialog {
|
|
|
|
width: 90%;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Animation */
|
|
|
|
.p-dialog-enter-active {
|
2020-01-08 10:51:56 +00:00
|
|
|
top: 50%;
|
|
|
|
left: 50%;
|
|
|
|
transform: translateX(-50%) translateY(-50%);
|
2019-05-25 21:13:31 +00:00
|
|
|
transition: all 150ms cubic-bezier(0, 0, 0.2, 1);
|
|
|
|
}
|
|
|
|
.p-dialog-leave-active {
|
2020-01-08 10:51:56 +00:00
|
|
|
top: 50%;
|
|
|
|
left: 50%;
|
|
|
|
transform: translateX(-50%) translateY(-50%);
|
2019-05-25 21:13:31 +00:00
|
|
|
transition: all 75ms cubic-bezier(0.4, 0.0, 0.2, 1);
|
|
|
|
}
|
|
|
|
.p-dialog-enter,
|
|
|
|
.p-dialog-leave-to {
|
|
|
|
opacity: 0;
|
|
|
|
transform: translateX(-50%) translateY(-50%) scale(0.7);
|
|
|
|
}
|
|
|
|
/* Maximize */
|
|
|
|
.p-dialog-maximized {
|
|
|
|
-webkit-transition: none;
|
|
|
|
transition: none;
|
|
|
|
transform: none;
|
|
|
|
width: 100vw !important;
|
|
|
|
top: 0;
|
|
|
|
left: 0;
|
|
|
|
}
|
|
|
|
.p-dialog-maximized .p-dialog-content {
|
|
|
|
-webkit-transition: height .3s;
|
|
|
|
transition: height .3s;
|
|
|
|
}
|
2020-01-17 13:27:16 +00:00
|
|
|
</style>
|