← All @molecule/* packages · App templates

@molecule/app-notification-feed-react

Feature · notification-feed · App (browser) · v1.0.1 · Apache-2.0

Vertical notification feed: typed icon + title + body + relative time + unread indicator, with optional per-row link wrapping

npm install @molecule/app-notification-feed-react

npm · Source on GitHub

How it works

@molecule/app-notification-feed-react is a ready-made notification-feed feature for the app (browser) side. It composes the core interfaces it needs, so it works with whichever providers your app has bonded.

import { NotificationFeed } from '@molecule/app-notification-feed-react'

const items = [
  { id: '1', icon: 'check_circle', title: 'Build succeeded', body: 'main branch deployed to prod', createdAt: '2024-06-01T09:00:00Z', unread: true, href: '/deployments/42' },
  { id: '2', icon: 'chat', title: 'New comment', body: 'Alice left a comment on PR #17', createdAt: '2024-06-01T08:30:00Z' },
]

<NotificationFeed items={items} ariaLabel="Notifications" dataMolId="notification-feed" />

Works with: @molecule/app-react, @molecule/app-ui

Reference

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Vertical notification feed.

Exports <NotificationFeed> — a list of notification rows with typed icon, title, body, relative time, and unread indicator. Optionally wraps each row in a Link if the notification has an href.

Quick Start

import { NotificationFeed } from '@molecule/app-notification-feed-react'

const items = [
  { id: '1', icon: 'check_circle', title: 'Build succeeded', body: 'main branch deployed to prod', createdAt: '2024-06-01T09:00:00Z', unread: true, href: '/deployments/42' },
  { id: '2', icon: 'chat', title: 'New comment', body: 'Alice left a comment on PR #17', createdAt: '2024-06-01T08:30:00Z' },
]

<NotificationFeed items={items} ariaLabel="Notifications" dataMolId="notification-feed" />

Type

feature

Installation

npm install @molecule/app-notification-feed-react @molecule/app-react @molecule/app-ui react react-router
npm install -D @types/react

API

Interfaces

FeedItem

A single item rendered inside a NotificationFeed list.

interface FeedItem {
  /** Stable identifier (used as React key). */
  id: string
  /** Material symbol icon name (e.g. `'check_circle'`, `'chat'`). */
  icon: string
  /** Bolded headline string. */
  title: string
  /** Secondary body string. */
  body: string
  /** ISO timestamp shown as relative time on the right. */
  createdAt: string
  /** Optional route — when set, wraps the row in `<Link>`. */
  href?: string | null
  /** When true, the row gets a left primary-accent border. */
  unread?: boolean
}

NotificationFeedProps

Props for the NotificationFeed component.

interface NotificationFeedProps {
  /** Items to render, top to bottom. */
  items: ReadonlyArray<FeedItem>
  /** Aria-label for the underlying `<ul>`. */
  ariaLabel?: string
  /** Extra classes on the outer `<ul>`. */
  className?: string
  /** `data-mol-id` for AI-agent selectors. */
  dataMolId?: string
}

Functions

fmtRelativeShort(iso)

Render an ISO timestamp as a short relative string: "12m", "3h", "5d".

Used by NotificationFeed to keep the timestamp tight enough to fit the top-right corner of a feed row.

function fmtRelativeShort(iso: string): string
  • iso — ISO 8601 timestamp string

Returns: short relative string (e.g. "12m", "3h", "5d")

NotificationFeed(props)

Vertical notification feed: typed icon + title + body + relative time with optional unread border-l accent and optional per-row Link.

Apps build their own typed-icon mapping (notif.type → icon name) and pass the resolved icon string in. Keeps this package free of per-app type unions.

function NotificationFeed({
  items,
  ariaLabel,
  className,
  dataMolId,
}: NotificationFeedProps): JSX.Element
  • props — Component props (see {@link NotificationFeedProps}).

Injection Notes

Requirements

Peer dependencies:

  • @molecule/app-react ^1.0.1
  • @molecule/app-ui ^1.0.1
  • react ^18.0.0 || ^19.0.0
  • react-router ^7.0.0 || ^8.0.0

Runtime Dependencies

  • @molecule/app-react
  • @molecule/app-ui
  • react
  • react-router

FeedItem.icon is a Material Symbols LIGATURE — the app must load the "Material Symbols Outlined" font and define the material-symbols-outlined CSS class, or icon names render as plain text (the literal string check_circle). The icon circle background and the unread left-border accent additionally rely on raw Tailwind utilities (bg-primary-container, border-l-4) that standard molecule scaffolds neither scan nor theme — add an @source line for this package's dist plus a primary-container theme color, or expect both to be invisible until the package is migrated to ClassMap.

Rows WITH href render a react-router <Link> — they THROW outside a <Router> context. In apps not using react-router, omit href (rows render as plain divs) or handle navigation on a wrapping element. Requires a wired ClassMap bond — getClassMap() throws before wiring.

fmtRelativeShort (exported) renders compact 12m / 3h / 5d strings with English unit letters — swap in your own formatter for localized feeds by pre-formatting and rendering your own rows.

E2E Tests

Integration checklist — drive the real UI (live preview, no mocks), adapt each item to this app's actual screens/flows, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:

  • The feed renders real notifications with icon, title, body, and a relative time — no undefined fields or raw timestamps.
  • Unread rows are visibly distinct, and any unread badge/count matches the number of unread rows.
  • Clicking a notification that carries an href navigates to its target.
  • Marking as read (however this app wires it) clears the unread state and it stays cleared after a full reload.
  • Performing an action the app notifies about adds a new notification to the feed (newest first).
  • An empty feed shows a readable empty state — not a blank panel.