subbu

subbu

Achieving tailwind enter/leave transitions with LiveView.JS

Tailwind has nice transitions for components like slid-overs, dropdowns, and modals. For example, these are the transitions classes for a slideover:

Slide-over panel, show/hide based on slide-over state.

        Entering: "transform transition ease-in-out duration-500 sm:duration-700"
          From: "translate-x-full"
          To: "translate-x-0"
        Leaving: "transform transition ease-in-out duration-500 sm:duration-700"
          From: "translate-x-0"
          To: "translate-x-full"

These are easy to get right with Alpine.js using x-transitions, but is there a way to do them using LiveView.JS? Has anybody tried?

Marked As Solved

cvkmohan

cvkmohan

Also Liked

christopherslee

christopherslee

I think the answer here is that you can apply multiple classes in the 3-tuple separated by spaces. I guessed at this by looking at the linked source code, and then saw that it uses a function transition_class_names which calls class_names which uses String.split(" "") (source)

For example something specified as:

  Entering: "transition ease-out duration-100"
    From: "transform opacity-0 scale-95"
    To: "transform opacity-100 scale-100"
  Leaving: "transition ease-in duration-75"
    From: "transform opacity-100 scale-100"
    To: "transform opacity-0 scale-95"

can be implemented as:

  def show_user_menu(js \\ %JS{}) do
    js
    |> JS.toggle(
      to: "#user_menu",
      in:
        {"transition ease-out duration-100", "transform opacity-0 scale-95",
         "transform opacity-100 scale-100"},
      out:
        {"transition ease-in duration-75", "transform opacity-100 scale-100",
         "transform opacity-0 scale-95"}
    )
  end
paulstatezny

paulstatezny

@tcoopman Thanks for chiming in!

I was mostly having trouble with entrance transitions. (Elements not previously shown.) I had to add these to get Tailwind transitions to apply correctly:

  1. style="display: none"
  2. class="start-classes"
  3. phx-mounted={JS.show(transition: {"transition-classes", "start-classes", "end-classes"}, time: ...)}

So for example, if a TailwindUI component has:

<!--
  Entering: "ease-out duration-300"
    From: "opacity-0"
    To: "opacity-100"
-->
<div>
  ...
</div>

I had to do:

<div
  style="display: none"
  class="opacity-0"
  phx-mounted={JS.show(
    transition: {"ease-out duration-300", "opacity-0", "opacity-100"},
    time: 300
  )}
>
  ...
</div>

Without this precise configuration, I wasn’t able to get the transition to display correctly. (Notice I’m using JS.show instead of JS.transition.)

Hopefully someone out there finds this helpful! :slight_smile:


It’s worth noting that Alpine.js makes this much less confusing to get right. You just take the 3 lists of classes from the TailwindUI example HTML and drop them into 3 corresponding attributes.

<div
  x-show="open"
  x-transition:enter="ease-out duration-300"
  x-transition:enter-start="opacity-0"
  x-transition:enter-end="opacity-100"
>
  ...
</div>

Perhaps LiveView could benefit to evolve more in that direction. :slight_smile:

Where Next?

Popular in Questions Top

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
dotdotdotPaul
Okay, I’m having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I’m sure I’...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New

Other popular topics Top

New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

We're in Beta

About us Mission Statement