For the last few days, I'm learning how to use the Laravel Livewire framework. I'm really impressed with how well it works, and how fast we can develop working applications using Livewire along with Tailwind CSS. It's a great option for someone who wants to start his own startup as a one-man army. Only you need to know is PHP or more precisely Laravel and some HTML / CSS.
Not everything is possible over the wire
HTML over the wire (which is the main concept behind Livewire) is very powerful, but not everything is possible to do using only on the backend. Some UX features require to use of the frontend API.
One of the things that are not possible using only Livewire is transition animations of HTML elements. There was functionality wire:transition
before the first release of Livewire, but it has been removed in the final release for some reason.
When you try to look for a Livewire transition in livewire/livewire GitHub issues, almost all of them contain the information, that there are no attributes like wire:transition
and that Livewire supports Alpine.js transitions. That's fine, but there are no working examples, and some GitHub users were a bit confused about that.
The solution
tl:dr If you want just to copy and paste the working solution, please go ahead ๐
I prepared a working modal component in a gist: https://gist.github.com/mtk3d/699502a70ee9af1cd412ddcb805e20da
First let's create a basic modal in Livewire, just using blade @if
statement.
class Modal extends Component
{
public string $content;
public bool $show;
public function mount(): void
{
$this->content = 'Modal content';
}
public function render()
{
return view('livewire.modal');
}
}
And the blade template:
<div>
<button wire:click="$set('show', true)">
Open
</button>
@if($show)
<div>
<div>{{ $content }}</div>
<button wire:click="$set('show', false)">
Close
</button>
</div>
@endif
</div>
Of course instead of using $set()
you can set up PHP open/close methods in the component and call them using wire:click
.
After refreshing the page, it should works like this one:
Ok, and now, let's modify this component, to work with Alpine.js transitions. You need only to change the template part:
<div x-data>
<button wire:click="$set('show', true)">
Open
</button>
<div x-cloak
x-show="$wire.show"
x-transition.opacity.duration.500ms
>
<div>{{ $content }}</div>
<button wire:click="$set('show', false)">
Close
</button>
</div>
</div>
First, in the main component element (div in this example) add the x-data
attribute. That will inform Alpine.js that this component contains some attributes to process.
Next remove @if
statement and add x-show
and x-transition
attributes to the modal element. As a parameter for x-show
you can use the value of $show
property from component, using JS $wire
proxy object.
Do not forget about the x-cloak
attribute, and the CSS definition for it. x-cloak
is the attribute that prevents hidden elements from blinking before the Alpine.js is loaded. By default, it hides the element by CSS, and then it's removed by Alpine.js on load.
Add to your CSS file:
[x-cloak] { display: none !important; }
The rest of the code is the same as before. Now our modal should work like this:
And that's it, we have working Alpine.js transitions in Livewire ๐
Top comments (1)
[insert clap] ๐ thanks for this!