Rich in-app notification components inspired by Ant Design Notification, Mantine Notifications, and Atlassian Flag system.
Distinct from Toast (ephemeral, auto-dismiss after seconds) and Alert (inline static):
notifications are semi-persistent messages representing events — payments received, mentions,
deployments finished, system events. They can live in a notification center panel or as
corner cards manually dismissed by the user.
Sub-components
| Component | Purpose |
|---|---|
notification/1 | Floating corner notification card (manually dismissed) |
notification_item/1 | Row entry inside a notification center list |
notification_center/1 | Dropdown panel container listing notification_item/1 rows |
notification_badge/1 | Unread count badge wrapper for a bell/trigger element |
Floating corner notification
<.notification
id="notif-payment"
variant={:success}
title="Payment received"
description="$99.00 received from Acme Corp."
timestamp="Just now"
/>Notification center with badge
<.notification_badge count={@unread_count}>
<.button variant={:ghost} size={:icon} phx-click="open_notifications">
<.icon name="bell" class="h-5 w-5" />
</.button>
</.notification_badge>
<.notification_center :if={@notifications_open}>
<.notification_item
:for={n <- @notifications}
title={n.title}
description={n.body}
timestamp={n.time_ago}
read={n.read}
variant={n.variant}
/>
<:footer>
<.button variant={:ghost} size={:sm} class="w-full">
View all notifications
</.button>
</:footer>
</.notification_center>Accessibility
notification/1usesrole="alert"+aria-atomic="true"so screen readers announce new notifications immediately.notification_center/1usesrole="region"witharia-label.notification_badge/1provides anaria-labelwith the count for screen readers.- Close button on
notification/1has an explicitaria-label.
Summary
Functions
Renders a floating notification card, typically placed at a corner of the viewport.
Wraps a trigger element with an unread notification count badge.
Renders a dropdown notification center panel.
Renders a single notification row for use inside notification_center/1.
Functions
Renders a floating notification card, typically placed at a corner of the viewport.
Use for semi-persistent events (payments, mentions, deployments) where the user
needs to explicitly dismiss the notification. For auto-dismissing transient messages,
use Toast or GlobalMessage.
Example
<.notification
id="notif-deploy"
variant={:success}
title="Deployment complete"
description="v2.4.1 is now live on production."
timestamp="2 min ago"
>
<:actions>
<.button size={:xs} variant={:ghost} phx-click="view_deploy">View</.button>
</:actions>
</.notification>Attributes
id(:string) (required) - Unique ID — used for JS.hide dismiss animation.title(:string) (required) - Short notification heading.description(:string) - Supporting body text. Defaults tonil.timestamp(:string) - Relative or absolute timestamp string shown below the description (e.g. 'Just now', '3 min ago'). Defaults tonil.variant(:atom) - Controls the border tint and default icon. Defaults to:default. Must be one of:default,:success,:destructive,:warning, or:info.closeable(:boolean) - Whentrue, renders an × dismiss button. Set tofalsefor persistent notifications. Defaults totrue.class(:string) - Additional CSS classes for the root element. Defaults tonil.- Global attributes are accepted. HTML attrs forwarded to the root
<div>.
Slots
icon- Optional custom icon replacing the default variant icon.actions- Optional action buttons rendered below the description.
Wraps a trigger element with an unread notification count badge.
The badge uses position: absolute relative to the wrapper, so the wrapper
uses relative inline-flex. Place your bell icon button as the inner block.
Example
<.notification_badge count={@unread}>
<.button variant={:ghost} size={:icon} aria-label="Open notifications">
<.icon name="bell" class="h-5 w-5" />
</.button>
</.notification_badge>Attributes
count(:integer) - Number of unread notifications. Badge is hidden when 0 (unlessshow_zero). Defaults to0.max(:integer) - Maximum count displayed before showingN+. Default:99. Defaults to99.show_zero(:boolean) - Whentrue, the badge is rendered even whencountis 0. Defaults tofalse.class(:string) - Additional CSS classes for the wrapper. Defaults tonil.- Global attributes are accepted. HTML attrs forwarded to the wrapper
<div>.
Slots
inner_block(required) - The trigger element (button, icon) to wrap.
Renders a dropdown notification center panel.
Place inside a positioned container (e.g. a Popover) to show as a dropdown.
Put notification_item/1 components as the inner content.
Example
<.notification_center>
<:header_actions>
<.button variant={:ghost} size={:sm} phx-click="mark_all_read">
Mark all read
</.button>
</:header_actions>
<.notification_item title="New comment" timestamp="1 min ago" />
<.notification_item title="PR merged" read={true} timestamp="2h ago" />
<:footer>
<.button variant={:ghost} size={:sm} class="w-full">View all</.button>
</:footer>
</.notification_center>Attributes
title(:string) - Panel heading text. Defaults to"Notifications".empty_text(:string) - Message shown when no items are rendered. Defaults to"No notifications yet".class(:string) - Additional CSS classes for the panel. Defaults tonil.- Global attributes are accepted. HTML attrs forwarded to the root
<div>.
Slots
header_actions- Buttons/links placed next to the title, e.g. 'Mark all read', 'Settings'.inner_block- Containsnotification_item/1entries.footer- Optional footer row, e.g. 'View all notifications' link.
Renders a single notification row for use inside notification_center/1.
Displays an unread indicator dot (when read={false}), a variant icon,
title, description, timestamp, and optional inline actions.
Example
<.notification_item
title="Alice mentioned you"
description="@you in #general — 'Can you review my PR?'"
timestamp="5 min ago"
read={false}
variant={:info}
/>Attributes
title(:string) (required) - Notification heading.description(:string) - Supporting detail text. Defaults tonil.timestamp(:string) - Relative timestamp string (e.g. '3 min ago'). Defaults tonil.read(:boolean) - Whenfalse, renders an unread dot and bold title. Defaults tofalse.variant(:atom) - Controls the default icon color. Defaults to:default. Must be one of:default,:success,:destructive,:warning, or:info.class(:string) - Additional CSS classes. Defaults tonil.- Global attributes are accepted. HTML attrs forwarded to the root
<div>.
Slots
icon- Optional custom icon slot.actions- Optional action buttons shown below description.