BATMAN_2008
BATMAN_2008

Reputation: 3530

Nuxt 3 multi module component re-usage closes the Modal/Dialog automatically closes when using the Modals from different modules

In a multi-module Nuxt 3 project when one Modal0.vue modal/HeadlessUI Dialog is in the projectA module and another Modal1.vue modal/HeadlessUI Dialog in projectB then opening the Modal1 and providing the values from Modal0 automatically closes. This mainly happens when accessing via Quarkus Static web. Direct usage via Nuxt 3 npm run dev it seems to work fine when I generate the npm run generate and access from quarkus static web then I am getting this error.

I have a Nuxt3 based application which is a multi-module has the following structure:

root
  - projectA
  - projectB

projectA extends the components present in projectB so I have added the following code in projectA nuxt.config.ts:

// auto import components
components: [
  {
    path: '~/components',
    pathPrefix: false,
  },
  {
    path: "../projectB/components",
    pathPrefix: false,
  },
],

extends: ["../projectB"],

It works fine and able to access the components and use them correctly but I am facing a strange problem when accessing the modal.

I have created the following page in my projectA: projectA/pages/test.vue:

<template>
  <button
    class="flex justify-center items-center text-white mx-auto border focus:ring-0 focus:outline-none font-medium px-5 py-2.5 text-center"
    @click="showModal0Fn"
  >
    Open Modal 0
  </button>

  <Modal0 v-if="showInfoModal" :showInfoModal="showInfoModal" />
</template>

<script setup>
const showInfoModal = ref(false);

const showModal0Fn = () => {
  showInfoModal.value = true;
};
</script>

Following is my Modal0.vue which is present within projectA/components/Modal0.vue where I am accessing the Modal1.vue present in projectB from Modal0:

<template>
  <TransitionRoot appear :show="infoModal" as="template">
    <Dialog as="div" @close="closeModal('dialog')" class="relative z-50">
      <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-3/4 transform overflow-auto rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all z-20"
          >
            <DialogTitle
              as="h5"
              class="leading-6 text-primary dark:text-white p-5 relative text-center"
            >
              MODAL ZERO
            </DialogTitle>

            <Modal1 />
          </DialogPanel>
        </div>
      </div>
    </Dialog>
  </TransitionRoot>
</template>
  
<script setup>
import { Icon } from "@iconify/vue";
import { ref } from "vue";
import { Form } from "vee-validate";
import {
  TransitionRoot,
  TransitionChild,
  Dialog,
  DialogPanel,
  DialogTitle,
} from "@headlessui/vue";

const props = defineProps({
  showInfoModal: {
    type: Boolean,
    required: false,
  },
});

const emits = defineEmits(["infoModal"]);
const infoModal = ref(props.showInfoModal);

const closeModal = (value) => {
  console.log("From Modal 0 : " + value);
  console.log("CLOSE MODAL ZERO");
  infoModal.value = false;
  emits("infoModal", infoModal.value);
};
</script>

Following is my Modal1.vue which is present within projectB/components/Modal1.vue:

<template>
  <button
    type="button"
    @click="openModal($event)"
    class="flex secondary-button text-secondary dark:bg-transparent dark:hover:text-secondary dark:hover:bg-slate-700 border justify-center items-center rounded mx-auto 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</span>
  </button>

  <TransitionRoot appear :show="showModal1" as="template">
    <Dialog as="div" @close="closeModal('dialog')" class="relative z-50">
      <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-3/4 transform overflow-auto rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all z-20"
          >
            <DialogTitle
              as="h5"
              class="leading-6 text-primary dark:text-white p-5 relative text-center"
            >
              MODAL 1
            </DialogTitle>

            <select
              class="relative w-full h-full bg-gray-50 dark:text-white dark:bg-gray-700 dark:border-gray-600 border-gray-300 border rounded text-center block overflow-hidden"
            >
              <option
                v-for="option in options"
                :key="option.value"
                :value="option.value"
              >
                {{ option.text }}
              </option>
            </select>
          </DialogPanel>
        </div>
      </div>
    </Dialog>
  </TransitionRoot>
</template>
  
  <script setup>
import { ref } from "vue";
import { Form } from "vee-validate";
import {
  TransitionRoot,
  TransitionChild,
  Dialog,
  DialogPanel,
  DialogTitle,
} from "@headlessui/vue";

const showModal1 = ref(false);

//Open the modal on click of the button
const openModal = (event) => {
  showModal1.value = true;
};

//Close the modal on click of the button
const closeModal = (value) => {
  console.log("Modal 1 close : " + value);
  console.log("Within Close Modal 1");
  showModal1.value = false;
};

const options = ref([
  { value: "Value1", text: "Text 1", disabled: true, selected: true },
  { value: "Value2", text: "Text 2", disabled: true, class: "font-bold" },
]);
</script>

Everything works fine here so far and able to open the Modal1.vue component but when I try to select any element from the Select dropdown within Modal1.vue then the Modal0 automatically closes for some reason. I am not sure why it would close the modal because I dont have any specific functions written to close the modal if we select any item from Dropdown.

After debugging I found that the issue resolves if both the components Modal0 and Modal1 are present in the same module either projectA/components or projectB/components. If I move Modal0.vue to projectB/components then everything works as expected.

I would like to know why accessing a Modal from another component would close the whole Modal. I am attaching the GIF with a screen recording for reference and easy understanding:

enter image description here

Upvotes: 0

Views: 203

Answers (0)

Related Questions