Home Posts Tags Post Search Tag Search

Post 18

Game Site Journal - 09 Core Components (put_flash)

Published on: 2025-04-19 Tags: elixir, Side Project, LiveView, Game Site, Fly, Deployment, Html/CSS
For this entry I wanted to go over how I changed the core components for the flash_group so that the message only stays up for a certain amount of time.

I wanted the user to be able to see what they are doing without having to clear the message every time.

In order to do this I had to find the function definition within the core_components.ex

Once there you will find everything that the function will display. 

attr :flash, :map, required: true, doc: "the map of flash messages"
  attr :id, :string, default: "flash-group", doc: "the optional id of flash container"

  def flash_group(assigns) do
    ~H"""
    <div id={@id}>
      <.flash
        kind={:info}
        title={gettext("Success!")}
        flash={@flash}

      />
      <.flash
        kind={:error}
        title={gettext("Error!")}
        flash={@flash}

      />
      <.flash
        id="client-error"
        kind={:error}
        title={gettext("We can't find the internet")}
        phx-disconnected={show(".phx-client-error #client-error")}
        phx-connected={hide("#client-error")}
        hidden
      >
        {gettext("Attempting to reconnect")}
        <.icon name="hero-arrow-path" class="ml-1 h-3 w-3 animate-spin" />
      </.flash>

      <.flash
        id="server-error"
        kind={:error}
        title={gettext("Something went wrong!")}
        phx-disconnected={show(".phx-server-error #server-error")}
        phx-connected={hide("#server-error")}
        hidden
      >
        {gettext("Hang in there while we get back on track")}
        <.icon name="hero-arrow-path" class="ml-1 h-3 w-3 animate-spin" />
      </.flash>
    </div>
    """
  end

This is the part I'm talking about. We want to add the following to any of the flash messages that we want to have a limited time to show.

        phx-hook="AutoDismiss"
        data-timeout="3000"

Once that is done we need to be sure to add in the Hook

Hooks.AutoDismiss = {
  mounted() {
    // Get the timeout value from the data attribute
    const timeout = this.el.dataset.timeout || 5000; // Default to 5000ms if not provided

    // Set a timeout to hide the flash message
    setTimeout(() => {
      this.el.style.opacity = "0";  // Fade out
      setTimeout(() => {
        this.el.remove();  // Completely remove the flash message from DOM after fade-out
      }, 500);  // Time for fade-out effect
    }, timeout);
  }
}

That should be it. If you want to change the values that we send (time the message will stay up), just change the value for data-timeout #to amount of time in milliseconds