TinyMce нарушает анимацию TailwindCss при загрузке внутри скользящего элемента

У меня есть простое приложение Vue3, интенсивно использующее компоненты TailwindUI . Я пытаюсь разместить редактор TinyMce внутри компонента слайда, и он отлично работает. Проблема в анимации входа.

При первом входе слайд вставляется так, как должен. Однако, если он будет закрыт и снова открыт, анимация входа исчезнет. Все время анимация выхода продолжает работать без проблем. Кто-нибудь пробовал это и смог сохранить анимацию в целости и сохранности?

Вот CodeSandBox с воспроизведением проблемы в простейшей форме.

Вот соответствующий код:App.vue

      <template>
  <button @click="open = true">Open Menu</button>
  <SlideOver :open="open" @close="open = false" />
</template>

<script>
import { ref } from "vue";
import SlideOver from "./components/slide-over.vue";

export default {
  name: "App",
  components: {
    SlideOver,
  },
  setup() {
    const open = ref(false);

    return { open };
  },
};
</script>

slide-over.vue

      <!-- This example requires Tailwind CSS v2.0+ -->
<template>
  <TransitionRoot as="template" :show="open">
    <Dialog
      as="div"
      static
      class="fixed inset-0 overflow-hidden"
      @close="$emit('close')"
      :open="open"
    >
      <div class="absolute inset-0 overflow-hidden">
        <DialogOverlay class="absolute inset-0" />

        <div class="fixed inset-y-0 right-0 pl-10 max-w-full flex">
          <TransitionChild
            as="template"
            enter="transform transition ease-in-out duration-500 sm:duration-700"
            enter-from="translate-x-full"
            enter-to="translate-x-0"
            leave="transform transition ease-in-out duration-500 sm:duration-700"
            leave-from="translate-x-0"
            leave-to="translate-x-full"
          >
            <div class="w-screen max-w-md">
              <div
                class="h-full flex flex-col py-6 bg-white shadow-xl overflow-y-scroll"
              >
                <div class="px-4 sm:px-6">
                  <div class="flex items-start justify-between">
                    <DialogTitle class="text-lg font-medium text-gray-900">
                      Panel title
                    </DialogTitle>
                    <div class="ml-3 h-7 flex items-center">
                      <button
                        class="bg-white rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
                        @click="$emit('close')"
                      >
                        <span class="sr-only">Close panel</span>
                        <XIcon class="h-6 w-6" aria-hidden="true" />
                      </button>
                    </div>
                  </div>
                </div>
                <div class="mt-6 relative flex-1 px-4 sm:px-6">
                  <TinyMceEditor api-key="no-api-key" />
                </div>
              </div>
            </div>
          </TransitionChild>
        </div>
      </div>
    </Dialog>
  </TransitionRoot>
</template>

<script>
import {
  Dialog,
  DialogOverlay,
  DialogTitle,
  TransitionChild,
  TransitionRoot,
} from "@headlessui/vue";
import { XIcon } from "@heroicons/vue/outline";
import TinyMceEditor from "@tinymce/tinymce-vue";

export default {
  components: {
    Dialog,
    DialogOverlay,
    DialogTitle,
    TransitionChild,
    TransitionRoot,
    XIcon,
    TinyMceEditor,
  },
  props: {
    open: {
      type: Boolean,
      default: false,
    },
  },
  setup() {},
};
</script>

1 ответ

На мой взгляд, это проблема с загрузкой редактора TinyMce (я точно не знаю, в чем проблема). Я добавил задержку загрузки редактора после открытия модального окна с помощью watchEffect на основе реквизита, открытого с setTimeout в нем, и v-if в теге TinyMceEditor . Возможно, это не идеальное и эстетичное решение, но анимация работает плавно.

Вот код вcodeandbox.io.

И здесь код: slide-over.vue (App.vue остается прежним)

      <template>
  <TransitionRoot as="template" :show="open">
    <Dialog
      as="div"
      static
      class="fixed inset-0 overflow-hidden"
      @close="$emit('close')"
      :open="open"
    >
      <div class="absolute inset-0 overflow-hidden">
        <DialogOverlay class="absolute inset-0" />

        <div class="fixed inset-y-0 right-0 pl-10 max-w-full flex">
          <TransitionChild
            as="template"
            enter="transform transition ease-in-out duration-500 sm:duration-700"
            enter-from="translate-x-full"
            enter-to="translate-x-0"
            leave="transform transition ease-in-out duration-500 sm:duration-700"
            leave-from="translate-x-0"
            leave-to="translate-x-full"
          >
            <div class="w-screen max-w-md">
              <div
                class="h-full flex flex-col py-6 bg-white shadow-xl overflow-y-scroll"
              >
                <div class="px-4 sm:px-6">
                  <div class="flex items-start justify-between">
                    <DialogTitle class="text-lg font-medium text-gray-900">
                      Panel title
                    </DialogTitle>
                    <div class="ml-3 h-7 flex items-center">
                      <button
                        class="bg-white rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
                        @click="$emit('close')"
                      >
                        <span class="sr-only">Close panel</span>
                        <XIcon class="h-6 w-6" aria-hidden="true" />
                      </button>
                    </div>
                  </div>
                </div>
                <div class="mt-6 relative flex-1 px-4 sm:px-6">
                  <TinyMceEditor v-if="loadEditor" api-key="no-api-key" />
                </div>
              </div>
            </div>
          </TransitionChild>
        </div>
      </div>
    </Dialog>
  </TransitionRoot>
</template>
<script>
import { ref, watchEffect } from "vue";
import {
  Dialog,
  DialogOverlay,
  DialogTitle,
  TransitionChild,
  TransitionRoot,
} from "@headlessui/vue";
import { XIcon } from "@heroicons/vue/outline";
import TinyMceEditor from "@tinymce/tinymce-vue";

export default {
  components: {
    Dialog,
    DialogOverlay,
    DialogTitle,
    TransitionChild,
    TransitionRoot,
    XIcon,
    TinyMceEditor,
  },
  props: {
    open: {
      type: Boolean,
      default: false,
    },
  },
  setup(props) {
    const loadEditor = ref(false);
    watchEffect(() => {
      if (props.open) {
        setTimeout(function () {
          loadEditor.value = true;
        }, 10);
      } else {
        loadEditor.value = false;
      }
    });
    return { loadEditor };
  }
};
</script>
Другие вопросы по тегам