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([]);
}
}