Home Posts Post Search Tag Search

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);
  }
}

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