Laravel blade tooltip svg component
— 7 min read
In our previous mini-post about blade components, I shared a very cool little SVG component to keep handy in your developer's tool belt. In this follow-up mini-post, we will dive deeper into the specific component and experiment with a way to use the simple SVG component as a part of a larger component.
Previous Post 🔗
In the previous Sudorealm mini-post I crafted this little beauty using the tabler-icons SVG library:
<x-svg svg="brand-facebook" />
What we want to achieve is to have a component that uses this small SVG blade component and also pop up a tooltip when you hover over the SVG.
Code by wishful thinking
While watching the course Test Driven Laravel by @adamwathan I learned a new way of thinking about code. “Let's code by wishful thinking”, he said, and I loved it. The idea is, that you first write the code that you would like to end up with, and then make it happen. So let's follow this approach for this component.
I want to end up with something like this:
<x-svg-tooltip svg="package" message="products to storages" color='green'/>
Step 1st: Create the blade component
We create a new file under the resources/components folder and name it svg-tooltip.blade.php
.
Step 2nd: Add the props We need to check what props we are having in our component. By taking a look at our wishful thinking we see three props
- svg
- message
- color
That's easy, let's create our @props
array inside our new svg-tooltip blade file.
@props([
'svg' => '',
'message' => '',
'color' => 'gray'
])
Done ✅
Step 3d: Add the component body
<div class="relative inline-block">
<x-svg {{ $attributes }} :svg="$svg"
class="relative text-{{ $color }}-500 transition cursor-pointer peer hover:text-{{ $color }}-700" />
<div
class="absolute shadow right-full top-1/2 z-20 mr-3 -translate-y-1/2 whitespace-nowrap rounded bg-{{ $color }}-100 py-[6px] px-4 text-sm font-semibold text-{{ $color }}-700 opacity-0 peer-hover:opacity-100">
<span
class="absolute right-[-3px] top-1/2 -z-10 h-2 w-2 -translate-y-1/2 rotate-45 rounded-sm bg-{{ $color }}-100">
</span>
{{ $message }}
</div>
</div>
I want to take a step back and explain some core pieces of this code.
As you see You can specify the message that you want to display when you hover over the tooltip by filling in the message prop! Also, you can decide what color your SVG will be, there is one additional small configuration that I will provide you with at the end of this mini-post.
The main little detail you might have noticed is the :svg="$svg"
prop. If you remember, in the SVG component from before we just passed the SVG name from the tabler-icons directly like, svg="some-component-name"
, but now we are using the colon symbol before the svg prop (:svg
).
In Laravel Blade templates, the colon symbol is used to introduce a PHP expression or variable. In the context of a component, the colon is typically used before a prop declaration to indicate that the prop is a PHP variable.
If you think about it, in the previous component we did this:
<!-- Component declaration -->
<x-component prop="svg-name" />
<!-- Component body -->
<svg title="{{$prop}}"> </svg>
But now with this tooltip component, we are a level deeper and we want to pass the {{$prop}}
variable to the nested svg component.
<!-- Component declaration -->
<x-component prop="svg-name" />
<!-- Tooltip Component body -->
<x-svg :prop="$prop" /> <!-- That's the trick -->
<!-- SVG Component body -->
<svg title="{{$prop}}"> </svg>
And this is a small preview of how we pass PHP variables to a blade component as well as a hint on how you can nest one blade component within another.
Component Code Snippet
<!--
* ------------------------------------------------------------------------
* For this component to work with dynamic coloring
* we have to pre fetch all the tailwind colors we need for JIT to know
* ------------------------------------------------------------------------
* WHY?
* ------------------------------------------------------------------------
* If we don't, then the JIT will not have compiled the classes that we want
* to be using dynamically with this component
* ------------------------------------------------------------------------
-->
@props([
'svg' => '',
'message' => '',
'color' => 'gray'
])
<div class="relative inline-block">
<x-svg {{ $attributes }} :svg="$svg"
class="relative text-{{ $color }}-500 transition cursor-pointer peer hover:text-{{ $color }}-700" />
<div
class="absolute shadow right-full top-1/2 z-20 mr-3 -translate-y-1/2 whitespace-nowrap rounded bg-{{ $color }}-100 py-[6px] px-4 text-sm font-semibold text-{{ $color }}-700 opacity-0 peer-hover:opacity-100">
<span
class="absolute right-[-3px] top-1/2 -z-10 h-2 w-2 -translate-y-1/2 rotate-45 rounded-sm bg-{{ $color }}-100"></span>
{{ $message }}
</div>
</div>
JIT Configuration
Safelisting is used in situations where it’s impossible to scan certain content for class names. These situations are rare, and you should almost never need this feature. But here we do 🤓
Since tailwind scans our code for classes when it finally gets to scan out component it will see text-{{ $color }}-500
. This class is not comprehendible to tailwind. Consequently, we will be left out with a component without color unless we used a color whose class was used somewhere else in the application. Just sharing some knowledge here…
safelist: [
'bg-gradient-to-r',
{
pattern: /bg-(red|green|blue|indigo|yellow|purple|emerald|lime)-(100|200|300|400|500|600|700|800|900)/,
variants:['hover', 'focus'],
},
{
pattern: /text-(red|green|blue|indigo|yellow|purple|emerald|lime)-(100|200|300|400|500|600|700|800|900)/,
},
{
pattern: /border-(red|green|blue|indigo|yellow|purple|emerald|lime)-(100|200|300|400|500|600|700|800|900)/,
},
{
pattern: /from-(red|green|blue|indigo|yellow|purple|emerald|lime)-(100|200|300|400|500|600|700|800|900)/,
},
{
pattern: /via-(red|green|blue|indigo|yellow|purple|emerald|lime)-(100|200|300|400|500|600|700|800|900)/,
},
{
pattern: /to-(red|green|blue|indigo|yellow|purple|emerald|lime)-(100|200|300|400|500|600|700|800|900)/,
},
{
pattern: /overflow-(auto)/,
},
],
This safelist is a bit too much, but you can draw whatever you want from it for your own application since it covers a lot of safe listing ground.
Result of the component
In this brief introduction to this blade tooltip component, we explored the basic concepts and functionality of this powerful feature in the Laravel framework. We also looked at some additional features and ideas that you can use to enhance your blade templates and improve your development workflow. Whether you are a seasoned Laravel developer or just starting out, blade components can be a valuable tool in your toolkit, allowing you to create reusable, modular, and dynamic views with ease. I hope this dive into the world of blade components has been helpful, and I encourage you to continue learning and experimenting with these features to further improve your skills and efficiency as a developer.
Improve the component
If you like, you can create an extra prop or something and load the positioning classes inside the component conditionally. If I had done it, I would have added a new prop position="top|right|left|bottom
and used the @class
blade directive. I have a post about this here 🔗.
Get Better at Laravel!
Do you know what is the best way to learn Laravel? Laracasts of course! What else?
Why Every Dev is Raving About Laracasts:
🚀 All-Star Cast: Learn Laravel from the best! We're talking the creator of Laravel, Taylor Otwell, the genius behind Livewire, Caleb Porzio, and more Laravel legends.
🛠️ Full Toolkit: It’s not just Laravel! Dive deep into Livewire, Alpine.js, and the entire Laravel ecosystem and its intricacies.
🔄 Always Fresh: With direct insights from industry leaders, you’re getting content that’s not just up-to-date, but ahead of its time.
💡 Real-World Ready: Theory’s cool, but practical knowledge? Priceless. Jump from lesson to project seamlessly.
👩💻 Join the Elite: Step into a community that’s all about pushing boundaries and perfecting the craft.
Bottom line: Want to level up fast? Laracasts is your jam. Dive in using my referral link and join the coding revolution. 🔗 Laracasts
Conclusion
If you found this helpful let me know on 🐥 @DevThanos ❤️, I will continue to post mini-posts like this because I believe that sometimes people want a brief overview of how to do something rather than a lengthy, in-depth explanation of a small amount of code.
Stay tuned 📻 Share the post if you liked it, and If you loved it... Give it a Crown 👑! 😉
Learn more about the Sudorealm Project, we are constantly trying to make it better and we are so thankful that you have clumsily stumbled upon us! Hope you like our style.
I am @d3ad R1nger, Creator of Sudorealm, thank you for reading.