Skip to main content

Documentation

NotificationFilters

Filter tabs for notification lists with counts

Tags: component notification filter tabs

View Demo

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/notifications to 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 proper role="tab" buttons
  • aria-selected indicates the active tab
  • tabindex management for roving focus
  • aria-label on 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}
  {...}
/>
On this page