I am developing a custom tooltip menu which shows some tooltips on the hover of the text. As per my requirement, I want to add a pointer to my tooltip which points to the text on which hovered when showing the tooltip information.
To build the tooltip menu I have made use of the @headlessui/vue
within my Nuxt 3
application. Everything works fine but the only problem is that I am unable to add a pointer towards the text for my PopoverPanel
. Can someone please let me know how to add a pointer towards the text?
Following is the code I have which shows the tooltip menu on hover over the text in nuxt 3 composition api:
<template>
<Popover v-slot="{ open, close }" class="h-0">
<PopoverButton class="focus:outline-none">
<p
@mouseover.native.stop.prevent="hoverPopover($event, open)"
@mouseleave.native.stop.prevent="closePopover($event, close)"
>
Hover ME
</p>
</PopoverButton>
<PopoverPanel
class="absolute z-50 bg-gray-700 rounded-lg text-white px-3 py-2 text-sm font-normal inline-block ring-1 ring-black ring-opacity-5 focus:outline-none"
@mouseover.native.stop.prevent="popoverHover = true"
@mouseleave.native.stop.prevent="closePopover($event, close)"
>
<slot> Text to be shown on hover over </slot>
</PopoverPanel>
</Popover>
</template>
<script setup>
import { Popover, PopoverButton, PopoverPanel, Portal } from "@headlessui/vue";
const popoverHover = ref(false);
const popoverTimeout = ref();
//On hover show the tooltip with information
const hoverPopover = (e, open) => {
popoverHover.value = true;
if (!open) {
e.target.parentNode.click();
}
};
//On mouse leave close it
const closePopover = (e, close) => {
popoverHover.value = false;
if (popoverTimeout.value) clearTimeout(popoverTimeout.value);
popoverTimeout.value = setTimeout(() => {
if (!popoverHover.value) {
close();
}
}, 100);
};
</script>
I want to add a pointer towards the text something similar to this:
in your PopoverPanel, you can use Tailwind to build a caret to indicate your desired pointer. I did a quick test on Tailwind Play to illustrate.
The class you need is: after:content-[''] after:absolute after:w-0 after:h-0 after:border-4 after:border-gray-700 after:-bottom-1 after:left-1/2 after:-translate-x-1/2 after:rotate-45
Essentially, your PopoverPanel will now look like:
<PopoverPanel
class="absolute z-50 bg-gray-700 rounded-lg text-white px-3 py-2 text-sm font-normal inline-block ring-1 ring-black ring-opacity-5 focus:outline-none after:content-[''] after:absolute after:w-0 after:h-0 after:border-4 after:border-gray-700 after:-bottom-1 after:left-1/2 after:-translate-x-1/2 after:rotate-45"
@mouseover.native.stop.prevent="popoverHover = true"
@mouseleave.native.stop.prevent="closePopover($event, close)"
>
<slot> Text to be shown on hover over </slot>
</PopoverPanel>
You can see my test on Tailwind Play.
Hope this helps :)