Expected result from code:
We are going to create a component that will handle the tooltip. So, we need to create a file named tooltip.blade.php
in /view/components
. This way we will be able to call our tooltip as <x-tooltip ... />
@props([
'tooltip'
])
<div
x-data="{ show: false }"
x-on:mouseover="show = true"
x-on:mouseleave="show = false"
{{ $attributes->class(['relative inline-flex w-auto cursor-pointer']) }}>
<span x-show="show" x-cloak
class="bg-gray-800 absolute -mt-5 top-1/2 right-1/2 transform translate-x-1/2 -translate-y-1/2 rotate-45"
style="width: 10px; height: 10px;"
></span>
<span x-show="show" x-cloak
class="text-sm overflow-hidden text-white absolute bg-gray-800 rounded-md px-2 py-1 -mt-8 top-1/2 right-1/2 transform translate-x-1/2 -translate-y-1/2"
>
{!! str_replace(' ', ' ', $tooltip) !!}
</span>
{{ $slot }}
</div>
Then you can call in your blade files the component as:
<x-tooltip tooltip="Some Tooltip">
Some Text
</x-tooltip>
Explaining the code
First we explicitly say that we require a tooltip argument.
@props([
'tooltip'
])
Then we initiate the Alpine data, and also set to change the show
value when entering or leaving the component.
Here we also set the required classes allowing to receive any other class from the view that is using the component.
<div
x-data="{ show: false }"
x-on:mouseover="show = true"
x-on:mouseleave="show = false"
{{ $attributes->class(['relative inline-flex w-auto cursor-pointer']) }}
>
We then create the “arrow” (which is just a rotated square), and only display it when show
is true.
We also don’t want to display it when the page is loading, so we add the x-cloak
Alpine method on it.
<span x-show="show" x-cloak
class="bg-gray-800 absolute -mt-5 top-1/2 right-1/2 transform translate-x-1/2 -translate-y-1/2 rotate-45"
style="width: 10px; height: 10px;"
></span>
And we add our tooltip.
<span x-show="show" x-cloak
class="text-sm overflow-hidden text-white absolute bg-gray-800 rounded-md px-2 py-1 -mt-8 top-1/2 right-1/2 transform translate-x-1/2 -translate-y-1/2"
>
{!! str_replace(' ', ' ', $tooltip) !!}
</span>
The str_replace
method is needed to avoid break line on sentences with space.
Using Transitions
This is the approach you can see in the gif at top.
<x-tooltip tooltip="It will answer your question">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-indigo-500" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd" />
</svg>
</x-tooltip>
If you want to add some transition in your tooltip, you should add it to both span tags.
Sample of the tooltip.blade.php
full body with transitions:
@props([
'tooltip'
])
<div
x-data="{ show: false }"
x-on:mouseover="show = true"
x-on:mouseleave="show = false"
{{ $attributes->class(['relative inline-flex w-auto cursor-pointer']) }}>
<span x-show="show" x-cloak
x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="opacity-0 transform scale-90"
x-transition:enter-end="opacity-100 transform scale-100"
x-transition:leave="transition ease-in duration-50"
x-transition:leave-start="opacity-100 transform scale-100"
x-transition:leave-end="opacity-0 transform scale-90"
class="bg-gray-800 absolute -mt-5 top-1/2 right-1/2 transform translate-x-1/2 -translate-y-1/2 rotate-45"
style="width: 10px; height: 10px;"
></span>
<span x-show="show" x-cloak
x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="opacity-0 transform scale-90"
x-transition:enter-end="opacity-100 transform scale-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100 transform scale-100"
x-transition:leave-end="opacity-0 transform scale-90"
class="text-sm overflow-hidden text-white absolute bg-gray-800 rounded-md px-2 py-1 -mt-8 top-1/2 right-1/2 transform translate-x-1/2 -translate-y-1/2"
>
{!! str_replace(' ', ' ', $tooltip) !!}
</span>
{{ $slot }}
</div>