I'm showing a toast alert, controlling visibility with alpinejs
, and want the alert to dim after a couple of seconds and be hidden after some more seconds unless the mouse hovers over it.
I got the dimming working, but don't know how to interrupt the timeout that hides the element.
<div
x-data="{visible: true, dimmed: false}"
x-show="visible"
x-effect="setTimeout(() => dimmed = true, 5000);setTimeout(() => visible = false, 10000)"
x-on:mouseover="dimmed = false" // <-- How can I stop the second setTimeout() here?
x-transition.duration.500ms
:class="dimmed ? 'opacity-60' : 'opacity-100'"
class="flex alert alert-info justify-between">
<div>Some message here</div>
<div x-on:click="visible = false">
<button class="btn btn-sm btn-square btn-info">
Close
</button>
</div>
</div>
In js I would declare a variable for the setTimeout()
and then call cancelTimeout()
on that variable but I don't know how to do this using alpine.
Additionally want to restart the setTimeout()
once the mouse leaves the <div>
. I guess this could easily be done by defining another setTimeout
in x-data and then calling that @onmouseleave
, but I can't figure out how to interrupt the timeout in the first place.
Do something like this, add a mouse over and mouse leave event that can start/stop the timer. Mouse over can call a function to stop the timer and mouse leave can do the inverse.
<div
x-data="toast()"
x-show="visible"
x-transition.duration.500ms
:class="dimmed ? 'opacity-60' : 'opacity-100'"
class="flex alert alert-info justify-between"
x-init="startTimers()"
x-on:mouseover="cancelTimers(); dimmed = false"
x-on:mouseleave="startTimers()"
>
<div>Some message here</div>
<div x-on:click="visible = false">
<button class="btn btn-sm btn-square btn-info">
Close
</button>
</div>
</div>
<script>
part:
function toast() {
return {
visible: true,
dimmed: false,
dimTimeout: null,
hideTimeout: null,
startTimers() {
this.cancelTimers();
this.dimTimeout = setTimeout(() => this.dimmed = true , 5000);
this.hideTimeout = setTimeout(() => this.visible = false, 10000);
},
cancelTimers() {
clearTimeout(this.dimTimeout);
clearTimeout(this.hideTimeout);
}
}
}