neilberkman

neilberkman

LiveView and enter / leave transitions?

I’m trying to implement some TailwindUI components using LiveView and some of these specify enter / leave transitions to be implemented in JS. As an example, if you go here and view the code you’ll see comments such as:

<!--
  'Solutions' flyout menu, show/hide based on flyout menu state.

  Entering: "transition ease-out duration-200"
    From: "opacity-0 translate-y-1"
    To: "opacity-100 translate-y-0"
  Leaving: "transition ease-in duration-150"
    From: "opacity-100 translate-y-0"
    To: "opacity-0 translate-y-1"
-->

(some background on why this can’t be done with CSS alone can be found here)

React, Vue and other frameworks have built-in support for such transitions, for example: Transition | Vue.js but it doesn’t appear that LiveView currently does, and I haven’t found an issue about this.

I was wondering if anyone has found a way to implement enter / leave transitions with LiveView. Thanks.

Most Liked

stryrckt

stryrckt

LiveView added support for AlpineJS in 0.13.3. It works great, with no phx-update="ignore" necessary. I wrote about it here:

stryrckt

stryrckt

My article on creating LiveView modals with Tailwind CSS and Alpine.js is up.

outlog

outlog

had some spare time:
add tailwindcss and ui to your app
copy the html from Tailwind CSS Headers - Official Tailwind UI Components
put a phx-click on the more button, and add my_more_nav <%= @more_status %> to the div class

        <div class="relative">
          <!-- Item active: "text-gray-900", Item inactive: "text-gray-500" -->
          <button  phx-click="toggle_more" type="button" class="text-gray-500 inline-flex items-center space-x-2 text-base leading-6 font-medium hover:text-gray-900 focus:outline-none focus:text-gray-900 transition ease-in-out duration-150">
            <span>More</span>
            <!-- Item active: "text-gray-600", Item inactive: "text-gray-400" -->
            <svg class="text-gray-400 h-5 w-5 group-hover:text-gray-500 group-focus:text-gray-500 transition ease-in-out duration-150" fill="currentColor" viewBox="0 0 20 20">
              <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
            </svg>
          </button>

          <!--
            'More' flyout menu, show/hide based on flyout menu state.

            Entering: "transition ease-out duration-200"
              From: "opacity-0 translate-y-1"
              To: "opacity-100 translate-y-0"
            Leaving: "transition ease-in duration-150"
              From: "opacity-100 translate-y-0"
              To: "opacity-0 translate-y-1"
          -->
          <div class="my_more_nav <%= @more_status %> absolute left-1/2 transform -translate-x-1/2 mt-3 px-2 w-screen max-w-md sm:px-0">

css is: (probably some unneeded !important and what not)

div.my_more_nav:not(.show_more):not(.hide_more) {
  display: none;
}

div.show_more
{
    animation-fill-mode: forwards !important;
    animation: fadeInFromNone 0.2s ease-out;
}



div.hide_more
{ 

    animation-fill-mode: forwards !important;
    animation: fadeOut 0.15s ease-in;
}

@keyframes fadeInFromNone {
    0% {
        display: none;
        opacity: 0;
       transform: translateY(4px) translateX(-50%);
        
    }

    1% {
        display: block;
        opacity: 0;
        transform: translateY(4px) translateX(-50%);
    }

    100% {
        display: block !important;
        opacity: 1;
       transform: translateY(0px) translateX(-50%);
    }
}

@keyframes fadeOut {
    0% {
        display: block;
        opacity: 1;
        transform: translateY(0px) translateX(-50%);
    }

    99% {
        opacity: 0;
        transform: translateY(4px) translateX(-50%);
    }

    100% {
        display: none;
        opacity: 0;
        transform: translateY(4px) translateX(-50%);
    }
}

then in the liveview mount assign more_status: "" on the socket..

and have a toggle_more:

  @impl true
  def handle_event("toggle_more", _query, socket) do

   value = if socket.assigns.more_status == "show_more" do
       "hide_more"
     else
      "show_more"
   end
   {:noreply,
         socket
         |> assign(results: %{}, more_status: value)}
  end

most likely I would handle navbar clicks client side (do a phx-hook and addeventlistener on click) - I would also underlay the entire div - and catch clicks outside the navbar thing..

Where Next?

Popular in Questions Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
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
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
mgjohns61585
Could someone help me? I’m making my first elixir program, number guessing game. I can’t figure out how to convert the user’s guess from ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
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

Other popular topics Top

sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 42920 311
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
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a &gt; b) do {:ok, "a"} end if (a &lt; b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36128 110
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New

We're in Beta

About us Mission Statement