Loading Icon Component for Phoenix LiveView

Today I am going to put together how to make a loading icon LiveComponent for Phoenix LiveView.

Get a loader CSS

First, I look for an open-source loader CSS because I am poor at designing and writing CSS. Luke Haas's Single Element CSS Spinners is nice.

Make a loader CSS file

I create assets/css/_loader.scss file in my phoenix project and paste the loader CSS into that file.

I make sure that my loader CSS file is imported into assets/css/app.scss file.

+ @import 'loader';

Make a loading icon component

First I make lib/mnishiguchi_web/live/components/loading_component.ex file. I make the component configurable for the CSS class name bacause I might want to use different loaders in different locations.

defmodule MnishiguchiWeb.LoadingComponent do
  @moduledoc """
  Shows a loading icon.

  ## Examples

      <%= live_component @socket,
                          MnishiguchiWeb.LoadingComponent,
                          class: "loader7" %>

      <%= live_component @socket,
                          MnishiguchiWeb.LoadingComponent,
                          loading: @loading,
                          class: "loader7" %>

      <%= live_component @socket,
                          MnishiguchiWeb.LoadingComponent,
                          loading: !connected?(@socket),
                          class: "loader7" %>

  """

  use MnishiguchiWeb, :live_component

  @default_assigns %{
    loading: true,
    class: "loader"
  }

  @impl Phoenix.LiveComponent
  def update(assigns, socket) do
    socket =
      socket
      |> assign(@default_assigns)
      |> assign(assigns)

    {:ok, socket}
  end

  @impl Phoenix.LiveComponent
  def render(assigns) do
    ~L"""
    <%= if @loading do %>
      <div class="<%= @class %>">
        Loading...
      </div>
    <% end %>
    """
  end
end

That's it!