Skip to content

Instantly share code, notes, and snippets.

@lovebes
Last active December 14, 2021 05:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lovebes/8f18700ae874b85441f85b6dadbe3ba4 to your computer and use it in GitHub Desktop.
Save lovebes/8f18700ae874b85441f85b6dadbe3ba4 to your computer and use it in GitHub Desktop.
Phoenix LiveView flash fade out
import 'phoenix_html'
// assets/js/app.js
import { Socket } from 'phoenix'
import { LiveSocket } from 'phoenix_live_view'
let liveSocket = new LiveSocket('/live', Socket, {
params: { _csrf_token: csrfToken },
...
});
// Connect if there are any LiveViews on the page
liveSocket.connect()
window.liveSocket = liveSocket
// ****** flash event handler for server to dispatch fading out event to dom *******
window.addEventListener('phx:fade-out-flash', (e) => {
const targetAttr = 'data-handle-fadeout-flash'
document.querySelectorAll(`[${targetAttr}]`).forEach((el) => {
const key = el.getAttribute('phx-value-key')
if (key == e.detail.type) {
liveSocket.execJS(el, el.getAttribute(targetAttr))
}
})
})
// in tailwind.config.js:
module.exports = {
...
theme: {
...
extend: {
...
transitionProperty: ['visibility'],
transitionDuration: {
2000: '2000ms',
},
transitionDelay: {
2000: '2000ms',
5000: '5000ms',
},
}
}
}
# in your LiveComponent that will handle flashes:
defmodule MyAppWeb.HeaderComponent do
@moduledoc """
Header that shows flashes.
"""
use MyAppWeb, :live_component
@impl true
def update(assigns, socket) do
{:ok,
socket
|> assign(assigns)
# this function will look and `push_event()` for each existing flash type
|> trigger_fade_out_flashes(assigns)}
end
# depending on how you structured your code, `socket.assigns.flash` might have your flash map.
# for me I was running this as a component, so it was being passed @flash into `view_flash`.
defp trigger_fade_out_flashes(socket, %{view_flash: nil} = assigns), do: socket
defp trigger_fade_out_flashes(socket, %{view_flash: flash} = assigns) do
# push event for each flash type.
Map.keys(flash)
|> Enum.reduce(socket, fn flash_key, piped_socket ->
piped_socket
|> push_event("fade-out-flash", %{type: flash_key})
end)
end
# use TailwindCSS to wait 2 seconds before starting transition. Afterwards, send event to server to clear out flash.
# `lv:clear-flash` will use `phx-value-key` attribute in element to remove flash per type.
def delayed_fade_out_flash() do
JS.hide(
transition:
{"transition-opacity ease-out delay-2000 duration-1000", "opacity-100", "opacity-0"},
time: 6000
)
|> JS.push("lv:clear-flash")
end
end
<div
role="alert"
data-handle-fadeout-flash={delayed_fade_out_flash()}
phx-value-key="info"
>
<%= live_flash(@view_flash, :info) %>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment