byElvinas Predkelis
May 22, 2022
The setup is pretty straight-forward. It's just a turbo frame with a spinner inside of it.
However, when the frame is being loaded, it looks something like <turbo-frame id="loadable" busy="" aria-busy="true">
- it has a [busy]
attribute attached to it.
Turns out, it's possible to leverage that [busy]
attribute. 💆
This is where most of the 🪄🎩 magic 🎩🪄 happens. Tailwind allows to set up custom modifiers which is exactly what we need in this case.
// tailwind.config.js
let plugin = require("tailwindcss/plugin");
module.exports = {
// ...
plugins: [
plugin(({ addVariant }) => {
addVariant("busy", "&[busy]");
addVariant("group-busy", ":merge(.group)[busy] &");
}),
],
};
Here a busy
modifier is set up which is bound to the [busy]
attribute. Also, group-busy
is added to target the spinner inside of the parent turbo frame.
Now we can just ✨sprinkle✨ some classes on some elements.
<turbo-frame id="loadable" class="group">
<svg
class="group-busy:inline hidden h-6 w-6 animate-spin"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
class="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
stroke-width="4"
></circle>
<path
class="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
</turbo-frame>
In this instance, the spinner just appears while the turbo frame is being loaded. The frame element now has a group
class while the spinner now has group-busy:inline hidden
classes.
Obviously, you can now style it to your liking when using the respective modifiers. For example, busy:opacity-50
will make the turbo frame transparent while loading.
The main goal was to once again shake off some unnecessary Javascript from the codebase. This turned out to be a rather tidy way of doing so while keeping the simplicity of Hotwire and the flexibility of Tailwind.
Reach out to us and let's build something great together
Schedule an exploration call