Toast

Non-intrusive notification components for feedback and status updates with auto-dismiss functionality.

Toast Types

Success Toast

Error Toast

Warning Toast

Info Toast

Toast with Progress

Persistent Toast

Static Examples

Property Saved
Your property has been successfully saved to favorites.
Upload Failed
Could not upload images. Please try again.
Limited Availability
Only 2 units remaining in this building.
New Properties
5 new properties match your criteria.

Implementation Guide

HTML Structure

<!-- Toast Container -->
<div class="lyd-toast-container">
    <!-- Success Toast -->
    <div class="lyd-toast success">
        <svg class="lyd-toast-icon">...</svg>
        <div class="lyd-toast-content">
            <div class="lyd-toast-title">Success!</div>
            <div class="lyd-toast-message">Operation completed successfully.</div>
        </div>
        <button class="lyd-toast-close">
            <svg>...</svg>
        </button>
    </div>
    
    <!-- Toast with Progress -->
    <div class="lyd-toast info">
        <svg class="lyd-toast-icon">...</svg>
        <div class="lyd-toast-content">
            <div class="lyd-toast-title">Processing</div>
            <div class="lyd-toast-message">Please wait...</div>
        </div>
        <div class="lyd-toast-progress"></div>
    </div>
</div>

JavaScript Functions

// Toast Manager
class ToastManager {
    constructor() {
        this.container = null;
        this.init();
    }
    
    init() {
        // Create container if it doesn't exist
        if (!document.querySelector('.lyd-toast-container')) {
            this.container = document.createElement('div');
            this.container.className = 'lyd-toast-container';
            document.body.appendChild(this.container);
        } else {
            this.container = document.querySelector('.lyd-toast-container');
        }
    }
    
    show(type, title, message, duration = 5000) {
        const toast = document.createElement('div');
        toast.className = `lyd-toast ${type}`;
        
        const icons = {
            success: '<path d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />',
            error: '<path d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />',
            warning: '<path d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />',
            info: '<path d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />'
        };
        
        toast.innerHTML = `
            <svg class="lyd-toast-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                ${icons[type]}
            </svg>
            <div class="lyd-toast-content">
                <div class="lyd-toast-title">${title}</div>
                <div class="lyd-toast-message">${message}</div>
            </div>
            <button class="lyd-toast-close">
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
                </svg>
            </button>
            ${duration > 0 ? '<div class="lyd-toast-progress"></div>' : ''}
        `;
        
        this.container.appendChild(toast);
        
        // Close button
        toast.querySelector('.lyd-toast-close').addEventListener('click', () => {
            this.hide(toast);
        });
        
        // Auto dismiss
        if (duration > 0) {
            setTimeout(() => {
                this.hide(toast);
            }, duration);
        }
    }
    
    hide(toast) {
        toast.classList.add('hiding');
        setTimeout(() => {
            toast.remove();
        }, 300);
    }
}

// Initialize
const toastManager = new ToastManager();

// Helper functions
function showToast(type) {
    const messages = {
        success: { title: 'Success!', message: 'Operation completed successfully.' },
        error: { title: 'Error!', message: 'Something went wrong. Please try again.' },
        warning: { title: 'Warning!', message: 'Please check your input.' },
        info: { title: 'Info', message: 'Here\'s some useful information.' }
    };
    
    toastManager.show(type, messages[type].title, messages[type].message);
}

React/Next.js Component

// components/Toast.tsx
import { useState, useEffect } from 'react';
import { createPortal } from 'react-dom';

interface ToastProps {
  type: 'success' | 'error' | 'warning' | 'info';
  title: string;
  message: string;
  duration?: number;
  onClose: () => void;
}

export const Toast = ({ type, title, message, duration = 5000, onClose }: ToastProps) => {
  const [isVisible, setIsVisible] = useState(true);
  
  useEffect(() => {
    if (duration > 0) {
      const timer = setTimeout(() => {
        setIsVisible(false);
        setTimeout(onClose, 300);
      }, duration);
      
      return () => clearTimeout(timer);
    }
  }, [duration, onClose]);
  
  const icons = {
    success: 'M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z',
    error: 'M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z',
    warning: 'M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z',
    info: 'M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z'
  };
  
  return createPortal(
    <div className={`lyd-toast ${type} ${!isVisible ? 'hiding' : ''}`}>
      <svg className="lyd-toast-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d={icons[type]} />
      </svg>
      <div className="lyd-toast-content">
        <div className="lyd-toast-title">{title}</div>
        <div className="lyd-toast-message">{message}</div>
      </div>
      <button className="lyd-toast-close" onClick={() => {
        setIsVisible(false);
        setTimeout(onClose, 300);
      }}>
        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
        </svg>
      </button>
      {duration > 0 && <div className="lyd-toast-progress" />}
    </div>,
    document.body
  );
};

API Reference

Class Description
.lyd-toast-container Container for toast notifications
.lyd-toast Individual toast notification
.lyd-toast-icon Toast type icon
.lyd-toast-content Content wrapper
.lyd-toast-title Toast title text
.lyd-toast-message Toast message text
.lyd-toast-close Close button
.lyd-toast-progress Auto-dismiss progress bar
.success Success toast styling
.error Error toast styling
.warning Warning toast styling
.info Info toast styling

Accessibility & Best Practices

Accessibility Features

  • ARIA live regions for screen readers
  • Keyboard dismissible (Escape key)
  • Focus management
  • Sufficient color contrast

Best Practices

  • Keep messages concise and actionable
  • Use appropriate types for context
  • Auto-dismiss after 5-7 seconds
  • Allow manual dismissal
  • Stack multiple toasts vertically
  • Position consistently (top-right recommended)