<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/monokai-sublime.min.css" integrity="sha512-ade8vHOXH67Cm9z/U2vBpckPD1Enhdxl3N05ChXyFx5xikfqggrK4RrEele+VWY/iaZyfk7Bhk6CyZvlh7+5JQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
🌾 ng-oatv0.6.0Angular UI library

Notifications

A notification feed with dismissible items, unread badges, and clear-all action.

Preview

Notifications5
Welcome!Your account has been created successfully.2 min ago

New commentAlice replied to your post.15 min ago

New followerBob started following you.1 hour ago

ReminderYour subscription renews tomorrow.3 hours ago

Update availableng-oat v2.1 is now available.1 day ago

html
<div class="max-w-lg">
  <div class="card">
    <header class="flex flex-wrap items-center gap-4 justify-between">
      <div class="flex flex-wrap items-center gap-2">
        <strong>Notifications</strong>
        <ng-oat-badge variant="secondary">{{ notifications().length }}</ng-oat-badge>
      </div>
      <button class="btn ghost small" (click)="clearAll()">Clear all</button>
    </header>
    <div class="flex flex-col gap-1">
      @for (item of notifications(); track item.id) {
        <div class="flex flex-wrap gap-3 items-start p-2">
          <ng-oat-icon [icon]="item.icon" [size]="18" />
          <div class="flex flex-col gap-1 flex-1">
            <strong class="text-sm">{{ item.title }}</strong>
            <span class="text-sm text-muted">{{ item.description }}</span>
            <small class="text-muted">{{ item.time }}</small>
          </div>
          <button class="btn ghost small" (click)="dismiss(item.id)"><ng-oat-icon [icon]="iconX" [size]="14" /></button>
        </div>
        <hr />
      } @empty {
        <p class="text-center text-muted py-4">No notifications</p>
      }
    </div>
  </div>
</div>

SFC Source

typescript
import { Component, signal } from '@angular/core';
import { NgOatBadge } from '@letsprogram/ng-oat/badge';
import { NgOatIcon, type NgOatIconData, iconConfetti, iconMessage, iconStar, iconX } from '@letsprogram/ng-oat/icons';

@Component({
  selector: 'app-notifications',
  imports: [NgOatBadge, NgOatIcon],
  template: `
    <div class="max-w-lg">
      <div class="card">
        <header class="flex flex-wrap items-center gap-4 justify-between">
          <div class="flex flex-wrap items-center gap-2">
            <strong>Notifications</strong>
            <ng-oat-badge variant="secondary">{{ notifications().length }}</ng-oat-badge>
          </div>
          <button class="btn ghost small" (click)="clearAll()">Clear all</button>
        </header>
        <div class="flex flex-col gap-1">
          @for (item of notifications(); track item.id) {
            <div class="flex flex-wrap gap-3 items-start p-2">
              <ng-oat-icon [icon]="item.icon" [size]="18" />
              <div class="flex flex-col gap-1 flex-1">
                <strong class="text-sm">{{ item.title }}</strong>
                <span class="text-sm text-muted">{{ item.description }}</span>
                <small class="text-muted">{{ item.time }}</small>
              </div>
              <button class="btn ghost small" (click)="dismiss(item.id)"><ng-oat-icon [icon]="iconX" [size]="14" /></button>
            </div>
            <hr />
          } @empty {
            <p class="text-center text-muted py-4">No notifications</p>
          }
        </div>
      </div>
    </div>
  `,
})
export class NotificationsComponent {
  iconX = iconX;

  notifications = signal<{ id: number; icon: NgOatIconData; title: string; description: string; time: string }[]>([
    { id: 1, icon: iconConfetti, title: 'Welcome!', description: 'Account created.', time: '2 min ago' },
    { id: 2, icon: iconMessage, title: 'New comment', description: 'Alice replied.', time: '15 min ago' },
    { id: 3, icon: iconStar, title: 'New follower', description: 'Bob followed you.', time: '1 hour ago' },
  ]);

  dismiss(id: number) {
    this.notifications.update(list => list.filter(n => n.id !== id));
  }

  clearAll() {
    this.notifications.set([]);
  }
}