PhoenixPaper.Snackbar (PhoenixPaper v0.1.0)

Copy Markdown View Source

A brief toast notification (pp_snackbar/1), in the spirit of MUI's Snackbar.

<.pp_snackbar open={@flash_message != nil}>
  {@flash_message}
  <:action>
    <.pp_button variant="text" phx-click="dismiss_flash">Dismiss</.pp_button>
  </:action>
</.pp_snackbar>

Deliberately presentation-only — positioning (anchor_origin), the dark inverted-surface chip, a mount-in transition, and the optional :action slot, nothing else. A few things MUI's Snackbar has that this doesn't, and why:

  • No autoHideDuration. Auto-dismiss-after-a-few-seconds is one Process.send_after/3 in your LiveView clearing whatever assign controls open — the same mechanism mix phx.new's generated flash messages already use. A client-side JS timer here would just be a second, redundant way to do the same thing, and one that can drift out of sync with the server's own idea of whether the message is still live.

  • No exit transition. open={false} removes the element from the DOM immediately (:if under the hood) — animating that would need the same always-rendered-plus-Phoenix.LiveView.JS machinery PhoenixPaper.Dialog uses, which is a much bigger component for a toast. transition only animates the entrance (a real CSS @keyframes animation that plays once when the element mounts), which covers the common case — a snackbar popping in — without needing that machinery.

  • No built-in queueing of consecutive snackbars (MUI shows them one at a time, queued). That needs a place to actually hold the queue — a LiveComponent or a list in your LiveView's own assigns — not something a stateless function component can own. Render one pp_snackbar for whatever message you're currently showing; queuing which message that is is your call, the same as it would be building this by hand.

  • No dedicated "wrap an Alert" mode — MUI's Snackbar skips its own background/padding when given a child instead of message/action, so an Alert inside shows only the Alert's own colors. Here, pass paperize={false} (drops the inverted-surface chip and the positioning classes together, this library's usual all-or-nothing contract) and supply both back yourself via class:

    <.pp_snackbar paperize={false} class="fixed inset-x-4 bottom-4 z-50 mx-auto w-fit">
      <.pp_alert severity="success">Changes saved.</.pp_alert>
    </.pp_snackbar>

Always uses bg-pp-on-surface/text-pp-surface regardless of the current theme — an inverted surface (dark chip on a light theme, light chip on a dark theme) is the Material spec for a snackbar, not a themed surface like PhoenixPaper.Paper.

Summary

Functions

Renders a snackbar. See the module doc.

Functions

pp_snackbar(assigns)

Renders a snackbar. See the module doc.

Attributes

  • paperize (:boolean) - Defaults to true.
  • open (:boolean) - Defaults to true.
  • anchor_origin (:string) - corner/edge of the viewport it's anchored to. Defaults to "bottom-left". Must be one of "bottom-left", "bottom-center", "bottom-right", "top-left", "top-center", or "top-right".
  • transition (:string) - the mount-in animation — there's no exit transition, see the module doc. Defaults to "grow". Must be one of "grow", "fade", "slide", or "none".
  • elevation (:integer) - Defaults to 6.
  • class (:any) - Defaults to nil.
  • Global attributes are accepted.

Slots

  • action
  • inner_block (required)