-
Hey I try to implement the popover with hover on Vue, An tip or an example. Thanks! |
Beta Was this translation helpful? Give feedback.
Answered by
taythebot
Feb 3, 2023
Replies: 1 comment
-
Here's an example using
You can adjust the delay to your liking. I found 100 milliseconds to be a good match for me. If you have multiple popovers on your page, consider putting the below into a component with props to pass the text. <template>
<div class="fixed top-16 w-full max-w-sm px-4">
<Popover v-slot="{ open, close }" class="relative">
<PopoverButton
:class="open ? '' : 'text-opacity-90'"
class="group inline-flex items-center rounded-mdpx-3 py-2 text-base font-medium text-white hover:text-opacity-100"
@mouseover="(e) => hoverPopover(e, open)"
@mouseleave="closePopover(close)"
>
<span>Solutions</span>
<ChevronDownIcon
:class="open ? '' : 'text-opacity-70'"
class="ml-2 h-5 w-5 text-white transition duration-150 ease-in-out group-hover:text-opacity-80"
aria-hidden="true"
/>
</PopoverButton>
<transition
enter-active-class="transition duration-200 ease-out"
enter-from-class="translate-y-1 opacity-0"
enter-to-class="translate-y-0 opacity-100"
leave-active-class="transition duration-150 ease-in"
leave-from-class="translate-y-0 opacity-100"
leave-to-class="translate-y-1 opacity-0"
>
<PopoverPanel
class="absolute left-1/2 z-10 mt-3 w-screen max-w-sm -translate-x-1/2 transform px-4 sm:px-0 lg:max-w-3xl"
@mouseover.prevent="popoverHover = true"
@mouseleave.prevent="closePopover(close)"
>
<div
class="overflow-hidden rounded-lg shadow-lg ring-1 ring-black ring-opacity-5"
>
<div class="relative grid gap-8 bg-white p-7 lg:grid-cols-2">
<a
class="-m-3 flex items-center rounded-lg p-2 transition duration-150 ease-in-out hover:bg-gray-50"
>
<div class="ml-4">
<p class="text-sm font-medium text-gray-900">foo</p>
<p class="text-sm text-gray-500">bar</p>
</div>
</a>
</div>
</div>
</PopoverPanel>
</transition>
</Popover>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { Popover, PopoverButton, PopoverPanel } from '@headlessui/vue'
import { ChevronDownIcon } from '@heroicons/vue/20/solid'
const popoverHover = ref(false)
const popoverTimeout = ref(null)
const hoverPopover = (e, open) => {
popoverHover.value = true
if (!open) e.target.click()
}
const closePopover = (close) => {
popoverHover.value = false
if (popoverTimeout.value) clearTimeout(popoverHover.value)
popoverTimeout.value = setTimeout(() => {
if (!popoverHover.value) close()
}, 100)
}
</script> |
Beta Was this translation helpful? Give feedback.
0 replies
Answer selected by
prpanto
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here's an example using
mouseover
andmouseleave
events on thePopoverButton
andPopoverPanel
.mouseover
onPopoverButton
, usesevent.target.click()
to open popover panel and setspopoverHover = true
mouseleave
onPopoverButton
setspopoverHover = false
and starts a 100 millisecond delay. Afterwards it checks ifpopoverHover === false
before usingclose
prop to close the popoverPopverPanel
before the 100 millisecond delay, it setspopoverHoever = true
cancelling the closeYou can adjust the delay to your liking. I found 100 milliseconds to be a good match for me.
If you have multiple popovers on your page, consider putting the below into a compon…