Fixed #1169 - Customizable ZIndex Layering

pull/1088/head
Cagatay Civici 2021-04-13 16:59:08 +03:00
parent 3d72768811
commit b910825a84
25 changed files with 324 additions and 106 deletions

View File

@ -15,7 +15,7 @@
<i class="p-autocomplete-loader pi pi-spinner pi-spin" v-if="searching"></i> <i class="p-autocomplete-loader pi pi-spinner pi-spin" v-if="searching"></i>
<Button ref="dropdownButton" type="button" icon="pi pi-chevron-down" class="p-autocomplete-dropdown" :disabled="$attrs.disabled" @click="onDropdownClick" v-if="dropdown"/> <Button ref="dropdownButton" type="button" icon="pi pi-chevron-down" class="p-autocomplete-dropdown" :disabled="$attrs.disabled" @click="onDropdownClick" v-if="dropdown"/>
<Teleport :to="appendTo"> <Teleport :to="appendTo">
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave"> <transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave" @after-leave="onOverlayAfterLeave">
<div :ref="overlayRef" class="p-autocomplete-panel p-component" :style="{'max-height': scrollHeight}" v-if="overlayVisible" @click="onOverlayClick"> <div :ref="overlayRef" class="p-autocomplete-panel p-component" :style="{'max-height': scrollHeight}" v-if="overlayVisible" @click="onOverlayClick">
<slot name="header" :value="modelValue" :suggestions="suggestions"></slot> <slot name="header" :value="modelValue" :suggestions="suggestions"></slot>
<ul :id="listId" class="p-autocomplete-items" role="listbox"> <ul :id="listId" class="p-autocomplete-items" role="listbox">
@ -43,7 +43,7 @@
</template> </template>
<script> <script>
import {ConnectedOverlayScrollHandler,UniqueComponentId,ObjectUtils,DomHandler} from 'primevue/utils'; import {ConnectedOverlayScrollHandler,UniqueComponentId,ObjectUtils,DomHandler,ZIndexUtils} from 'primevue/utils';
import OverlayEventBus from 'primevue/overlayeventbus'; import OverlayEventBus from 'primevue/overlayeventbus';
import Button from 'primevue/button'; import Button from 'primevue/button';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
@ -134,7 +134,11 @@ export default {
this.scrollHandler.destroy(); this.scrollHandler.destroy();
this.scrollHandler = null; this.scrollHandler = null;
} }
if (this.overlay) {
ZIndexUtils.clear(this.overlay);
this.overlay = null; this.overlay = null;
}
}, },
updated() { updated() {
if (this.overlayVisible) { if (this.overlayVisible) {
@ -151,8 +155,8 @@ export default {
getOptionGroupChildren(optionGroup) { getOptionGroupChildren(optionGroup) {
return ObjectUtils.resolveFieldData(optionGroup, this.optionGroupChildren); return ObjectUtils.resolveFieldData(optionGroup, this.optionGroupChildren);
}, },
onOverlayEnter() { onOverlayEnter(el) {
this.overlay.style.zIndex = String(DomHandler.generateZIndex()); ZIndexUtils.set('overlay', el, this.$primevue.config.zIndex.overlay);
this.alignOverlay(); this.alignOverlay();
this.bindOutsideClickListener(); this.bindOutsideClickListener();
this.bindScrollListener(); this.bindScrollListener();
@ -164,6 +168,9 @@ export default {
this.unbindResizeListener(); this.unbindResizeListener();
this.overlay = null; this.overlay = null;
}, },
onOverlayAfterLeave(el) {
ZIndexUtils.clear(el);
},
alignOverlay() { alignOverlay() {
let target = this.multiple ? this.$refs.multiContainer : this.$refs.input; let target = this.multiple ? this.$refs.multiContainer : this.$refs.input;
this.overlay.style.minWidth = DomHandler.getOuterWidth(target) + 'px'; this.overlay.style.minWidth = DomHandler.getOuterWidth(target) + 'px';

View File

@ -4,7 +4,7 @@
:class="inputClass" :style="inputStyle" /> :class="inputClass" :style="inputStyle" />
<CalendarButton v-if="showIcon" :icon="icon" tabindex="-1" class="p-datepicker-trigger" :disabled="$attrs.disabled" @click="onButtonClick" type="button" :aria-label="inputFieldValue"/> <CalendarButton v-if="showIcon" :icon="icon" tabindex="-1" class="p-datepicker-trigger" :disabled="$attrs.disabled" @click="onButtonClick" type="button" :aria-label="inputFieldValue"/>
<Teleport :to="appendTo" :disabled="inline"> <Teleport :to="appendTo" :disabled="inline">
<transition name="p-connected-overlay" @enter="onOverlayEnter($event)" @after-enter="onOverlayEnterComplete" @leave="onOverlayLeave"> <transition name="p-connected-overlay" @enter="onOverlayEnter($event)" @after-enter="onOverlayEnterComplete" @after-leave="onOverlayAfterLeave" @leave="onOverlayLeave">
<div :ref="overlayRef" :class="panelStyleClass" v-if="inline ? true : overlayVisible" :role="inline ? null : 'dialog'" @click="onOverlayClick"> <div :ref="overlayRef" :class="panelStyleClass" v-if="inline ? true : overlayVisible" :role="inline ? null : 'dialog'" @click="onOverlayClick">
<template v-if="!timeOnly"> <template v-if="!timeOnly">
<div class="p-datepicker-group-container"> <div class="p-datepicker-group-container">
@ -133,7 +133,7 @@
</template> </template>
<script> <script>
import {ConnectedOverlayScrollHandler,DomHandler} from 'primevue/utils'; import {ConnectedOverlayScrollHandler,DomHandler,ZIndexUtils} from 'primevue/utils';
import OverlayEventBus from 'primevue/overlayeventbus'; import OverlayEventBus from 'primevue/overlayeventbus';
import InputText from 'primevue/inputtext'; import InputText from 'primevue/inputtext';
import Button from 'primevue/button'; import Button from 'primevue/button';
@ -342,6 +342,10 @@ export default {
this.scrollHandler.destroy(); this.scrollHandler.destroy();
this.scrollHandler = null; this.scrollHandler = null;
} }
if (this.overlay && this.autoZIndex) {
ZIndexUtils.clear(this.overlay);
}
this.overlay = null; this.overlay = null;
}, },
data() { data() {
@ -523,9 +527,12 @@ export default {
return validMin && validMax && validDate && validDay; return validMin && validMax && validDate && validDay;
}, },
onOverlayEnter() { onOverlayEnter(el) {
if (this.autoZIndex) { if (this.autoZIndex) {
this.overlay.style.zIndex = String(this.baseZIndex + DomHandler.generateZIndex()); if (this.touchUI)
ZIndexUtils.set('modal', el, this.baseZIndex || this.$primevue.config.zIndex.modal);
else
ZIndexUtils.set('overlay', el, this.baseZIndex || this.$primevue.config.zIndex.overlay);
} }
this.alignOverlay(); this.alignOverlay();
this.$emit('show'); this.$emit('show');
@ -535,6 +542,11 @@ export default {
this.bindScrollListener(); this.bindScrollListener();
this.bindResizeListener(); this.bindResizeListener();
}, },
onOverlayAfterLeave(el) {
if (this.autoZIndex) {
ZIndexUtils.clear(el);
}
},
onOverlayLeave() { onOverlayLeave() {
this.unbindOutsideClickListener(); this.unbindOutsideClickListener();
this.unbindScrollListener(); this.unbindScrollListener();

View File

@ -13,7 +13,7 @@
<span class="p-cascadeselect-trigger-icon pi pi-chevron-down"></span> <span class="p-cascadeselect-trigger-icon pi pi-chevron-down"></span>
</div> </div>
<Teleport :to="appendTo"> <Teleport :to="appendTo">
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave"> <transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave" @after-leave="onOverlayAfterLeave">
<div :ref="overlayRef" class="p-cascadeselect-panel p-component" v-if="overlayVisible" @click="onOverlayClick"> <div :ref="overlayRef" class="p-cascadeselect-panel p-component" v-if="overlayVisible" @click="onOverlayClick">
<div class="p-cascadeselect-items-wrapper"> <div class="p-cascadeselect-items-wrapper">
<CascadeSelectSub :options="options" :selectionPath="selectionPath" <CascadeSelectSub :options="options" :selectionPath="selectionPath"
@ -28,7 +28,7 @@
</template> </template>
<script> <script>
import {ConnectedOverlayScrollHandler,ObjectUtils,DomHandler} from 'primevue/utils'; import {ConnectedOverlayScrollHandler,ObjectUtils,DomHandler,ZIndexUtils} from 'primevue/utils';
import OverlayEventBus from 'primevue/overlayeventbus'; import OverlayEventBus from 'primevue/overlayeventbus';
import CascadeSelectSub from './CascadeSelectSub.vue'; import CascadeSelectSub from './CascadeSelectSub.vue';
@ -72,7 +72,11 @@ export default {
this.scrollHandler.destroy(); this.scrollHandler.destroy();
this.scrollHandler = null; this.scrollHandler = null;
} }
if (this.overlay) {
ZIndexUtils.clear(this.overlay);
this.overlay = null; this.overlay = null;
}
}, },
mounted() { mounted() {
this.updateSelectionPath(); this.updateSelectionPath();
@ -163,8 +167,8 @@ export default {
this.$refs.focusInput.focus(); this.$refs.focusInput.focus();
} }
}, },
onOverlayEnter() { onOverlayEnter(el) {
this.overlay.style.zIndex = String(DomHandler.generateZIndex()); ZIndexUtils.set('overlay', el, this.$primevue.config.zIndex.overlay);
this.alignOverlay(); this.alignOverlay();
this.bindOutsideClickListener(); this.bindOutsideClickListener();
this.bindScrollListener(); this.bindScrollListener();
@ -179,6 +183,9 @@ export default {
this.overlay = null; this.overlay = null;
this.dirty = false; this.dirty = false;
}, },
onOverlayAfterLeave(el) {
ZIndexUtils.clear(el);
},
alignOverlay() { alignOverlay() {
DomHandler.absolutePosition(this.overlay, this.$el); DomHandler.absolutePosition(this.overlay, this.$el);
this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$el) + 'px'; this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$el) + 'px';

View File

@ -3,7 +3,7 @@
<input ref="input" type="text" :class="inputClass" readonly="readonly" :tabindex="tabindex" :disabled="disabled" <input ref="input" type="text" :class="inputClass" readonly="readonly" :tabindex="tabindex" :disabled="disabled"
@click="onInputClick" @keydown="onInputKeydown" v-if="!inline" :aria-labelledby="ariaLabelledBy"/> @click="onInputClick" @keydown="onInputKeydown" v-if="!inline" :aria-labelledby="ariaLabelledBy"/>
<Teleport to="body" :disabled="inline"> <Teleport to="body" :disabled="inline">
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave"> <transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave" @after-leave="onOverlayAfterLeave">
<div :ref="pickerRef" :class="pickerClass" v-if="inline ? true : overlayVisible" @click="onOverlayClick"> <div :ref="pickerRef" :class="pickerClass" v-if="inline ? true : overlayVisible" @click="onOverlayClick">
<div class="p-colorpicker-content"> <div class="p-colorpicker-content">
<div :ref="colorSelectorRef" class="p-colorpicker-color-selector" @mousedown="onColorMousedown($event)" <div :ref="colorSelectorRef" class="p-colorpicker-color-selector" @mousedown="onColorMousedown($event)"
@ -24,7 +24,7 @@
</template> </template>
<script> <script>
import {ConnectedOverlayScrollHandler,DomHandler} from 'primevue/utils'; import {ConnectedOverlayScrollHandler,DomHandler,ZIndexUtils} from 'primevue/utils';
import OverlayEventBus from 'primevue/overlayeventbus'; import OverlayEventBus from 'primevue/overlayeventbus';
export default { export default {
@ -95,6 +95,11 @@ export default {
this.scrollHandler.destroy(); this.scrollHandler.destroy();
this.scrollHandler = null; this.scrollHandler = null;
} }
if (this.picker && this.autoZIndex) {
ZIndexUtils.clear(this.picker);
}
this.clearRefs(); this.clearRefs();
}, },
mounted() { mounted() {
@ -333,7 +338,7 @@ export default {
return hsb; return hsb;
}, },
onOverlayEnter() { onOverlayEnter(el) {
this.updateUI(); this.updateUI();
this.alignOverlay(); this.alignOverlay();
this.bindOutsideClickListener(); this.bindOutsideClickListener();
@ -341,7 +346,7 @@ export default {
this.bindResizeListener(); this.bindResizeListener();
if (this.autoZIndex) { if (this.autoZIndex) {
this.picker.style.zIndex = String(this.baseZIndex + DomHandler.generateZIndex()); ZIndexUtils.set('overlay', el, this.$primevue.config.zIndex.overlay);
} }
}, },
onOverlayLeave() { onOverlayLeave() {
@ -350,6 +355,11 @@ export default {
this.unbindResizeListener(); this.unbindResizeListener();
this.clearRefs(); this.clearRefs();
}, },
onOverlayAfterLeave(el) {
if (this.autoZIndex) {
ZIndexUtils.clear(el);
}
},
alignOverlay() { alignOverlay() {
DomHandler.absolutePosition(this.picker, this.$refs.input); DomHandler.absolutePosition(this.picker, this.$refs.input);
}, },

View File

@ -69,6 +69,12 @@ const defaultOptions = {
FilterMatchMode.DATE_BEFORE, FilterMatchMode.DATE_BEFORE,
FilterMatchMode.DATE_AFTER FilterMatchMode.DATE_AFTER
] ]
},
zIndex: {
modal: 1100,
overlay: 1000,
menu: 1000,
tooltip: 1100
} }
}; };

View File

@ -1,6 +1,6 @@
<template> <template>
<Teleport to="body"> <Teleport to="body">
<transition name="p-confirm-popup" @enter="onEnter" @leave="onLeave"> <transition name="p-confirm-popup" @enter="onEnter" @leave="onLeave" @after-leave="onAfterLeave">
<div class="p-confirm-popup p-component" v-if="visible" :ref="containerRef" v-bind="$attrs" @click="onOverlayClick"> <div class="p-confirm-popup p-component" v-if="visible" :ref="containerRef" v-bind="$attrs" @click="onOverlayClick">
<div class="p-confirm-popup-content"> <div class="p-confirm-popup-content">
<i :class="iconClass" /> <i :class="iconClass" />
@ -17,7 +17,7 @@
<script> <script>
import ConfirmationEventBus from 'primevue/confirmationeventbus'; import ConfirmationEventBus from 'primevue/confirmationeventbus';
import {ConnectedOverlayScrollHandler,DomHandler} from 'primevue/utils'; import {ConnectedOverlayScrollHandler,DomHandler,ZIndexUtils} from 'primevue/utils';
import OverlayEventBus from 'primevue/overlayeventbus'; import OverlayEventBus from 'primevue/overlayeventbus';
import Button from 'primevue/button'; import Button from 'primevue/button';
@ -65,8 +65,13 @@ export default {
this.scrollHandler = null; this.scrollHandler = null;
} }
this.unbindResizeListener(); this.unbindResizeListener();
this.target = null;
if (this.container) {
ZIndexUtils.clear(this.container);
this.container = null; this.container = null;
}
this.target = null;
this.confirmation = null; this.confirmation = null;
}, },
methods: { methods: {
@ -84,18 +89,22 @@ export default {
this.visible = false; this.visible = false;
}, },
onEnter() { onEnter(el) {
this.alignOverlay(); this.alignOverlay();
this.bindOutsideClickListener(); this.bindOutsideClickListener();
this.bindScrollListener(); this.bindScrollListener();
this.bindResizeListener(); this.bindResizeListener();
this.container.style.zIndex = String(this.baseZIndex + DomHandler.generateZIndex());
ZIndexUtils.set('overlay', el, this.$primevue.config.zIndex.overlay);
}, },
onLeave() { onLeave() {
this.unbindOutsideClickListener(); this.unbindOutsideClickListener();
this.unbindScrollListener(); this.unbindScrollListener();
this.unbindResizeListener(); this.unbindResizeListener();
}, },
onAfterLeave(el) {
ZIndexUtils.clear(el);
},
alignOverlay() { alignOverlay() {
DomHandler.absolutePosition(this.container, this.target); DomHandler.absolutePosition(this.container, this.target);

View File

@ -1,6 +1,6 @@
<template> <template>
<Teleport :to="appendTo"> <Teleport :to="appendTo">
<transition name="p-contextmenu" @enter="onEnter" @leave="onLeave"> <transition name="p-contextmenu" @enter="onEnter" @leave="onLeave" @after-leave="onAfterLeave">
<div :ref="containerRef" class="p-contextmenu p-component" v-if="visible" v-bind="$attrs"> <div :ref="containerRef" class="p-contextmenu p-component" v-if="visible" v-bind="$attrs">
<ContextMenuSub :model="model" :root="true" @leaf-click="onLeafClick" /> <ContextMenuSub :model="model" :root="true" @leaf-click="onLeafClick" />
</div> </div>
@ -9,7 +9,7 @@
</template> </template>
<script> <script>
import {DomHandler} from 'primevue/utils'; import {DomHandler,ZIndexUtils} from 'primevue/utils';
import ContextMenuSub from './ContextMenuSub.vue'; import ContextMenuSub from './ContextMenuSub.vue';
export default { export default {
@ -52,6 +52,10 @@ export default {
this.unbindResizeListener(); this.unbindResizeListener();
this.unbindOutsideClickListener(); this.unbindOutsideClickListener();
this.unbindDocumentContextMenuListener(); this.unbindDocumentContextMenuListener();
if (this.container && this.autoZIndex) {
ZIndexUtils.clear(this.container);
}
this.container = null; this.container = null;
}, },
mounted() { mounted() {
@ -92,19 +96,24 @@ export default {
hide() { hide() {
this.visible = false; this.visible = false;
}, },
onEnter() { onEnter(el) {
this.position(); this.position();
this.bindOutsideClickListener(); this.bindOutsideClickListener();
this.bindResizeListener(); this.bindResizeListener();
if (this.autoZIndex) { if (this.autoZIndex) {
this.container.style.zIndex = String(this.baseZIndex + DomHandler.generateZIndex()); ZIndexUtils.set('menu', el, this.baseZIndex + this.$primevue.config.zIndex.menu);
} }
}, },
onLeave() { onLeave() {
this.unbindOutsideClickListener(); this.unbindOutsideClickListener();
this.unbindResizeListener(); this.unbindResizeListener();
}, },
onAfterLeave(el) {
if (this.autoZIndex) {
ZIndexUtils.clear(el);
}
},
position() { position() {
let left = this.pageX + 1; let left = this.pageX + 1;
let top = this.pageY + 1; let top = this.pageY + 1;

View File

@ -29,7 +29,7 @@
</template> </template>
<script> <script>
import {UniqueComponentId,DomHandler} from 'primevue/utils'; import {UniqueComponentId,DomHandler,ZIndexUtils} from 'primevue/utils';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
export default { export default {
@ -95,8 +95,13 @@ export default {
beforeUnmount() { beforeUnmount() {
this.unbindDocumentState(); this.unbindDocumentState();
this.destroyStyle(); this.destroyStyle();
this.container = null;
this.mask = null; this.mask = null;
if (this.container && this.autoZIndex) {
ZIndexUtils.clear(this.container);
}
this.container = null;
}, },
mounted() { mounted() {
if (this.breakpoints) { if (this.breakpoints) {
@ -109,7 +114,7 @@ export default {
}, },
onBeforeEnter(el) { onBeforeEnter(el) {
if (this.autoZIndex) { if (this.autoZIndex) {
el.style.zIndex = String(this.baseZIndex + DomHandler.generateZIndex()); ZIndexUtils.set('modal', el, this.baseZIndex + this.$primevue.config.zIndex.modal);
} }
el.setAttribute(this.attributeSelector, ''); el.setAttribute(this.attributeSelector, '');
@ -127,7 +132,10 @@ export default {
onLeave() { onLeave() {
this.$emit('hide'); this.$emit('hide');
}, },
onAfterLeave() { onAfterLeave(el) {
if (this.autoZIndex) {
ZIndexUtils.clear(el);
}
this.containerVisible = false; this.containerVisible = false;
this.unbindDocumentState(); this.unbindDocumentState();
}, },

View File

@ -14,7 +14,7 @@
<span class="p-dropdown-trigger-icon pi pi-chevron-down"></span> <span class="p-dropdown-trigger-icon pi pi-chevron-down"></span>
</div> </div>
<Teleport :to="appendTo"> <Teleport :to="appendTo">
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave"> <transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave" @after-leave="onOverlayAfterLeave">
<div :ref="overlayRef" class="p-dropdown-panel p-component" v-if="overlayVisible" @click="onOverlayClick"> <div :ref="overlayRef" class="p-dropdown-panel p-component" v-if="overlayVisible" @click="onOverlayClick">
<slot name="header" :value="modelValue" :options="visibleOptions"></slot> <slot name="header" :value="modelValue" :options="visibleOptions"></slot>
<div class="p-dropdown-header" v-if="filter"> <div class="p-dropdown-header" v-if="filter">
@ -58,7 +58,7 @@
</template> </template>
<script> <script>
import {ConnectedOverlayScrollHandler,ObjectUtils,DomHandler} from 'primevue/utils'; import {ConnectedOverlayScrollHandler,ObjectUtils,DomHandler,ZIndexUtils} from 'primevue/utils';
import OverlayEventBus from 'primevue/overlayeventbus'; import OverlayEventBus from 'primevue/overlayeventbus';
import {FilterService} from 'primevue/api'; import {FilterService} from 'primevue/api';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
@ -133,8 +133,13 @@ export default {
this.scrollHandler.destroy(); this.scrollHandler.destroy();
this.scrollHandler = null; this.scrollHandler = null;
} }
this.itemsWrapper = null; this.itemsWrapper = null;
if (this.overlay) {
ZIndexUtils.clear(this.overlay);
this.overlay = null; this.overlay = null;
}
}, },
methods: { methods: {
getOptionLabel(option) { getOptionLabel(option) {
@ -386,8 +391,8 @@ export default {
onEditableInput(event) { onEditableInput(event) {
this.$emit('update:modelValue', event.target.value); this.$emit('update:modelValue', event.target.value);
}, },
onOverlayEnter() { onOverlayEnter(el) {
this.overlay.style.zIndex = String(DomHandler.generateZIndex()); ZIndexUtils.set('overlay', el, this.$primevue.config.zIndex.overlay);
this.scrollValueInView(); this.scrollValueInView();
this.alignOverlay(); this.alignOverlay();
this.bindOutsideClickListener(); this.bindOutsideClickListener();
@ -408,6 +413,9 @@ export default {
this.itemsWrapper = null; this.itemsWrapper = null;
this.overlay = null; this.overlay = null;
}, },
onOverlayAfterLeave(el) {
ZIndexUtils.clear(el);
},
alignOverlay() { alignOverlay() {
this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$el) + 'px'; this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$el) + 'px';
DomHandler.absolutePosition(this.overlay, this.$el); DomHandler.absolutePosition(this.overlay, this.$el);

View File

@ -11,7 +11,7 @@
<script> <script>
import GalleriaContent from './GalleriaContent.vue'; import GalleriaContent from './GalleriaContent.vue';
import {DomHandler} from 'primevue/utils'; import {DomHandler,ZIndexUtils} from 'primevue/utils';
export default { export default {
inheritAttrs: false, inheritAttrs: false,
@ -131,21 +131,25 @@ export default {
DomHandler.removeClass(document.body, 'p-overflow-hidden'); DomHandler.removeClass(document.body, 'p-overflow-hidden');
} }
this.container = null;
this.mask = null; this.mask = null;
if (this.container) {
ZIndexUtils.clear(this.container);
this.container = null;
}
}, },
methods: { methods: {
onBeforeEnter(el) { onBeforeEnter(el) {
el.style.zIndex = String(this.baseZIndex + DomHandler.generateZIndex()); ZIndexUtils.set('modal', el, this.baseZIndex || this.$primevue.config.zIndex.modal);
}, },
onEnter() { onEnter(el) {
this.mask.style.zIndex = String(this.baseZIndex + DomHandler.generateZIndex()); this.mask.style.zIndex = String(parseInt(el.style.zIndex, 10) - 1);
DomHandler.addClass(document.body, 'p-overflow-hidden'); DomHandler.addClass(document.body, 'p-overflow-hidden');
}, },
onBeforeLeave() { onBeforeLeave() {
DomHandler.addClass(this.mask, 'p-galleria-mask-leave'); DomHandler.addClass(this.mask, 'p-galleria-mask-leave');
}, },
onAfterLeave() { onAfterLeave(el) {
ZIndexUtils.clear(el);
this.containerVisible = false; this.containerVisible = false;
DomHandler.removeClass(document.body, 'p-overflow-hidden'); DomHandler.removeClass(document.body, 'p-overflow-hidden');
}, },

View File

@ -1,6 +1,6 @@
<template> <template>
<Teleport :to="appendTo" :disabled="!popup"> <Teleport :to="appendTo" :disabled="!popup">
<transition name="p-connected-overlay" @enter="onEnter" @leave="onLeave"> <transition name="p-connected-overlay" @enter="onEnter" @leave="onLeave" @after-leave="onAfterLeave">
<div :ref="containerRef" :class="containerClass" v-if="popup ? overlayVisible : true" v-bind="$attrs" @click="onOverlayClick"> <div :ref="containerRef" :class="containerClass" v-if="popup ? overlayVisible : true" v-bind="$attrs" @click="onOverlayClick">
<ul class="p-menu-list p-reset" role="menu"> <ul class="p-menu-list p-reset" role="menu">
<template v-for="(item, i) of model" :key="item.label + i.toString()"> <template v-for="(item, i) of model" :key="item.label + i.toString()">
@ -21,7 +21,7 @@
</template> </template>
<script> <script>
import {ConnectedOverlayScrollHandler,DomHandler} from 'primevue/utils'; import {ConnectedOverlayScrollHandler,DomHandler,ZIndexUtils} from 'primevue/utils';
import OverlayEventBus from 'primevue/overlayeventbus'; import OverlayEventBus from 'primevue/overlayeventbus';
import Menuitem from './Menuitem.vue'; import Menuitem from './Menuitem.vue';
@ -68,6 +68,10 @@ export default {
this.scrollHandler = null; this.scrollHandler = null;
} }
this.target = null; this.target = null;
if (this.container && this.autoZIndex) {
ZIndexUtils.clear(this.container);
}
this.container = null; this.container = null;
}, },
methods: { methods: {
@ -101,14 +105,14 @@ export default {
this.overlayVisible = false; this.overlayVisible = false;
this.target = null; this.target = null;
}, },
onEnter() { onEnter(el) {
this.alignOverlay(); this.alignOverlay();
this.bindOutsideClickListener(); this.bindOutsideClickListener();
this.bindResizeListener(); this.bindResizeListener();
this.bindScrollListener(); this.bindScrollListener();
if (this.autoZIndex) { if (this.autoZIndex) {
this.container.style.zIndex = String(this.baseZIndex + DomHandler.generateZIndex()); ZIndexUtils.set('menu', el, this.baseZIndex + this.$primevue.config.zIndex.menu);
} }
}, },
onLeave() { onLeave() {
@ -116,6 +120,11 @@ export default {
this.unbindResizeListener(); this.unbindResizeListener();
this.unbindScrollListener(); this.unbindScrollListener();
}, },
onAfterLeave(el) {
if (this.autoZIndex) {
ZIndexUtils.clear(el);
}
},
alignOverlay() { alignOverlay() {
DomHandler.absolutePosition(this.container, this.target); DomHandler.absolutePosition(this.container, this.target);
this.container.style.minWidth = DomHandler.getOuterWidth(this.target) + 'px'; this.container.style.minWidth = DomHandler.getOuterWidth(this.target) + 'px';

View File

@ -15,7 +15,7 @@
<script> <script>
import MenubarSub from './MenubarSub.vue'; import MenubarSub from './MenubarSub.vue';
import {DomHandler} from 'primevue/utils'; import {ZIndexUtils} from 'primevue/utils';
export default { export default {
props: { props: {
@ -33,11 +33,21 @@ export default {
beforeUnmount() { beforeUnmount() {
this.mobileActive = false; this.mobileActive = false;
this.unbindOutsideClickListener(); this.unbindOutsideClickListener();
if (this.$refs.rootmenu && this.$refs.rootmenu.$el) {
ZIndexUtils.clear(this.$refs.rootmenu.$el);
}
}, },
methods: { methods: {
toggle(event) { toggle(event) {
this.mobileActive = !this.mobileActive; if (this.mobileActive) {
this.$refs.rootmenu.$el.style.zIndex = String(DomHandler.generateZIndex()); this.mobileActive = false;
ZIndexUtils.clear(this.$refs.rootmenu.$el);
}
else {
this.mobileActive = true;
ZIndexUtils.set('menu', this.$refs.rootmenu.$el, this.$primevue.config.zIndex.menu);
}
this.bindOutsideClickListener(); this.bindOutsideClickListener();
event.preventDefault(); event.preventDefault();
}, },

View File

@ -24,7 +24,7 @@
<span class="p-multiselect-trigger-icon pi pi-chevron-down"></span> <span class="p-multiselect-trigger-icon pi pi-chevron-down"></span>
</div> </div>
<Teleport :to="appendTo"> <Teleport :to="appendTo">
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave"> <transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave" @after-leave="onOverlayAfterLeave">
<div :ref="overlayRef" class="p-multiselect-panel p-component" v-if="overlayVisible" @click="onOverlayClick"> <div :ref="overlayRef" class="p-multiselect-panel p-component" v-if="overlayVisible" @click="onOverlayClick">
<slot name="header" :value="modelValue" :options="visibleOptions"></slot> <slot name="header" :value="modelValue" :options="visibleOptions"></slot>
<div class="p-multiselect-header"> <div class="p-multiselect-header">
@ -93,7 +93,7 @@
</template> </template>
<script> <script>
import {ConnectedOverlayScrollHandler,ObjectUtils,DomHandler} from 'primevue/utils'; import {ConnectedOverlayScrollHandler,ObjectUtils,DomHandler,ZIndexUtils} from 'primevue/utils';
import OverlayEventBus from 'primevue/overlayeventbus'; import OverlayEventBus from 'primevue/overlayeventbus';
import {FilterService} from 'primevue/api'; import {FilterService} from 'primevue/api';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
@ -166,7 +166,11 @@ export default {
this.scrollHandler.destroy(); this.scrollHandler.destroy();
this.scrollHandler = null; this.scrollHandler = null;
} }
if (this.overlay) {
ZIndexUtils.clear(this.overlay);
this.overlay = null; this.overlay = null;
}
}, },
methods: { methods: {
getOptionLabel(option) { getOptionLabel(option) {
@ -340,8 +344,8 @@ export default {
else else
return null; return null;
}, },
onOverlayEnter() { onOverlayEnter(el) {
this.overlay.style.zIndex = String(DomHandler.generateZIndex()); ZIndexUtils.set('overlay', el, this.$primevue.config.zIndex.overlay);
this.alignOverlay(); this.alignOverlay();
this.bindOutsideClickListener(); this.bindOutsideClickListener();
this.bindScrollListener(); this.bindScrollListener();
@ -355,6 +359,9 @@ export default {
this.$emit('hide'); this.$emit('hide');
this.overlay = null; this.overlay = null;
}, },
onOverlayAfterLeave(el) {
ZIndexUtils.clear(el);
},
alignOverlay() { alignOverlay() {
this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$el) + 'px'; this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$el) + 'px';
DomHandler.absolutePosition(this.overlay, this.$el); DomHandler.absolutePosition(this.overlay, this.$el);

View File

@ -1,6 +1,6 @@
<template> <template>
<Teleport :to="appendTo"> <Teleport :to="appendTo">
<transition name="p-overlaypanel" @enter="onEnter" @leave="onLeave"> <transition name="p-overlaypanel" @enter="onEnter" @leave="onLeave" @after-leave="onAfterLeave">
<div class="p-overlaypanel p-component" v-if="visible" :ref="containerRef" v-bind="$attrs" @click="onOverlayClick"> <div class="p-overlaypanel p-component" v-if="visible" :ref="containerRef" v-bind="$attrs" @click="onOverlayClick">
<div class="p-overlaypanel-content" @click="onContentClick"> <div class="p-overlaypanel-content" @click="onContentClick">
<slot></slot> <slot></slot>
@ -14,7 +14,7 @@
</template> </template>
<script> <script>
import {UniqueComponentId,DomHandler,ConnectedOverlayScrollHandler} from 'primevue/utils'; import {UniqueComponentId,DomHandler,ConnectedOverlayScrollHandler,ZIndexUtils} from 'primevue/utils';
import OverlayEventBus from 'primevue/overlayeventbus'; import OverlayEventBus from 'primevue/overlayeventbus';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
@ -74,6 +74,10 @@ export default {
this.destroyStyle(); this.destroyStyle();
this.unbindResizeListener(); this.unbindResizeListener();
this.target = null; this.target = null;
if (this.container && this.autoZIndex) {
ZIndexUtils.clear(this.container);
}
this.container = null; this.container = null;
}, },
mounted() { mounted() {
@ -98,7 +102,7 @@ export default {
onContentClick() { onContentClick() {
this.selfClick = true; this.selfClick = true;
}, },
onEnter() { onEnter(el) {
this.container.setAttribute(this.attributeSelector, ''); this.container.setAttribute(this.attributeSelector, '');
this.alignOverlay(); this.alignOverlay();
if (this.dismissable) { if (this.dismissable) {
@ -109,8 +113,9 @@ export default {
this.bindResizeListener(); this.bindResizeListener();
if (this.autoZIndex) { if (this.autoZIndex) {
this.container.style.zIndex = String(this.baseZIndex + DomHandler.generateZIndex()); ZIndexUtils.set('overlay', el, this.baseZIndex + this.$primevue.config.zIndex.overlay);
} }
OverlayEventBus.on('overlay-click', e => { OverlayEventBus.on('overlay-click', e => {
if (this.container.contains(e.target)) { if (this.container.contains(e.target)) {
this.selfClick = true; this.selfClick = true;
@ -123,6 +128,11 @@ export default {
this.unbindResizeListener(); this.unbindResizeListener();
OverlayEventBus.off('overlay-click'); OverlayEventBus.off('overlay-click');
}, },
onAfterLeave(el) {
if (this.autoZIndex) {
ZIndexUtils.clear(el);
}
},
alignOverlay() { alignOverlay() {
DomHandler.absolutePosition(this.container, this.target); DomHandler.absolutePosition(this.container, this.target);

View File

@ -3,7 +3,7 @@
<PInputText ref="input" :class="inputFieldClass" :style="inputStyle" :type="inputType" :value="modelValue" @input="onInput" @focus="onFocus" @blur="onBlur" @keyup="onKeyUp" v-bind="$attrs" /> <PInputText ref="input" :class="inputFieldClass" :style="inputStyle" :type="inputType" :value="modelValue" @input="onInput" @focus="onFocus" @blur="onBlur" @keyup="onKeyUp" v-bind="$attrs" />
<i v-if="toggleMask" :class="toggleIconClass" @click="onMaskToggle" /> <i v-if="toggleMask" :class="toggleIconClass" @click="onMaskToggle" />
<Teleport :to="appendTo"> <Teleport :to="appendTo">
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave"> <transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave" @after-leave="onOverlayAfterLeave">
<div :ref="overlayRef" class="p-password-panel p-component" v-if="overlayVisible" @click="onOverlayClick"> <div :ref="overlayRef" class="p-password-panel p-component" v-if="overlayVisible" @click="onOverlayClick">
<slot name="header"></slot> <slot name="header"></slot>
<slot name="content"> <slot name="content">
@ -20,7 +20,7 @@
</template> </template>
<script> <script>
import {ConnectedOverlayScrollHandler,DomHandler} from 'primevue/utils'; import {ConnectedOverlayScrollHandler,DomHandler,ZIndexUtils} from 'primevue/utils';
import OverlayEventBus from 'primevue/overlayeventbus'; import OverlayEventBus from 'primevue/overlayeventbus';
import InputText from 'primevue/inputtext'; import InputText from 'primevue/inputtext';
@ -95,10 +95,15 @@ export default {
this.scrollHandler.destroy(); this.scrollHandler.destroy();
this.scrollHandler = null; this.scrollHandler = null;
} }
if (this.overlay) {
ZIndexUtils.clear(this.overlay);
this.overlay = null;
}
}, },
methods: { methods: {
onOverlayEnter() { onOverlayEnter(el) {
this.overlay.style.zIndex = String(DomHandler.generateZIndex()); ZIndexUtils.set('overlay', el, this.$primevue.config.zIndex.overlay);
this.alignOverlay(); this.alignOverlay();
this.bindScrollListener(); this.bindScrollListener();
this.bindResizeListener(); this.bindResizeListener();
@ -108,6 +113,9 @@ export default {
this.unbindResizeListener(); this.unbindResizeListener();
this.overlay = null; this.overlay = null;
}, },
onOverlayAfterLeave(el) {
ZIndexUtils.clear(el);
},
alignOverlay() { alignOverlay() {
this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$refs.input.$el) + 'px'; this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$refs.input.$el) + 'px';
DomHandler.absolutePosition(this.overlay, this.$refs.input.$el); DomHandler.absolutePosition(this.overlay, this.$refs.input.$el);

View File

@ -1,16 +1,17 @@
<template> <template>
<transition name="p-scrolltop" appear @enter="onEnter"> <transition name="p-scrolltop" appear @enter="onEnter" @after-leave="onAfterLeave">
<button :class="containerClass" v-if="visible" @click="onClick" type="button"> <button :ref="containerRef" :class="containerClass" v-if="visible" @click="onClick" type="button">
<span :class="iconClass"></span> <span :class="iconClass"></span>
</button> </button>
</transition> </transition>
</template> </template>
<script> <script>
import {DomHandler} from 'primevue/utils'; import {DomHandler,ZIndexUtils} from 'primevue/utils';
export default { export default {
scrollListener: null, scrollListener: null,
container: null,
data() { data() {
return { return {
visible: false visible: false
@ -45,6 +46,11 @@ export default {
this.unbindDocumentScrollListener(); this.unbindDocumentScrollListener();
else if (this.target === 'parent') else if (this.target === 'parent')
this.unbindParentScrollListener(); this.unbindParentScrollListener();
if (this.container) {
ZIndexUtils.clear(this.container);
this.overlay = null;
}
}, },
methods: { methods: {
onClick() { onClick() {
@ -86,8 +92,14 @@ export default {
this.scrollListener = null; this.scrollListener = null;
} }
}, },
onEnter() { onEnter(el) {
this.$el.style.zIndex = String(DomHandler.generateZIndex()); ZIndexUtils.set('overlay', el, this.$primevue.config.zIndex.overlay);
},
onAfterLeave(el) {
ZIndexUtils.clear(el);
},
containerRef(el) {
this.container = el;
} }
}, },
computed: { computed: {

View File

@ -1,7 +1,7 @@
<template> <template>
<Teleport to="body"> <Teleport to="body">
<transition name="p-sidebar" @enter="onEnter" @leave="onLeave" appear> <transition name="p-sidebar" @enter="onEnter" @leave="onLeave" @after-leave="onAfterLeave" appear>
<div :class="containerClass" v-if="visible" ref="container" role="complementary" :aria-modal="modal" v-bind="$attrs"> <div :class="containerClass" v-if="visible" :ref="containerRef" role="complementary" :aria-modal="modal" v-bind="$attrs">
<div class="p-sidebar-content"> <div class="p-sidebar-content">
<button class="p-sidebar-close p-link" @click="hide" :aria-label="ariaCloseLabel" v-if="showCloseIcon" type="button" v-ripple> <button class="p-sidebar-close p-link" @click="hide" :aria-label="ariaCloseLabel" v-if="showCloseIcon" type="button" v-ripple>
<span class="p-sidebar-close-icon pi pi-times" /> <span class="p-sidebar-close-icon pi pi-times" />
@ -14,7 +14,7 @@
</template> </template>
<script> <script>
import {DomHandler} from 'primevue/utils'; import {DomHandler,ZIndexUtils} from 'primevue/utils';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
export default { export default {
@ -56,18 +56,24 @@ export default {
}, },
mask: null, mask: null,
maskClickListener: null, maskClickListener: null,
container: null,
beforeUnmount() { beforeUnmount() {
this.destroyModal(); this.destroyModal();
if (this.container && this.autoZIndex) {
ZIndexUtils.clear(this.container);
}
this.container = null;
}, },
methods: { methods: {
hide() { hide() {
this.$emit('update:visible', false); this.$emit('update:visible', false);
}, },
onEnter() { onEnter(el) {
this.$emit('show'); this.$emit('show');
if (this.autoZIndex) { if (this.autoZIndex) {
this.$refs.container.style.zIndex = String(this.baseZIndex + DomHandler.generateZIndex()); ZIndexUtils.set('modal', el, this.baseZIndex || this.$primevue.config.zIndex.modal);
} }
this.focus(); this.focus();
if (this.modal && !this.fullScreen) { if (this.modal && !this.fullScreen) {
@ -81,8 +87,13 @@ export default {
this.disableModality(); this.disableModality();
} }
}, },
onAfterLeave(el) {
if (this.autoZIndex) {
ZIndexUtils.clear(el);
}
},
focus() { focus() {
let focusable = DomHandler.findSingle(this.$refs.container, 'input,button'); let focusable = DomHandler.findSingle(this.container, 'input,button');
if (focusable) { if (focusable) {
focusable.focus(); focusable.focus();
} }
@ -91,7 +102,7 @@ export default {
if (!this.mask) { if (!this.mask) {
this.mask = document.createElement('div'); this.mask = document.createElement('div');
this.mask.setAttribute('class', 'p-sidebar-mask'); this.mask.setAttribute('class', 'p-sidebar-mask');
this.mask.style.zIndex = String(parseInt(this.$refs.container.style.zIndex, 10) - 1); this.mask.style.zIndex = String(parseInt(this.container.style.zIndex, 10) - 1);
if (this.dismissable) { if (this.dismissable) {
this.bindMaskClickListener(); this.bindMaskClickListener();
} }
@ -132,6 +143,9 @@ export default {
DomHandler.removeClass(document.body, 'p-overflow-hidden'); DomHandler.removeClass(document.body, 'p-overflow-hidden');
this.mask = null; this.mask = null;
} }
},
containerRef(el) {
this.container = el;
} }
}, },
computed: { computed: {

View File

@ -1,6 +1,6 @@
<template> <template>
<Teleport :to="appendTo" :disabled="!popup"> <Teleport :to="appendTo" :disabled="!popup">
<transition name="p-connected-overlay" @enter="onEnter" @leave="onLeave"> <transition name="p-connected-overlay" @enter="onEnter" @leave="onLeave" @after-leave="onAfterLeave">
<div :ref="containerRef" :class="containerClass" v-if="popup ? visible : true" v-bind="$attrs" @click="onOverlayClick"> <div :ref="containerRef" :class="containerClass" v-if="popup ? visible : true" v-bind="$attrs" @click="onOverlayClick">
<TieredMenuSub :model="model" :root="true" :popup="popup" @leaf-click="onLeafClick"/> <TieredMenuSub :model="model" :root="true" :popup="popup" @leaf-click="onLeafClick"/>
</div> </div>
@ -9,7 +9,7 @@
</template> </template>
<script> <script>
import {ConnectedOverlayScrollHandler,DomHandler} from 'primevue/utils'; import {ConnectedOverlayScrollHandler,DomHandler,ZIndexUtils} from 'primevue/utils';
import OverlayEventBus from 'primevue/overlayeventbus'; import OverlayEventBus from 'primevue/overlayeventbus';
import TieredMenuSub from './TieredMenuSub.vue'; import TieredMenuSub from './TieredMenuSub.vue';
@ -56,6 +56,9 @@ export default {
this.scrollHandler = null; this.scrollHandler = null;
} }
this.target = null; this.target = null;
if (this.container && this.autoZIndex) {
ZIndexUtils.clear(this.container);
}
this.container = null; this.container = null;
}, },
methods: { methods: {
@ -80,14 +83,14 @@ export default {
hide() { hide() {
this.visible = false; this.visible = false;
}, },
onEnter() { onEnter(el) {
this.alignOverlay(); this.alignOverlay();
this.bindOutsideClickListener(); this.bindOutsideClickListener();
this.bindResizeListener(); this.bindResizeListener();
this.bindScrollListener(); this.bindScrollListener();
if (this.autoZIndex) { if (this.autoZIndex) {
this.container.style.zIndex = String(this.baseZIndex + DomHandler.generateZIndex()); ZIndexUtils.set('menu', el, this.baseZIndex + this.$primevue.config.zIndex.menu);
} }
}, },
onLeave() { onLeave() {
@ -95,6 +98,11 @@ export default {
this.unbindResizeListener(); this.unbindResizeListener();
this.unbindScrollListener(); this.unbindScrollListener();
}, },
onAfterLeave(el) {
if (this.autoZIndex) {
ZIndexUtils.clear(el);
}
},
alignOverlay() { alignOverlay() {
DomHandler.absolutePosition(this.container, this.target); DomHandler.absolutePosition(this.container, this.target);
this.container.style.minWidth = DomHandler.getOuterWidth(this.target) + 'px'; this.container.style.minWidth = DomHandler.getOuterWidth(this.target) + 'px';

View File

@ -11,7 +11,7 @@
<script> <script>
import ToastEventBus from 'primevue/toasteventbus'; import ToastEventBus from 'primevue/toasteventbus';
import ToastMessage from './ToastMessage.vue'; import ToastMessage from './ToastMessage.vue';
import {DomHandler} from 'primevue/utils'; import {ZIndexUtils} from 'primevue/utils';
var messageIdx = 0; var messageIdx = 0;
@ -55,10 +55,14 @@ export default {
this.messages = []; this.messages = [];
}); });
this.updateZIndex(); if (this.autoZIndex) {
ZIndexUtils.set('modal', this.$refs.container, this.baseZIndex || this.$primevue.config.zIndex.modal);
}
}, },
beforeUpdate() { beforeUnmount() {
this.updateZIndex(); if (this.$refs.container && this.autoZIndex) {
ZIndexUtils.clear(this.$refs.container);
}
}, },
methods: { methods: {
add(message) { add(message) {
@ -78,11 +82,6 @@ export default {
} }
this.messages.splice(index, 1); this.messages.splice(index, 1);
},
updateZIndex() {
if (this.autoZIndex) {
this.$refs.container.style.zIndex = String(this.baseZIndex + DomHandler.generateZIndex());
}
} }
}, },
components: { components: {

View File

@ -1,6 +1,4 @@
import {UniqueComponentId} from 'primevue/utils'; import {UniqueComponentId,DomHandler,ConnectedOverlayScrollHandler,ZIndexUtils} from 'primevue/utils';
import {DomHandler} from 'primevue/utils';
import {ConnectedOverlayScrollHandler} from 'primevue/utils';
function bindEvents(el) { function bindEvents(el) {
const modifiers = el.$_ptooltipModifiers; const modifiers = el.$_ptooltipModifiers;
@ -72,7 +70,6 @@ function show(el) {
let tooltipElement = create(el); let tooltipElement = create(el);
align(el); align(el);
DomHandler.fadeIn(tooltipElement, 250); DomHandler.fadeIn(tooltipElement, 250);
tooltipElement.style.zIndex = ++DomHandler.zindex;
window.addEventListener('resize', function onWindowResize() { window.addEventListener('resize', function onWindowResize() {
hide(el); hide(el);
@ -80,11 +77,13 @@ function show(el) {
}); });
bindScrollListener(el); bindScrollListener(el);
ZIndexUtils.set('tooltip', tooltipElement, el.$_ptooltipZIndex);
} }
function hide(el) { function hide(el) {
remove(el); remove(el);
unbindScrollListener(el); unbindScrollListener(el);
ZIndexUtils.clear(el);
} }
function getTooltipElement(el) { function getTooltipElement(el) {
@ -245,6 +244,7 @@ const Tooltip = {
let target = getTarget(el); let target = getTarget(el);
target.$_ptooltipModifiers = options.modifiers; target.$_ptooltipModifiers = options.modifiers;
target.$_ptooltipValue = options.value; target.$_ptooltipValue = options.value;
target.$_ptooltipZIndex = options.instance.$primevue && options.instance.$primevue.config && options.instance.$primevue.config.zIndex.tooltip;
bindEvents(target); bindEvents(target);
}, },
unmounted(el) { unmounted(el) {
@ -256,6 +256,8 @@ const Tooltip = {
target.$_ptooltipScrollHandler.destroy(); target.$_ptooltipScrollHandler.destroy();
target.$_ptooltipScrollHandler = null; target.$_ptooltipScrollHandler = null;
} }
ZIndexUtils.clear(el);
}, },
updated(el, options) { updated(el, options) {
let target = getTarget(el); let target = getTarget(el);

View File

@ -23,7 +23,7 @@
<span class="p-treeselect-trigger-icon pi pi-chevron-down"></span> <span class="p-treeselect-trigger-icon pi pi-chevron-down"></span>
</div> </div>
<Teleport :to="appendTo"> <Teleport :to="appendTo">
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave"> <transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave" @after-leave="onOverlayAfterLeave">
<div :ref="overlayRef" v-if="overlayVisible" @click="onOverlayClick" :class="['p-treeselect-panel p-component', panelClass]"> <div :ref="overlayRef" v-if="overlayVisible" @click="onOverlayClick" :class="['p-treeselect-panel p-component', panelClass]">
<slot name="header" :value="modelValue" :options="options"></slot> <slot name="header" :value="modelValue" :options="options"></slot>
<div class="p-treeselect-items-wrapper" :style="{'max-height': scrollHeight}"> <div class="p-treeselect-items-wrapper" :style="{'max-height': scrollHeight}">
@ -43,7 +43,7 @@
</template> </template>
<script> <script>
import {ConnectedOverlayScrollHandler,DomHandler} from 'primevue/utils'; import {ConnectedOverlayScrollHandler,DomHandler,ZIndexUtils} from 'primevue/utils';
import OverlayEventBus from 'primevue/overlayeventbus'; import OverlayEventBus from 'primevue/overlayeventbus';
import Tree from 'primevue/tree'; import Tree from 'primevue/tree';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
@ -121,7 +121,11 @@ export default {
this.scrollHandler.destroy(); this.scrollHandler.destroy();
this.scrollHandler = null; this.scrollHandler = null;
} }
if (this.overlay) {
ZIndexUtils.clear(this.overlay);
this.overlay = null; this.overlay = null;
}
}, },
mounted() { mounted() {
this.updateTreeState(); this.updateTreeState();
@ -204,8 +208,8 @@ export default {
break; break;
} }
}, },
onOverlayEnter() { onOverlayEnter(el) {
this.overlay.style.zIndex = String(DomHandler.generateZIndex()); ZIndexUtils.set('overlay', el, this.$primevue.config.zIndex.overlay);
this.alignOverlay(); this.alignOverlay();
this.bindOutsideClickListener(); this.bindOutsideClickListener();
this.bindScrollListener(); this.bindScrollListener();
@ -219,6 +223,9 @@ export default {
this.$emit('hide'); this.$emit('hide');
this.overlay = null; this.overlay = null;
}, },
onOverlayAfterLeave(el) {
ZIndexUtils.clear(el);
},
alignOverlay() { alignOverlay() {
this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$el) + 'px'; this.overlay.style.minWidth = DomHandler.getOuterWidth(this.$el) + 'px';
DomHandler.absolutePosition(this.overlay, this.$el); DomHandler.absolutePosition(this.overlay, this.$el);

View File

@ -93,15 +93,6 @@ export default class DomHandler {
}; };
} }
static generateZIndex() {
this.zindex = this.zindex||999;
return ++this.zindex;
}
static getCurrentZIndex() {
return this.zindex;
}
static index(element) { static index(element) {
let children = element.parentNode.childNodes; let children = element.parentNode.childNodes;
let num = 0; let num = 0;

View File

@ -1,7 +1,8 @@
import ConnectedOverlayScrollHandler from './ConnectedOverlayScrollHandler'; import ConnectedOverlayScrollHandler from './ConnectedOverlayScrollHandler';
import DomHandler from './DomHandler'; import DomHandler from './DomHandler';
import ObjectUtils from './ObjectUtils'; import ObjectUtils from './ObjectUtils';
import ZIndexUtils from './ZIndexUtils';
import UniqueComponentId from './UniqueComponentId'; import UniqueComponentId from './UniqueComponentId';
import EventBus from './EventBus'; import EventBus from './EventBus';
export {ConnectedOverlayScrollHandler,DomHandler,ObjectUtils,UniqueComponentId,EventBus}; export {ConnectedOverlayScrollHandler,DomHandler,ObjectUtils,ZIndexUtils,UniqueComponentId,EventBus};

View File

@ -0,0 +1,41 @@
function handler() {
let zIndexes = [];
const generateZIndex = (key, baseZIndex) => {
let lastZIndex = zIndexes.length > 0 ? zIndexes[zIndexes.length - 1] : { key, value: baseZIndex };
let newZIndex = lastZIndex.value + (lastZIndex.key === key ? 0 : baseZIndex) + 1;
zIndexes.push({ key, value: newZIndex });
return newZIndex;
}
const revertZIndex = (zIndex) => {
zIndexes = zIndexes.filter(obj => obj.value !== zIndex);
}
const getCurrentZIndex = () => {
return zIndexes.length > 0 ? zIndexes[zIndexes.length - 1].value : 0;
}
const getZIndex = (el) => {
return el ? parseInt(el.style.zIndex, 10) || 0 : 0
}
return {
get: getZIndex,
set: (key, el, baseZIndex) => {
if (el) {
el.style.zIndex = String(generateZIndex(key, baseZIndex));
}
},
clear: (el) => {
if (el) {
revertZIndex(getZIndex(el));
el.style.zIndex = '';
}
},
getCurrent: () => getCurrentZIndex()
};
}
export default handler();

View File

@ -220,6 +220,25 @@ app.use(PrimeVue, {ripple: true});
</code></pre> </code></pre>
<h5>ZIndex Layering</h5>
<p>ZIndexes are managed automatically to make sure layering of overlay components work seamlessly when combining multiple components. Still there may be cases where you'd like to configure
the configure default values such as a custom layout where header section is fixed. In a case like this, dropdown needs to be displayed below the application header but a modal dialog should be displayed above. PrimeVue configuration
offers the <i>zIndex</i> property to customize the default values for components categories. Default values are described below and can be customized when setting up PrimeVue.</p>
<pre v-code.script><code>
import {createApp} from 'vue';
import PrimeVue from 'primevue/config';
const app = createApp(App);
app.use(PrimeVue, {
zIndex: {
modal: 1100, //dialog, sidebar
overlay: 1000, //dropdown, overlaypanel
menu: 1000, //overlay menus
tooltip: 1100 //tooltip
}
});
</code></pre>
<h5>Locale</h5> <h5>Locale</h5>
<p>PrimeVue provides a Locale API to support i18n and l7n, visit the <router-link to="/locale">Locale</router-link> documentation for more information.</p> <p>PrimeVue provides a Locale API to support i18n and l7n, visit the <router-link to="/locale">Locale</router-link> documentation for more information.</p>