Open silverdr opened 1 month ago
Hey @silverdr,
thank you for reporting! It would be helpful if you could provide a sample script to reproduce the problem. I cannot currently say if your quick fix has any consequences on transition based animations, so I'd need to experiment a little bit myself. A reproduction would help a lot, but I can try to come up with one myself when I find the time :)
@SteffenDE I apologise for the delayed response. I must have overlooked notification :-( Yes, I can prepare a more detailed example shortly but FWIW the problem is already visible when following the documentation examples as described in the linked Elixir forum thread. The trigger in my case is only a bit different but it doesn't make any change in behaviour:
phx-click={JS.show(to: "#window-title-window", transition: "fade-in-scale", display: "flex")}
As for the pull request – it shows what change "fixed" the problem at hand but the disclaimer obviously applies ;-)
Here comes the example. If you need anything else, please ping me back.
router.ex
:
[...]
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, html: {MyApp.Layouts, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
end
scope "/", MyApp do
pipe_through :browser
live "/races", RacesLive
end
[...]
races_live.ex
:
defmodule MyApp.RacesLive do
use MyApp, :live_view
def mount(_params, _session, socket) do
socket = socket
|> assign(:page_title, "Races")
{:ok, socket}
end
def render(assigns) do
~H"""
<div id="wrapper" class="mx-6 my-6 w-64 h-64">
<div id="target" class="w-64 h-64 bg-red-600"></div>
</div>
<div id="buttons-wrapper" class="flex justify-around w-64">
<button class="px-2 rounded border-2" phx-click={JS.show(to: "#target", transition: "fade-in-scale")}>Show</button>
<button class="px-2 rounded border-2" phx-click={JS.hide(to: "#target", transition: "fade-out-scale")}>Hide</button>
</div>
"""
end
end
app.css
:
@keyframes fade-out-scale {
100% {
/* transform: scale(0.4); */
transform: scale(0.4) translateY(25px);
opacity: 0;
}
}
.fade-out-scale {
opacity: 1;
animation: .2s ease-in fade-out-scale;
animation-fill-mode: forwards;
}
@keyframes fade-in-scale {
0% {
transform: scale(0.4) translateY(25px);
opacity: 0;
}
90% {
transform: scale(1.05) translateY(-3px);
opacity: 0.9;
}
100%{
transform: scale(1.0) translateY(0px);
opacity: 1;
}
}
.fade-in-scale {
animation-direction: normal;
animation-duration: .2s;
animation-fill-mode: forwards;
animation-name: fade-in-scale;
}
Video of the results:
@chrismccord please let me know if I can help more with this one. Regards.
Environment
Actual behavior
When using JS.show() with animated transition
sometimes the element pops-up BEFORE the transition animation starts, then disappears and only then animates. Video showing the problem:
https://cld.silverdr.com/s/z8KbZkCDGw8Ffyx
Expected behavior
The transition flow is undisturbed every time.
The relevant elixirforum thread: https://elixirforum.com/t/liveview-js-show-hide-race-condition/66405/
The Pull Request with a quick fix.
https://github.com/phoenixframework/phoenix_live_view/pull/3455
Please note that I am not familiar with the codebase so can't guarantee that it is the most "correct" way to deal with the problem.