All files / src/shared/components/Toast Toast.tsx

0% Statements 0/56
0% Branches 0/1
0% Functions 0/1
0% Lines 0/56

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66                                                                                                                                   
import { useEffect, useMemo } from 'react';
import { createPortal } from 'react-dom';
import { useToastStore } from '@/store/useToastStore';
import Button, { ButtonVariant } from '../button/Button';
import { FaTimes } from 'react-icons/fa';
import './Toast.scss';
 
const Toast = () => {
  const { toasts, removeToast } = useToastStore();
 
  useEffect(() => {
    const timers = new Map<string, ReturnType<typeof setTimeout>>();
 
    toasts.forEach((toast) => {
      if (toast.duration && toast.duration > 0 && !timers.has(toast.id)) {
        const timer = setTimeout(() => {
          removeToast(toast.id);
          timers.delete(toast.id);
        }, toast.duration);
        timers.set(toast.id, timer);
      }
    });
 
    return () => {
      timers.forEach((timer) => clearTimeout(timer));
      timers.clear();
    };
  }, [toasts, removeToast]);
 
  const renderedToasts = useMemo(() => {
    return toasts.map((toast) => (
      <div
        key={toast.id}
        className={`toast toast-${toast.type}`}
        role="status"
        aria-live="polite"
        aria-label={`Notification: ${toast.type}`}
        data-testid={`toast-${toast.type}`}
      >
        <span className="toast-message" id={`toast-msg-${toast.id}`}>
          {toast.message}
        </span>
        <Button
          className="toast-close"
          variant={ButtonVariant.ROUND}
          size="xs"
          aria-label="Close notification"
          handleClick={() => removeToast(toast.id)}
        >
          <FaTimes />
        </Button>
      </div>
    ));
  }, [toasts, removeToast]);
 
  const container = document.getElementById('toast-root') || document.body;
  return createPortal(
    <div className="toast-container" data-testid="toast-container">
      {renderedToasts}
    </div>,
    container
  );
};
 
export default Toast;