Filter tabs for notification lists with counts
Tags: component notification filter tabs
Provides filter tabs for filtering notifications by read status (All, Unread, Read). Each tab displays a count badge.
Import
Notification components are available via a separate entry point to make @classic-homes/notifications an optional dependency.
<script>
import { NotificationFilters } from '@classic-homes/theme-svelte/notifications';
</script>Note: Using notification components requires
@classic-homes/notificationsto be installed.
Basic Usage
<script>
import type { NotificationFilter, NotificationCounts } from '@classic-homes/notifications/core';
let filter = $state<NotificationFilter>('all');
const counts: NotificationCounts = {
all: 10,
unread: 3,
read: 7,
};
</script>
<NotificationFilters bind:filter {counts} />Props
| Prop | Type | Default | Description |
|---|---|---|---|
filter |
NotificationFilter |
'all' |
Current active filter (bindable) |
counts |
NotificationCounts |
required | Counts for each filter tab |
onFilterChange |
(filter: NotificationFilter) => void |
- | Callback when filter changes |
class |
string |
- | Additional CSS classes |
Types
From @classic-homes/notifications/core:
type NotificationFilter = 'all' | 'unread' | 'read';
interface NotificationCounts {
all: number;
unread: number;
read: number;
}Filter Tabs
The component renders three tabs:
| Filter | Description |
|---|---|
all |
Shows all notifications |
unread |
Shows only unread notifications |
read |
Shows only read notifications |
Two-Way Binding
Use bind:filter for two-way binding:
<script>
let filter = $state<NotificationFilter>('all');
</script>
<NotificationFilters bind:filter {counts} />
<p>Current filter: {filter}</p>Change Handler
Use onFilterChange to handle filter changes:
<script>
let filter = $state<NotificationFilter>('all');
function handleFilterChange(newFilter: NotificationFilter) {
filter = newFilter;
// Reset selection when filter changes
selectedIds = new Set();
}
</script>
<NotificationFilters bind:filter {counts} onFilterChange={handleFilterChange} />Keyboard Navigation
The component supports full keyboard navigation:
| Key | Action |
|---|---|
| ArrowLeft | Move to previous tab |
| ArrowRight | Move to next tab |
| Home | Move to first tab (All) |
| End | Move to last tab (Read) |
Accessibility
The component includes accessibility features:
- Uses
role="tablist"with properrole="tab"buttons aria-selectedindicates the active tabtabindexmanagement for roving focusaria-labelon the container for screen readers
Examples
With Notification List
<script>
import {
NotificationFilters,
NotificationList,
} from '@classic-homes/theme-svelte/notifications';
import type { Notification, NotificationFilter, NotificationCounts } from '@classic-homes/notifications/core';
let notifications = $state<Notification[]>([...]);
let filter = $state<NotificationFilter>('all');
const counts = $derived<NotificationCounts>({
all: notifications.length,
unread: notifications.filter(n => !n.read).length,
read: notifications.filter(n => n.read).length,
});
const filteredNotifications = $derived(() => {
switch (filter) {
case 'unread': return notifications.filter(n => !n.read);
case 'read': return notifications.filter(n => n.read);
default: return notifications;
}
});
</script>
<NotificationFilters bind:filter {counts} />
<NotificationList
notifications={filteredNotifications()}
emptyTitle={filter === 'unread'
? 'No unread notifications'
: filter === 'read'
? 'No read notifications'
: 'No notifications'}
/>Reset Selection on Filter Change
<script>
let selectedIds = $state(new Set<string>());
function handleFilterChange(newFilter: NotificationFilter) {
filter = newFilter;
selectedIds = new Set(); // Clear selection
}
</script>
<NotificationFilters
bind:filter
{counts}
onFilterChange={handleFilterChange}
/>
<NotificationBulkActions
selectedCount={selectedIds.size}
totalCount={filteredNotifications().length}
{...}
/>Related Components
- NotificationList - Display filtered notifications
- NotificationBulkActions - Bulk action toolbar
- Tabs - General-purpose tab component