floating-vue icon indicating copy to clipboard operation
floating-vue copied to clipboard

v-if DOM redraw breaks popover

Open dusterio opened this issue 2 years ago • 1 comments

I noticed that whenever a popover element is within a conditional v-if parent element, it will only work until the first redraw - something in the lifecycle is potentially broken

Inspecting the DOM, I can see t hat floating-vue does mount again after re-draw, so maybe there is an issue with event handlers and/or binding - hover event is no longer handled

Very easy to re-produce - just wrap <VMenu> or another component in a

dusterio avatar May 27 '22 01:05 dusterio

I do notice this behavior is failing for component (<CustomComponent>) used as trigger element, as well as, simple text node.

<template>
  <div v-if="condition">
    <VDropdown
      :distance="6"
    >
      <!-- This will be the popover reference (for the events and position) -->
      <CustomComponent>Click me</CustomComponent>
    
      <!-- This will be the content of the popover -->
      <template #popper>
        <input class="tooltip-content" v-model="msg" placeholder="Tooltip content" />
        <p>
          {{ msg }}
        </p>
    
        <!-- You can put other components too -->
        <ExampleComponent char="=" />
      </template>
    </VDropdown>
  </div>
</template>

Related part of the code which is failed to read custom component: https://github.com/Akryum/floating-vue/blob/47be7061cd660c5ad1895e98d9c07df7630b57b1/packages/floating-vue/src/components/Popper.ts#L487

Since query of trigger of cares more for HTML element https://github.com/Akryum/floating-vue/blob/47be7061cd660c5ad1895e98d9c07df7630b57b1/packages/floating-vue/src/components/PopperWrapper.vue#L87-L90


In case you really need <CustomComponent>, you can put it inside of simple <span>, or, preferred solution would be utilize default slot wrapper, for example:

<template>
    <!-- [...] -->
    <VDropdown
      :distance="6"
    >
      <template #default="{ shown, show, hide }">
        <CustomComponent @click="shown ? hide() : show()">Click me</CustomComponent>
      </template>
      <!-- [...] -->
</template>

Hope this help ;)

bcphung avatar Sep 15 '22 19:09 bcphung