Packages
moon
2.78.4
2.90.5
retired
2.90.4
2.90.3
2.90.2
2.90.1
2.90.0
2.89.4
2.89.1
2.89.0
2.88.0
2.87.11
2.87.10
2.87.9
2.87.8
2.87.7
2.87.6
2.87.5
2.87.4
2.87.3
2.87.2
2.87.1
2.87.0
2.86.1
2.86.0
2.85.1
2.85.0
2.84.0
2.83.0
2.82.0
2.81.4
2.81.3
2.81.2
2.81.1
2.81.0
2.80.2
2.80.1
2.80.0
2.79.13
2.79.12
2.79.11
2.79.10
2.79.9
2.79.8
2.79.7
2.79.6
2.79.5
2.79.4
2.79.3
2.79.2
2.79.1
2.79.0
2.78.4
2.78.3
2.78.2
2.78.1
2.78.0
2.77.0
2.76.5
2.76.4
2.76.3
2.76.2
2.76.1
2.76.0
2.75.0
2.74.1
2.74.0
2.73.8
2.73.7
2.73.6
2.73.5
2.73.4
2.73.3
2.73.2
2.73.1
2.73.0
2.72.5
2.72.4
2.72.3
2.72.2
2.72.1
2.72.0
2.71.1
2.71.0
2.70.0
2.69.2
2.69.1
2.69.0
2.68.11
2.68.10
Components-based design system written in elixir
Current section
Files
Jump to
Current section
Files
lib/moon/components/toast_stack.ex
defmodule Moon.Components.ToastStack do
@moduledoc false
use Moon.StatefulComponent
alias Moon.Components.Toast
alias Moon.Components.Toast.Message
@default_duration 4000
data(toasts, :keyword, default: Keyword.new())
def render(assigns) do
~F"""
<div class="fixed md:top-0 md:right-0 bottom-0 flex flex-col max-w-sm md:max-w-md p-4 items-end overflow-y-scroll overflow-x-hidden mx-auto z-50">
<Toast
:for={{id, toast} <- @toasts}
id={id}
testid={toast.testid || id}
message={toast.message}
variant={toast.variant}
closeable={toast.closeable}
link_text={toast.link_text}
link_href={toast.link_href}
on_close="hide_toast"
/>
</div>
"""
end
def show(toast = %Message{}, id) do
toast =
if toast.id do
toast
else
%{toast | id: generate_id()}
end
send_update(__MODULE__, id: id, toast: toast)
end
def show(toasts, id) when is_list(toasts) do
Enum.each(toasts, fn toast -> show(toast, id) end)
end
def hide_toast(toast_id, stack_id) do
send_update(__MODULE__, id: stack_id, toast_to_hide: toast_id)
end
def update(%{toast: toast}, socket) do
Process.send_after(self(), {:hide_toast, toast.id}, @default_duration)
{:ok, assign(socket, toasts: socket.assigns.toasts ++ [{toast.id, toast}])}
end
def update(%{toast_to_hide: toast_id}, socket) do
{
:ok,
assign(socket, toasts: Keyword.delete(socket.assigns.toasts, toast_id))
}
end
def update(_assigns, socket), do: {:ok, socket}
def handle_event("hide_toast", %{"id" => id}, socket) do
toasts = Keyword.delete(socket.assigns.toasts, String.to_existing_atom(id))
{:noreply, assign(socket, toasts: toasts)}
end
defp generate_id do
12
|> :crypto.strong_rand_bytes()
|> Base.url_encode64()
|> binary_part(0, 12)
|> String.to_atom()
end
end