Toolbar for selecting and performing bulk actions on notifications
Tags: component notification bulk actions toolbar
Toolbar for selecting multiple notifications and performing bulk actions like mark as read, mark as unread, and delete.
Import
Notification components are available via a separate entry point to make @classic-homes/notifications an optional dependency.
<script>
import { NotificationBulkActions } from '@classic-homes/theme-svelte/notifications';
</script>Note: Using notification components requires
@classic-homes/notificationsto be installed.
Basic Usage
<script>
let selectedIds = $state(new Set<string>());
const notifications = [...];
</script>
<NotificationBulkActions
selectedCount={selectedIds.size}
totalCount={notifications.length}
allSelected={selectedIds.size === notifications.length}
onSelectAll={(selected) => {
/* ... */
}}
onMarkRead={() => {
/* ... */
}}
onMarkUnread={() => {
/* ... */
}}
onDelete={() => {
/* ... */
}}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
selectedCount |
number |
required | Number of currently selected notifications |
totalCount |
number |
required | Total number of notifications available |
allSelected |
boolean |
false |
Whether all notifications are selected |
onSelectAll |
(selected: boolean) => void |
- | Callback to select/deselect all |
onMarkRead |
() => void |
- | Callback to mark selected as read |
onMarkUnread |
() => void |
- | Callback to mark selected as unread |
onDelete |
() => void |
- | Callback to delete selected |
onClearSelection |
() => void |
- | Callback to clear selection |
class |
string |
- | Additional CSS classes |
Visual States
No Selection
When no items are selected, only the "Select all" checkbox is shown:
<NotificationBulkActions selectedCount={0} totalCount={10} allSelected={false} />Partial Selection
When some items are selected, action buttons appear:
<NotificationBulkActions selectedCount={3} totalCount={10} allSelected={false} />
<!-- Shows: "3 of 10 selected" with Clear button and action buttons -->All Selected
When all items are selected:
<NotificationBulkActions selectedCount={10} totalCount={10} allSelected={true} />Actions
Select All
Toggle selection of all visible notifications:
<script>
function handleSelectAll(selected: boolean) {
if (selected) {
selectedIds = new Set(filteredNotifications().map(n => n.id));
} else {
selectedIds = new Set();
}
}
</script>
<NotificationBulkActions
onSelectAll={handleSelectAll}
{...}
/>Mark as Read
Mark all selected notifications as read:
<script>
function handleBulkMarkRead() {
const count = selectedIds.size;
notifications = notifications.map(n =>
selectedIds.has(n.id)
? { ...n, read: true, readAt: new Date().toISOString() }
: n
);
selectedIds = new Set();
toastStore.success(`Marked ${count} notifications as read`);
}
</script>
<NotificationBulkActions
onMarkRead={handleBulkMarkRead}
{...}
/>Mark as Unread
Mark all selected notifications as unread:
<script>
function handleBulkMarkUnread() {
const count = selectedIds.size;
notifications = notifications.map(n =>
selectedIds.has(n.id)
? { ...n, read: false, readAt: undefined }
: n
);
selectedIds = new Set();
toastStore.info(`Marked ${count} notifications as unread`);
}
</script>
<NotificationBulkActions
onMarkUnread={handleBulkMarkUnread}
{...}
/>Delete
Delete all selected notifications:
<script>
function handleBulkDelete() {
const count = selectedIds.size;
notifications = notifications.filter(n => !selectedIds.has(n.id));
selectedIds = new Set();
toastStore.info(`Deleted ${count} notifications`);
}
</script>
<NotificationBulkActions
onDelete={handleBulkDelete}
{...}
/>Examples
Complete Implementation
<script>
import { toastStore } from '@classic-homes/theme-svelte';
import {
NotificationList,
NotificationFilters,
NotificationBulkActions,
} 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');
let selectedIds = $state(new Set<string>());
const filteredNotifications = $derived(() => {
switch (filter) {
case 'unread': return notifications.filter(n => !n.read);
case 'read': return notifications.filter(n => n.read);
default: return notifications;
}
});
const counts = $derived<NotificationCounts>({
all: notifications.length,
unread: notifications.filter(n => !n.read).length,
read: notifications.filter(n => n.read).length,
});
const allSelected = $derived(
filteredNotifications().length > 0 &&
filteredNotifications().every(n => selectedIds.has(n.id))
);
function handleToggleSelect(id: string, selected: boolean) {
const newSet = new Set(selectedIds);
if (selected) newSet.add(id);
else newSet.delete(id);
selectedIds = newSet;
}
function handleSelectAll(selected: boolean) {
if (selected) {
selectedIds = new Set(filteredNotifications().map(n => n.id));
} else {
selectedIds = new Set();
}
}
function handleClearSelection() {
selectedIds = new Set();
}
function handleBulkMarkRead() {
notifications = notifications.map(n =>
selectedIds.has(n.id)
? { ...n, read: true, readAt: new Date().toISOString() }
: n
);
selectedIds = new Set();
toastStore.success('Marked as read');
}
function handleBulkMarkUnread() {
notifications = notifications.map(n =>
selectedIds.has(n.id)
? { ...n, read: false, readAt: undefined }
: n
);
selectedIds = new Set();
toastStore.info('Marked as unread');
}
function handleBulkDelete() {
notifications = notifications.filter(n => !selectedIds.has(n.id));
selectedIds = new Set();
toastStore.info('Deleted');
}
</script>
<NotificationFilters bind:filter {counts} onFilterChange={() => (selectedIds = new Set())} />
{#if filteredNotifications().length > 0}
<NotificationBulkActions
selectedCount={selectedIds.size}
totalCount={filteredNotifications().length}
{allSelected}
onSelectAll={handleSelectAll}
onMarkRead={handleBulkMarkRead}
onMarkUnread={handleBulkMarkUnread}
onDelete={handleBulkDelete}
onClearSelection={handleClearSelection}
/>
{/if}
<NotificationList
notifications={filteredNotifications()}
{selectedIds}
selectable={true}
onToggleSelect={handleToggleSelect}
/>Related Components
- NotificationList - Display notifications with selection
- NotificationFilters - Filter tabs
- NotificationItem - Single notification with checkbox