vueuse / motion

🤹 Vue Composables putting your components in motion
https://motion.vueuse.org
MIT License
2.27k stars 79 forks source link

Hover on nested element removes "hovered" styles #191

Closed Fifciu closed 4 months ago

Fifciu commented 4 months ago

System info


Reproduction

  1. Create the following component:

    <div class="flex flex-col bg-white box-shadow" 
    v-motion 
    :initial="{
      opacity: 0,
      y: 0,
      scale: 0
    }" 
    :visibleOnce="{
      opacity: 1,
      y: 0,
      scale: 1
    }"
    :duration="2300" 
    :hovered="{
      scale: 1.03
    }">
    <img src="https://t3.ftcdn.net/jpg/05/85/86/44/360_F_585864419_kgIYUcDQ0yiLOCo1aRjeu7kRxndcoitz.jpg" />
    <div class="px-2 py-4 flex flex-col gap-2 md:px-4 h-full" id="bugged-childs">
      <h3 class="font-secondary font-medium text-2xl text-neutral-800 hyphens-auto break-words">Lorem ipsum dolor</h3>
      <div class="font-secondary font-light text-base text-neutral-800 flex-auto">
        <p class="line-clamp-6">Lorem ipsum dolor sit amet consectetur. Amet at aenean mauris lacinia sociis habitasse
          at sem. Nisl egestas netus elit vivamus felis odio massa at ultrices. Pharetra sed pulvinar lectus tempor. Sed
          amet natoque nulla tellus.</p>
      </div>
    </div>
    </div>
  2. Play with "hovered" part. When you over on image or padding of main div then it works perfectly. But if you hover on child of #bugged-childs (h3, div, div>p) then hovered styles are removed.

Describe the bug

Hovered styles are removed when we hover on grandchild and it's descendants.

Additional context

No response

Logs

No response

Fifciu commented 4 months ago

I suspect the problem is caused by event bubbling. I think these handlers https://github.com/vueuse/motion/blob/5e2346ac1d2239821043bd3ad52148d099c2f818/src/features/eventListeners.ts#L48 catches events from child and sets hover to false.

As a temporary workaround I set @mouseout.stop @mouseleave.stop on both img and #bugged-childs and it solves the problem.

gimwachan-git commented 4 months ago

I set child to pointer-events: none; and it worked.

Fifciu commented 4 months ago

I am pretty sure it's possible to solve without workarounds, so we still can have pointer events inside.

BobbieGoede commented 4 months ago

This behaviour is caused by this: https://github.com/vueuse/motion/blob/5e2346ac1d2239821043bd3ad52148d099c2f818/src/features/eventListeners.ts#L53-L56

I wonder if there is any use case for triggering this on mouseout, which also triggers whenever mouse hovers over child elements? If not, we can probably remove this and only handle this on mouseleave.