This article will outline how to show a spinner while loading a turbo frame without additional Javascript.
Disclaimer - The setup includes Tailwind configuration which is technically Javascript.
Idea and Setup
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. 💆
Adding Tailwind modifiers
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.
Finishing touches
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.
Wrapping up
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.
If you have any questions or suggestions, feel free to reach out to me on Twitter or visit my website!
Top comments (0)