View Source Live Toast

CI Hex

Live Toast is a drop-in replacement for the flash system in Phoenix/LiveView.

Installation

Add live_toast to your list of dependencies in the mix.exs of your Phoenix application:

def deps do
  [
    {:live_toast, "~> 0.3.0"}
  ]
end

Next open up your app.js and import/setup the hook:

import { createLiveToastHook } from 'live_toast'

let liveSocket = new LiveSocket('/live', Socket, {
  hooks: {
    LiveToast: createLiveToastHook()
  }
})

Then, add '../deps/live_toast/lib/**/*.*ex' to your list of paths Tailwind will look for class names, in your tailwind.config.js:

// assets/tailwind.config.js

module.exports = {
  content: [
    './js/**/*.js',
    '../lib/your_app_web.ex',
    '../lib/your_app_web/**/*.*ex',
    '../deps/live_toast/lib/**/*.*ex',
  ]
}

Your particular file will look different but all you need to do is make sure the last line is there.

Note that the classes are currently hardcoded. Configuration of the toast components, and therefore there styling, are on the roadmap. But the default styles should look pretty good in the mean time.

Finally, replace your <.flash_group /> component with the new <LiveToast.toast_group />. It's most likely in your app.html.heex:

<!-- Remove this! -->
<.flash_group flash={@flash} />

<!-- And replace it with this: -->
<LiveToast.toast_group flash={@flash} connected={assigns[:socket] != nil} />

<%= @inner_content %>

And you're done! Note that it's very important to set connected based on whether we're in a LiveView or not.

Usage

LiveToast will hijack the usual display of your flash messages, so they will continue to work as normal. You can continue to use flashes as normal, if you want to.

However, one of the reasons to not use flash messages, is the Phoenix flash system only allows one message for each kind of flash. The toast pattern, alternatively, generally allows for multiple messages displayed to the user at at time.

From a LiveView, you can now use put_toast similar to how you may use put_flash:

defmodule YourApp.SomeLiveView do
  def handle_event("submit", _payload, socket) do
    # you do some thing with the payload, then you want to show a toast, so:
    LiveToast.send_toast(:info, "Upload successful.")

    {:noreply, socket}
  end
end

Configuration

You can define a custom toast class function, like so:

defmodule MyModule do
  def toast_class_fn(assigns) do
    [
      "w-80 sm:w-96 z-50 p-2 rounded-md shadow origin-center overflow-hidden",
      assigns[:rest][:hidden] != true && "flex",
      assigns[:kind] == :info && "text-gray-800 bg-gray-50 dark:bg-gray-800 dark:text-gray-300",
      assigns[:kind] == :success && "text-green-800 bg-green-50 dark:bg-gray-800 dark:text-green-400",
      assigns[:kind] == :error && "text-red-800 bg-red-50 dark:bg-gray-800 dark:text-red-400"
    ]
  end
end

And then use it to override the default styles:

<LiveToast.toast_group flash={@flash} connected={assigns[:socket] != nil} toast_class_fn={MyModule.toast_class_fn/1} />

And that's pretty much it.

Roadmap

Some of the stuff still to work on:

  • [ ] Improved docs
  • [ ] Configuration for the classes on toasts
  • [ ] Tests
  • [ ] More configuration for the animations