Skip to content
EspañolEnglish
All components (204)

Notification tray

Layers · NotificationTray

What it is and when to use it

The bell with the counter of what is unread and, when pressed, the panel with the latest notifications and how old they are ("4 minutes ago"). It goes in the top bar, normally in the actions of TopBar.

When to use it

  • What happened while nobody was looking: orders, payments, stock running out.
  • onMarkAllRead puts "Mark all as read" in the footer, disabled if nothing unread is left; footer adds whatever is needed next to it ("See all notifications").
  • link on a notification turns it into a real link; without it, it is a button that notifies through onAlertOpen and closes the panel. Both notify through onAlertOpen when pressed.
  • empty is what is seen with no notifications ("No notifications" by default).

When not to

  • Telling something at the moment it happens, without storing it: a notification with useNotifications.
  • An application-wide alert that must be seen without opening anything: GlobalAlert.

Keyboard: the bell is a button (Enter or Space open the panel). Inside, Tab goes through the notifications and the footer. Escape closes and focus returns to the bell.

Accessibility: the unread number is in the button's name ("Notifications, 3 unread"), not only in the red bubble: you can tell whether there is something new on arriving by tabbing. The bubble is cut off at "9+", but the name gives the exact number. Each unread notification says so in words ("· unread"), not only with a colored dot. The panel is a dialog named "Notifications".

Fine-tuning: the width of the panel is set by size (18, 22 or 28 rem); the rest, with the amset-tray__* classes (bell, bubble, list, notification). open and onOpenChange open it from outside: a shortcut, or a notification that has just arrived.

Context: it goes inside LocaleProvider (or AmsetProvider), which decides how the age of each notification is expressed.

What it looks like

Click the bell: 3 unread alerts.

<NotificationTray
  alerts={[
    { key: 'pedido-1042', title: 'Order 1042 shipped', detail: 'Leaves the warehouse today', date: '2026-10-14T09:56:00+02:00' },
    { key: 'factura-0118', title: 'Invoice F-2026-0118 overdue', date: '2026-10-10T09:00:00+02:00', read: true },
  ]}
  onAlertOpen={abrirAviso}
  onMarkAllRead={marcarTodo}
/>

Props

Import it with import { NotificationTray } from '@amset/ui'. Required props are marked.

PropTypeWhat it does
alertsrequiredreadonly TrayAlert[]—
classNamestringMerged with the library classes; it does not replace them.
emptystring—
footerReactNodePanel footer: "View all notifications".
onAlertOpen(key: string) => voidMark one as read, or go to it. Receives the key.
onMarkAllRead() => void—
onOpenChange(open: boolean) => void—
openbooleanTo open the tray from outside (a shortcut, a notice that has just arrived).
size"sm" | "md" | "lg"The width of the panel: 18, 22 or 28 rem.

It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.

In the test bench

Every state and variant, to try one at a time, on its page at ui.amset.tech: