-
Notifications
You must be signed in to change notification settings - Fork 95
Open
Description
Occasionally a modal that is opened from inside another modal is not shown on top.
This happens when, in between opening the modals, other components also manipulate the children of the <body> element.
Originally observed in nextcloud/calendar#7822
Demo
Screencast.From.2026-02-12.18-25-21.webm
Steps to Reproduce
Given the following setup:
<template>
<div>
<NcActions
@opened="() => (popoverRemovedFromDom = false)"
@close="onPopoverClose"
>
<NcActionButton>Edit</NcActionButton>
<NcActionButton>Delete</NcActionButton>
</NcActions>
<NcButton @click="() => (outerModal = true)">Show outer modal</NcButton>
<NcModal
v-if="outerModal"
@close="() => (outerModal = false)"
name="Outer Modal"
size="large"
>
<div class="modal__content">
<div v-if="!popoverRemovedFromDom">
The button will be enabled automatically in a few seconds. We are
waiting until the popover is removed from the DOM.
</div>
<NcButton
:disabled="!popoverRemovedFromDom"
@click="() => (nestedModal = true)"
>Show nested modal</NcButton
>
<NcModal
v-if="nestedModal"
@close="() => (nestedModal = false)"
name="Nested Modal"
size="small"
>
<div class="modal__content" style="height: 256px">
Nested modal content
</div>
</NcModal>
</div>
</NcModal>
</div>
</template>
<script>
export default {
data() {
return {
outerModal: false,
nestedModal: false,
popoverRemovedFromDom: true,
};
},
methods: {
onPopoverClose() {
// We used 'close` event, because 'closed' is currently not triggered in v9.
// See https://github.com/nextcloud-libraries/nextcloud-vue/issues/8200
// Also in v8 `closed` does not guarantee that the popover was removed from the DOM.
// So in any case, we just wait a bit to guarantee that the popover was removed, which triggers the bug for modals in v8.
setTimeout(() => {
this.popoverRemovedFromDom = true;
}, 5000);
},
},
};
</script>
<style scoped>
.modal__content {
margin: 64px;
}
</style>- Click on the menu indicator to open the popover
- Click on "Show outer modal"
- Wait until the button "Show nested modal" is enabled
- Click on "Show nested modal"
Actual Behavior
"Outer modal" is on top of "Nested Modal"
Expected Behavior
"Nested Modal" shown on top of "Outer modal".
closed event being emitted.
Environment
- Version
stable8on https://stable8--nextcloud-vue-components.netlify.app - Browser
- Chrome 144
- Firefox 147
Notes
This is caused by how the modals are appended at:
| document.body.insertBefore(this.$el, document.body.lastChild) |
v9 uses <Teleport> from Vue 3 which does not have this issue.
Besides the popover from <NcActions> other components might also trigger this behavior if they append and remove nodes to document.body.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels