CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-toastify

React notification library for adding customizable toast notifications to applications

Pending
Overview
Eval results
Files

notification-center.mddocs/

Notification Center

The Notification Center addon provides persistent notification management through a React hook-based API. Unlike regular toasts that automatically disappear, the notification center maintains a persistent list of notifications that users can manage manually.

Package Information

The notification center is distributed as a separate addon:

  • Import Path: react-toastify/addons/use-notification-center
  • Dependencies: Requires react-toastify as a peer dependency

Core Imports

import { useNotificationCenter } from 'react-toastify/addons/use-notification-center';

Capabilities

useNotificationCenter Hook

Main hook for managing persistent notifications with full CRUD operations and state management.

/**
 * React hook for managing a persistent notification center
 * @param params - Optional configuration parameters
 * @returns Notification center API with methods and state
 */
function useNotificationCenter<T = {}>(
  params?: UseNotificationCenterParams<T>
): UseNotificationCenter<T>;

interface UseNotificationCenterParams<T = {}> {
  /** Initial notifications to populate the center (for rehydration) */
  data?: NotificationCenterItem<T>[];
  /** Filter function to determine which notifications to include */
  filter?: FilterFn<T>;
  /** Sort function to order notifications */
  sort?: SortFn<T>;
}

type FilterFn<T = {}> = (item: NotificationCenterItem<T>) => boolean;
type SortFn<T = {}> = (a: NotificationCenterItem<T>, b: NotificationCenterItem<T>) => number;

interface UseNotificationCenter<T = {}> {
  /** Array of all notifications in the center */
  notifications: NotificationCenterItem<T>[];
  /** Remove all notifications from the center */
  clear(): void;
  /** Mark all notifications as read or unread */
  markAllAsRead(read?: boolean): void;
  /** Mark specific notifications as read or unread */
  markAsRead(id: Id | Id[], read?: boolean): void;
  /** Remove specific notifications from the center */
  remove(id: Id | Id[]): void;
  /** Add a new notification to the center */
  add(item: NotificationCenterItem<T>): void;
  /** Update an existing notification */
  update(id: Id, item: Partial<NotificationCenterItem<T>>): void;
  /** Find notification(s) by ID */
  find(id: Id): NotificationCenterItem<T> | undefined;
  /** Sort notifications using a custom comparator */
  sort(compareFn: SortFn<T>): void;
  /** Number of unread notifications */
  unreadCount: number;
}

Basic Usage:

import React from 'react';
import { useNotificationCenter } from 'react-toastify/addons/use-notification-center';

function NotificationCenter() {
  const {
    notifications,
    clear,
    markAllAsRead,
    markAsRead,
    remove,
    unreadCount
  } = useNotificationCenter();

  return (
    <div className="notification-center">
      <div className="header">
        <h3>Notifications ({unreadCount} unread)</h3>
        <button onClick={() => markAllAsRead()}>Mark All Read</button>
        <button onClick={clear}>Clear All</button>
      </div>
      
      <div className="notifications">
        {notifications.map(notification => (
          <div 
            key={notification.id}
            className={`notification ${notification.read ? 'read' : 'unread'}`}
          >
            <div className="content">{notification.content}</div>
            <div className="actions">
              <button onClick={() => markAsRead(notification.id)}>
                {notification.read ? 'Mark Unread' : 'Mark Read'}
              </button>
              <button onClick={() => remove(notification.id)}>Remove</button>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

Adding Notifications

Add notifications to the center programmatically or from toast events.

/**
 * Add a new notification to the center
 * @param item - The notification item to add
 */
add(item: NotificationCenterItem<T>): void;

Manual Addition:

function MyComponent() {
  const { add } = useNotificationCenter();

  const addNotification = () => {
    add({
      id: Date.now().toString(),
      content: "New notification message",
      theme: "light",
      type: "info",
      read: false,
      createdAt: Date.now(),
      data: { source: 'manual' }
    });
  };

  return <button onClick={addNotification}>Add Notification</button>;
}

From Toast Events:

import { toast } from 'react-toastify';
import { useNotificationCenter } from 'react-toastify/addons/use-notification-center';

function MyComponent() {
  const { add } = useNotificationCenter();

  const showToastAndAddToCenter = () => {
    const toastId = toast.success("Operation completed", {
      onClose: () => {
        // Add to notification center when toast closes
        add({
          id: toastId.toString(),
          content: "Operation completed successfully",
          type: "success",
          read: false,
          createdAt: Date.now()
        });
      }
    });
  };

  return <button onClick={showToastAndAddToCenter}>Show Toast</button>;
}

Managing Read State

Control the read/unread state of notifications individually or in bulk.

/**
 * Mark all notifications as read or unread
 * @param read - True to mark as read, false for unread (default: true)
 */
markAllAsRead(read?: boolean): void;

/**
 * Mark specific notifications as read or unread
 * @param id - Single ID or array of IDs to mark
 * @param read - True to mark as read, false for unread (default: true)
 */
markAsRead(id: Id | Id[], read?: boolean): void;

Usage Examples:

const { markAllAsRead, markAsRead, notifications } = useNotificationCenter();

// Mark all as read
markAllAsRead();

// Mark all as unread
markAllAsRead(false);

// Mark specific notification as read
markAsRead('notification-1');

// Mark multiple notifications as read
markAsRead(['notification-1', 'notification-2']);

// Mark as unread
markAsRead('notification-1', false);

// Toggle read state
const toggleRead = (id: string) => {
  const notification = notifications.find(n => n.id === id);
  if (notification) {
    markAsRead(id, !notification.read);
  }
};

Removing Notifications

Remove individual notifications or clear the entire center.

/**
 * Remove specific notifications from the center
 * @param id - Single ID or array of IDs to remove
 */
remove(id: Id | Id[]): void;

/**
 * Remove all notifications from the center
 */
clear(): void;

Usage Examples:

const { remove, clear } = useNotificationCenter();

// Remove single notification
remove('notification-1');

// Remove multiple notifications
remove(['notification-1', 'notification-2']);

// Clear all notifications
clear();

// Remove all read notifications
const removeAllRead = () => {
  const readIds = notifications
    .filter(n => n.read)
    .map(n => n.id);
  remove(readIds);
};

Updating Notifications

Modify existing notifications in the center.

/**
 * Update an existing notification
 * @param id - The ID of the notification to update
 * @param item - Partial notification item with fields to update
 */
update(id: Id, item: Partial<NotificationCenterItem<T>>): void;

Usage Examples:

const { update } = useNotificationCenter();

// Update notification content
update('notification-1', {
  content: "Updated message content",
  read: true
});

// Update notification data
update('notification-1', {
  data: { ...existingData, priority: 'high' }
});

// Update notification theme
update('notification-1', {
  theme: 'dark',
  type: 'warning'
});

Finding and Sorting

Search for specific notifications and customize the display order.

/**
 * Find a notification by ID
 * @param id - The ID to search for
 * @returns The notification item or undefined if not found
 */
find(id: Id): NotificationCenterItem<T> | undefined;

/**
 * Sort notifications using a custom comparator function
 * @param compareFn - Function to determine sort order
 */
sort(compareFn: SortFn<T>): void;

type SortFn<T> = (a: NotificationCenterItem<T>, b: NotificationCenterItem<T>) => number;

Usage Examples:

const { find, sort, notifications } = useNotificationCenter();

// Find specific notification
const notification = find('notification-1');
if (notification) {
  console.log('Found:', notification.content);
}

// Sort by creation time (newest first)
sort((a, b) => b.createdAt - a.createdAt);

// Sort by read status (unread first)
sort((a, b) => {
  if (a.read === b.read) return 0;
  return a.read ? 1 : -1;
});

// Sort by type priority
const typePriority = { error: 0, warning: 1, info: 2, success: 3 };
sort((a, b) => typePriority[a.type] - typePriority[b.type]);

Configuration Options

Initialize the notification center with custom settings and data.

interface UseNotificationCenterParams<T = {}> {
  /** Initial notifications to populate the center */
  data?: NotificationCenterItem<T>[];
  /** Maximum number of notifications to keep (oldest removed first) */
  limit?: number;
  /** Filter function to determine which notifications to include */
  filter?: FilterFn<T>;
  /** Sort function to order notifications */
  sort?: SortFn<T>;
}

type FilterFn<T> = (notification: NotificationCenterItem<T>) => boolean;
type SortFn<T> = (a: NotificationCenterItem<T>, b: NotificationCenterItem<T>) => number;

Configuration Examples:

// Initialize with data and limit
const { notifications } = useNotificationCenter({
  data: [
    {
      id: '1',
      content: 'Welcome notification',
      type: 'info',
      read: false,
      createdAt: Date.now()
    }
  ],
  limit: 50,
  filter: (notification) => !notification.read, // Only show unread
  sort: (a, b) => b.createdAt - a.createdAt     // Newest first
});

// Filter for important notifications only
const { notifications: importantNotifications } = useNotificationCenter({
  filter: (notification) => 
    notification.data?.priority === 'high' || notification.type === 'error'
});

Integration with Toast Events

Automatically populate the notification center from toast lifecycle events.

import { toast } from 'react-toastify';
import { useNotificationCenter } from 'react-toastify/addons/use-notification-center';

function IntegratedNotifications() {
  const { add, notifications } = useNotificationCenter();

  // Subscribe to toast events
  React.useEffect(() => {
    const unsubscribe = toast.onChange((payload) => {
      if (payload.status === 'added') {
        // Add to notification center when toast appears
        add({
          id: payload.id.toString(),
          content: payload.content,
          type: payload.type || 'default',
          theme: payload.theme || 'light',
          read: false,
          createdAt: Date.now(),
          data: payload.data
        });
      }
    });

    return unsubscribe;
  }, [add]);

  const showToast = () => {
    toast.success("This will appear in both toast and notification center");
  };

  return (
    <div>
      <button onClick={showToast}>Show Toast</button>
      <div>Notification Center has {notifications.length} items</div>
    </div>
  );
}

Notification Item Type

interface NotificationCenterItem<T = {}> {
  /** Unique identifier for the notification */
  id: Id;
  /** Content to display (string, React node, or render function) */
  content: ToastContent<T>;
  /** Timestamp when notification was created */
  createdAt: number;
  /** Whether the notification has been read */
  read?: boolean;
  /** Toast type for styling and icons */
  type?: TypeOptions;
  /** Theme for styling */
  theme?: Theme;
  /** Custom data associated with the notification */
  data?: T;
  /** Custom icon for the notification */
  icon?: ToastIcon;
}

Advanced Patterns

Persistent Storage

Save notification center state to localStorage:

function usePersistentNotificationCenter<T>() {
  const STORAGE_KEY = 'notification-center';
  
  // Load initial data from storage
  const loadInitialData = (): NotificationCenterItem<T>[] => {
    try {
      const stored = localStorage.getItem(STORAGE_KEY);
      return stored ? JSON.parse(stored) : [];
    } catch {
      return [];
    }
  };

  const nc = useNotificationCenter<T>({
    data: loadInitialData()
  });

  // Save to storage whenever notifications change
  React.useEffect(() => {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(nc.notifications));
  }, [nc.notifications]);

  return nc;
}

Notification Categories

Group notifications by category:

interface CategorizedNotification {
  category: 'system' | 'user' | 'marketing';
  priority: 'low' | 'medium' | 'high';
}

function CategorizedNotificationCenter() {
  const { notifications, add } = useNotificationCenter<CategorizedNotification>();

  const notificationsByCategory = React.useMemo(() => {
    return notifications.reduce((acc, notification) => {
      const category = notification.data?.category || 'system';
      if (!acc[category]) acc[category] = [];
      acc[category].push(notification);
      return acc;
    }, {} as Record<string, NotificationCenterItem<CategorizedNotification>[]>);
  }, [notifications]);

  return (
    <div>
      {Object.entries(notificationsByCategory).map(([category, items]) => (
        <div key={category}>
          <h4>{category} ({items.length})</h4>
          {items.map(item => (
            <div key={item.id}>{item.content}</div>
          ))}
        </div>
      ))}
    </div>
  );
}

Install with Tessl CLI

npx tessl i tessl/npm-react-toastify

docs

container.md

index.md

notification-center.md

toast-api.md

transitions.md

utilities.md

tile.json