Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Opening Healdess UI Dialog (Modal) via another Dialog (Modal) closes the previous Dialog (Modal) automatically? #3193

Closed
Aravinda93 opened this issue May 10, 2024 · 3 comments

Comments

@Aravinda93
Copy link

Aravinda93 commented May 10, 2024

I am using the HeadlessUI/Vue component in my Nuxt 3 application to build the Dialog/Modals. I am using the latest version "@headlessui/vue": "^1.7.22" and developing in Chrome latest browser.

Minimal reproduction repo in CodeSandBox

I am creating a DialogPanel1.vue using the headlessui/vue. I have a button in DialogPanel1.vue on clicking it I am opening the DialogPanel2.vue but within DialogPanel2.vue when I click anywhere then it automatically closes the DialogPanel1.vue which is behind the DialogPanel2.vue.

Why is it closing DialogPanel1 automatically? I want to ensure that DialogPanel1 is closed only when I click the close button in DialogPanel1.vue not for any click on DialogPanel2. I tried adding the @click.stop or @mousedown.stop to prevent the propagation of the event but it's still not working. Can anyone please let me know the issue?

Following is my complete code /pages/Test.vue:

<template>
  <DialogPanel1 />
</template>
  
<script setup>
</script>

Following are my components /component/DialogPanel1.vue:

<template>
  <div class="mb-2">
    <button
      type="button"
      @click="openModal1"
      class="flex secondary-button text-secondary dark:bg-transparent dark:hover:text-secondary dark:hover:bg-slate-700 mx-auto justify-center items-center rounded border focus:ring-0 focus:outline-none font-medium px-5 py-2.5 text-center min-w-[8rem] sm:min-w-[10rem] lg:min-w-[12rem]"
    >
      <span class="pr-1"> Open Modal-1 </span>
    </button>
  </div>

  <TransitionRoot appear :show="modal1" as="template">
    <Dialog as="div" @close="closeModal" class="relative z-30">
      <div class="fixed inset-0 overflow-y-auto">
        <div
          class="flex min-h-full items-center justify-center p-4 text-center"
        >
          <DialogPanel
            class="dark:bg-slate-800 w-full transform overflow-auto rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all z-20"
          >
            THIS IS MODAL-1
            <button
              class="flex secondary-button text-secondary dark:bg-transparent dark:hover:text-secondary dark:hover:bg-slate-700 mx-auto justify-center items-center rounded border focus:ring-0 focus:outline-none font-medium px-5 py-2.5 text-center min-w-[8rem] sm:min-w-[10rem] lg:min-w-[12rem]"
              @click="openModal2"
            >
              MODAL-2
            </button>
          </DialogPanel>
        </div>
      </div>
    </Dialog>
  </TransitionRoot>

  <DialogPanel2 :modal2="modal2" @closeModal="hideModal2" />
</template>
    
<script setup>
import { TransitionRoot, Dialog, DialogPanel } from "@headlessui/vue";

const modal1 = ref(false);
const modal2 = ref(false);

//Function to open Modal-1
const openModal1 = () => {
  console.log("Opening Modal-1");
  modal1.value = true;
};

//Close the modal on click of the button
const closeModal = () => {
  console.log("CLOSE MODAL-1");
  modal1.value = false;
};

//Function to open Modal-2
const openModal2 = () => {
  console.log("Open MODAL-2");
  modal2.value = true;
};

const hideModal2 = () => {
  console.log("Closing MODAL-2");
  modal2.value = false;
};
</script>

Following is my /components/DialogPanel2.vue:

<template>
  <TransitionRoot appear :show="modal2" as="template">
    <Dialog
      as="div"
      @close="closeModal"
      class="relative z-50"
      :initialFocus="completeButtonRef"
    >
      <div class="fixed inset-0 overflow-y-auto">
        <div
          class="flex min-h-full items-center justify-center p-4 text-center"
        >
          <DialogPanel
            class="pt-5 w-full max-w-xl overflow-y-auto transform overflow-visible rounded-2xl bg-white dark:bg-slate-800 p-6 align-middle shadow-xl transition-all"
          >
            THIS IS MODAL-2
          </DialogPanel>
        </div>
      </div>
    </Dialog>
  </TransitionRoot>
</template>
  
  <script setup>
import { TransitionRoot, Dialog, DialogPanel } from "@headlessui/vue";

const props = defineProps({
  modal2: {
    type: Boolean, //Show/hide the modal based on the flag
    required: false,
  },
});

const emits = defineEmits(["closeModal"]);

//Reference variables
const modal2 = ref(props.modal2);

watch(
  () => props.modal2,
  async (newValue) => {
    modal2.value = newValue;
  }
);

const closeModal = () => {
  console.log("CLOSE MODAL-2");
  modal2.value = false;
  emits("closeModal");
};

const completeButtonRef = ref({}); // to avoid opening of the multiselect by default & initial focus
</script>

Why clicking anywhere on DialogPanel2.vue automatically closes the previous Dialog DialogPanel1.vue?

Following issue my issue GIF:
ModalCosure

@boring-joey
Copy link

I got the same exact issue in headlessui/react v2+ now.

@Aravinda93
Copy link
Author

@boring-joey

I solved it by placing the DialogPanel2.vue inside the DialogPanel1.vue:

  <TransitionRoot appear :show="modal1" as="template" @close="closeModal">
    <Dialog as="div" class="relative z-30">
      <div class="fixed inset-0 overflow-y-auto">
        <div
          class="flex min-h-full items-center justify-center p-4 text-center"
        >
          <DialogPanel
            class="dark:bg-slate-800 w-full transform overflow-auto rounded-2xl bg-gray-200 p-6 text-left align-middle shadow-xl transition-all z-20"
          >
            THIS IS MODAL-1
            <button
              class="flex secondary-button text-secondary dark:bg-transparent dark:hover:text-secondary dark:hover:bg-slate-700 mx-auto justify-center items-center rounded border focus:ring-0 focus:outline-none font-medium px-5 py-2.5 text-center min-w-[8rem] sm:min-w-[10rem] lg:min-w-[12rem]"
              @click="openModal2"
            >
              MODAL-2
            </button>
            <DialogPanel2 :modal2="modal2" @closeModal="hideModal2" /><!-- move it here-->
          </DialogPanel>
        </div>
      </div>
    </Dialog>
  </TransitionRoot>

@carlosvaldesweb
Copy link

carlosvaldesweb commented Oct 21, 2024

This issue is still happening. I've opened an issue in Nuxt ui:
nuxt/ui#2431

In my case i need only 1 Modal to show Pricing in the page, but sometimes another modal opens this modal, so i can't to add inside of other modals. Also some features are paid in my web, so i cannot add 3 times this modal in the same Page.

@RobinMalfait

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants