# ToastNotification

A versatile notification component that displays temporary messages to users. It supports different styles (neutral, success, error), customizable icons, dismissible behavior, and auto-dismiss functionality. Toast notifications are ideal for providing feedback about user actions and system status updates.

## Aliases

- ToastNotification
- Toast
- Notification

## Props Breakdown

**Extends:** `HTMLAttributes<HTMLDivElement>` (excluding `style`)

| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `style` | `'Neutral' \| 'Error' \| 'Success'` | `'Neutral'` | No | Style of the toast notification |
| `isDismissable` | `boolean` | `true` | No | Determines if the toast notification is dismissible |
| `leadingIcon` | `ReactNode` | `undefined` | No | Icon displayed before the message content |
| `trailingIcon` | `ReactNode` | `undefined` | No | Icon displayed after the message content |
| `closeIcon` | `ReactNode` | `undefined` | No | Close button/icon for dismissible toast notifications |
| `removeToast` | `(event?: MouseEvent<HTMLButtonElement>) => void` | `undefined` | No | Click event handler for the close action |
| `duration` | `number` | `undefined` | No | Duration before the toast auto-closes (in milliseconds) |
| `className` | `string` | `undefined` | No | Additional class for styling |
| `children` | `ReactNode` | `undefined` | No | The content of the toast notification |

Plus all standard HTML div attributes (id, title, aria-*, data-*, etc.).

## Examples

### Basic Toast Notifications

```tsx
import { ToastNotification, Button } from '@delightui/components';

function BasicToastExample() {
  const [toasts, setToasts] = useState<Array<{id: number, type: string, message: string}>>([]);

  const addToast = (type: 'Neutral' | 'Success' | 'Error', message: string) => {
    const newToast = {
      id: Date.now(),
      type,
      message
    };
    setToasts(prev => [...prev, newToast]);
  };

  const removeToast = (id: number) => {
    setToasts(prev => prev.filter(toast => toast.id !== id));
  };

  return (
    <div>
      <div style={{ display: 'flex', gap: '8px', marginBottom: '20px' }}>
        <Button onClick={() => addToast('Success', 'Operation completed successfully!')}>
          Success Toast
        </Button>
        <Button onClick={() => addToast('Error', 'An error occurred while processing.')}>
          Error Toast
        </Button>
        <Button onClick={() => addToast('Neutral', 'This is a neutral notification.')}>
          Neutral Toast
        </Button>
      </div>

      <div style={{ position: 'fixed', top: '20px', right: '20px', zIndex: 1000 }}>
        {toasts.map((toast) => (
          <ToastNotification
            key={toast.id}
            style={toast.type as any}
            removeToast={() => removeToast(toast.id)}
            style={{ marginBottom: '8px' }}
          >
            {toast.message}
          </ToastNotification>
        ))}
      </div>
    </div>
  );
}
```

### Toast with Icons

```tsx
import { ToastNotification, Icon, Button } from '@delightui/components';

function ToastWithIconsExample() {
  const [toasts, setToasts] = useState<Array<{id: number, style: string, message: string, icon: string}>>([]);

  const addToast = (style: 'Neutral' | 'Success' | 'Error', message: string, icon: string) => {
    const newToast = {
      id: Date.now(),
      style,
      message,
      icon
    };
    setToasts(prev => [...prev, newToast]);
  };

  const removeToast = (id: number) => {
    setToasts(prev => prev.filter(toast => toast.id !== id));
  };

  return (
    <div>
      <div style={{ display: 'flex', gap: '8px', marginBottom: '20px' }}>
        <Button onClick={() => addToast('Success', 'File uploaded successfully!', 'CheckFilled')}>
          Upload Success
        </Button>
        <Button onClick={() => addToast('Error', 'Connection failed. Please try again.', 'ErrorOutlined')}>
          Connection Error
        </Button>
        <Button onClick={() => addToast('Neutral', 'New message received.', 'InfoFilled')}>
          New Message
        </Button>
      </div>

      <div style={{ position: 'fixed', top: '20px', right: '20px', zIndex: 1000 }}>
        {toasts.map((toast) => (
          <ToastNotification
            key={toast.id}
            style={toast.style as any}
            leadingIcon={<Icon name={toast.icon} />}
            removeToast={() => removeToast(toast.id)}
            style={{ marginBottom: '8px' }}
          >
            {toast.message}
          </ToastNotification>
        ))}
      </div>
    </div>
  );
}
```

### Auto-dismiss Toasts

```tsx
import { ToastNotification, Button } from '@delightui/components';

function AutoDismissToastExample() {
  const [toasts, setToasts] = useState<Array<{id: number, style: string, message: string, duration: number}>>([]);

  const addToast = (style: 'Neutral' | 'Success' | 'Error', message: string, duration: number) => {
    const newToast = {
      id: Date.now(),
      style,
      message,
      duration
    };
    setToasts(prev => [...prev, newToast]);

    // Auto-remove after duration
    setTimeout(() => {
      removeToast(newToast.id);
    }, duration);
  };

  const removeToast = (id: number) => {
    setToasts(prev => prev.filter(toast => toast.id !== id));
  };

  return (
    <div>
      <div style={{ display: 'flex', gap: '8px', marginBottom: '20px' }}>
        <Button onClick={() => addToast('Success', 'Quick success message!', 2000)}>
          2 Second Toast
        </Button>
        <Button onClick={() => addToast('Neutral', 'Medium duration message.', 5000)}>
          5 Second Toast
        </Button>
        <Button onClick={() => addToast('Error', 'Important error that stays longer.', 10000)}>
          10 Second Toast
        </Button>
      </div>

      <div style={{ position: 'fixed', top: '20px', right: '20px', zIndex: 1000 }}>
        {toasts.map((toast) => (
          <ToastNotification
            key={toast.id}
            style={toast.style as any}
            duration={toast.duration}
            removeToast={() => removeToast(toast.id)}
            style={{ marginBottom: '8px' }}
          >
            {toast.message}
          </ToastNotification>
        ))}
      </div>
    </div>
  );
}
```

### Non-dismissible Toasts

```tsx
import { ToastNotification, Button } from '@delightui/components';

function NonDismissibleToastExample() {
  const [toasts, setToasts] = useState<Array<{id: number, message: string, dismissible: boolean}>>([]);

  const addToast = (message: string, dismissible: boolean) => {
    const newToast = {
      id: Date.now(),
      message,
      dismissible
    };
    setToasts(prev => [...prev, newToast]);
  };

  const removeToast = (id: number) => {
    setToasts(prev => prev.filter(toast => toast.id !== id));
  };

  const clearAll = () => {
    setToasts([]);
  };

  return (
    <div>
      <div style={{ display: 'flex', gap: '8px', marginBottom: '20px' }}>
        <Button onClick={() => addToast('This toast can be dismissed manually.', true)}>
          Dismissible Toast
        </Button>
        <Button onClick={() => addToast('This toast cannot be dismissed by user.', false)}>
          Non-dismissible Toast
        </Button>
        <Button onClick={clearAll} type="Outlined">
          Clear All
        </Button>
      </div>

      <div style={{ position: 'fixed', top: '20px', right: '20px', zIndex: 1000 }}>
        {toasts.map((toast) => (
          <ToastNotification
            key={toast.id}
            style="Neutral"
            isDismissable={toast.dismissible}
            removeToast={toast.dismissible ? () => removeToast(toast.id) : undefined}
            style={{ marginBottom: '8px' }}
          >
            {toast.message}
          </ToastNotification>
        ))}
      </div>
    </div>
  );
}
```

### Form Validation Toasts

```tsx
import { Form, FormField, Input, Button, ToastNotification, Icon } from '@delightui/components';

function FormValidationToastExample() {
  const [toasts, setToasts] = useState<Array<{id: number, type: string, message: string}>>([]);

  const addToast = (type: 'Success' | 'Error', message: string) => {
    const newToast = {
      id: Date.now(),
      type,
      message
    };
    setToasts(prev => [...prev, newToast]);

    // Auto-remove after 5 seconds
    setTimeout(() => {
      removeToast(newToast.id);
    }, 5000);
  };

  const removeToast = (id: number) => {
    setToasts(prev => prev.filter(toast => toast.id !== id));
  };

  const handleSubmit = (data: any) => {
    // Simulate form validation
    if (!data.email || !data.password) {
      addToast('Error', 'Please fill in all required fields.');
      return;
    }

    if (data.password.length < 8) {
      addToast('Error', 'Password must be at least 8 characters long.');
      return;
    }

    // Simulate successful submission
    addToast('Success', 'Account created successfully! Welcome aboard.');
  };

  return (
    <div>
      <Form onSubmit={handleSubmit}>
        <FormField name="email" label="Email" required>
          <Input inputType="Email" placeholder="Enter your email" />
        </FormField>

        <FormField name="password" label="Password" required>
          <Input inputType="Password" placeholder="Enter your password" />
        </FormField>

        <Button type="submit">
          Create Account
        </Button>
      </Form>

      {/* Toast Container */}
      <div style={{ position: 'fixed', top: '20px', right: '20px', zIndex: 1000 }}>
        {toasts.map((toast) => (
          <ToastNotification
            key={toast.id}
            style={toast.type as any}
            leadingIcon={
              <Icon name={toast.type === 'Success' ? 'CheckFilled' : 'ErrorOutlined'} />
            }
            removeToast={() => removeToast(toast.id)}
            style={{ marginBottom: '8px' }}
          >
            {toast.message}
          </ToastNotification>
        ))}
      </div>
    </div>
  );
}
```

### Action Feedback Toasts

```tsx
import { ToastNotification, Button, Icon } from '@delightui/components';

function ActionFeedbackToastExample() {
  const [toasts, setToasts] = useState<Array<{id: number, type: string, message: string, action?: string}>>([]);

  const addToast = (type: 'Success' | 'Error' | 'Neutral', message: string, action?: string) => {
    const newToast = {
      id: Date.now(),
      type,
      message,
      action
    };
    setToasts(prev => [...prev, newToast]);

    // Auto-remove after 6 seconds
    setTimeout(() => {
      removeToast(newToast.id);
    }, 6000);
  };

  const removeToast = (id: number) => {
    setToasts(prev => prev.filter(toast => toast.id !== id));
  };

  const simulateAction = (actionType: string) => {
    switch (actionType) {
      case 'save':
        addToast('Success', 'Document saved successfully!');
        break;
      case 'delete':
        addToast('Success', 'Item deleted successfully!', 'undo');
        break;
      case 'copy':
        addToast('Neutral', 'Copied to clipboard!');
        break;
      case 'error':
        addToast('Error', 'Failed to save. Please try again.');
        break;
      default:
        break;
    }
  };

  const handleUndo = () => {
    addToast('Neutral', 'Action undone successfully!');
  };

  return (
    <div>
      <div style={{ display: 'flex', gap: '8px', marginBottom: '20px', flexWrap: 'wrap' }}>
        <Button onClick={() => simulateAction('save')}>
          Save Document
        </Button>
        <Button onClick={() => simulateAction('delete')} style="Destructive">
          Delete Item
        </Button>
        <Button onClick={() => simulateAction('copy')} type="Outlined">
          Copy Text
        </Button>
        <Button onClick={() => simulateAction('error')} style="Destructive" type="Outlined">
          Simulate Error
        </Button>
      </div>

      {/* Toast Container */}
      <div style={{ position: 'fixed', top: '20px', right: '20px', zIndex: 1000 }}>
        {toasts.map((toast) => (
          <ToastNotification
            key={toast.id}
            style={toast.type as any}
            leadingIcon={
              <Icon 
                name={
                  toast.type === 'Success' ? 'CheckFilled' : 
                  toast.type === 'Error' ? 'ErrorOutlined' : 
                  'InfoFilled'
                } 
              />
            }
            trailingIcon={
              toast.action === 'undo' ? (
                <Button size="Small" type="Ghost" onClick={handleUndo}>
                  Undo
                </Button>
              ) : undefined
            }
            removeToast={() => removeToast(toast.id)}
            style={{ marginBottom: '8px', minWidth: '300px' }}
          >
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <span>{toast.message}</span>
            </div>
          </ToastNotification>
        ))}
      </div>
    </div>
  );
}
```

### Progress and Loading Toasts

```tsx
import { ToastNotification, Spinner, Button, Icon } from '@delightui/components';

function ProgressToastExample() {
  const [toasts, setToasts] = useState<Array<{id: number, type: string, message: string, loading?: boolean}>>([]);

  const addProgressToast = async (operation: string) => {
    const toastId = Date.now();
    
    // Add loading toast
    setToasts(prev => [...prev, {
      id: toastId,
      type: 'Neutral',
      message: `${operation} in progress...`,
      loading: true
    }]);

    // Simulate operation
    await new Promise(resolve => setTimeout(resolve, 3000));

    // Update to success toast
    setToasts(prev => prev.map(toast => 
      toast.id === toastId 
        ? { ...toast, message: `${operation} completed successfully!`, loading: false, type: 'Success' }
        : toast
    ));

    // Auto-remove after 3 seconds
    setTimeout(() => {
      removeToast(toastId);
    }, 3000);
  };

  const removeToast = (id: number) => {
    setToasts(prev => prev.filter(toast => toast.id !== id));
  };

  return (
    <div>
      <div style={{ display: 'flex', gap: '8px', marginBottom: '20px' }}>
        <Button onClick={() => addProgressToast('File upload')}>
          Upload File
        </Button>
        <Button onClick={() => addProgressToast('Data processing')}>
          Process Data
        </Button>
        <Button onClick={() => addProgressToast('Backup creation')}>
          Create Backup
        </Button>
      </div>

      {/* Toast Container */}
      <div style={{ position: 'fixed', top: '20px', right: '20px', zIndex: 1000 }}>
        {toasts.map((toast) => (
          <ToastNotification
            key={toast.id}
            style={toast.type as any}
            leadingIcon={
              toast.loading ? 
                <Spinner /> : 
                <Icon name={toast.type === 'Success' ? 'CheckFilled' : 'InfoFilled'} />
            }
            isDismissable={!toast.loading}
            removeToast={!toast.loading ? () => removeToast(toast.id) : undefined}
            style={{ marginBottom: '8px' }}
          >
            {toast.message}
          </ToastNotification>
        ))}
      </div>
    </div>
  );
}
```

### Toast Position Variations

```tsx
import { ToastNotification, Button } from '@delightui/components';

function ToastPositionExample() {
  const [toasts, setToasts] = useState<Array<{id: number, message: string, position: string}>>([]);

  const addToast = (position: string) => {
    const newToast = {
      id: Date.now(),
      message: `Toast from ${position}`,
      position
    };
    setToasts(prev => [...prev, newToast]);

    // Auto-remove after 4 seconds
    setTimeout(() => {
      removeToast(newToast.id);
    }, 4000);
  };

  const removeToast = (id: number) => {
    setToasts(prev => prev.filter(toast => toast.id !== id));
  };

  const getPositionStyles = (position: string) => {
    const baseStyles = { position: 'fixed', zIndex: 1000 };
    
    switch (position) {
      case 'top-right':
        return { ...baseStyles, top: '20px', right: '20px' };
      case 'top-left':
        return { ...baseStyles, top: '20px', left: '20px' };
      case 'bottom-right':
        return { ...baseStyles, bottom: '20px', right: '20px' };
      case 'bottom-left':
        return { ...baseStyles, bottom: '20px', left: '20px' };
      case 'top-center':
        return { ...baseStyles, top: '20px', left: '50%', transform: 'translateX(-50%)' };
      case 'bottom-center':
        return { ...baseStyles, bottom: '20px', left: '50%', transform: 'translateX(-50%)' };
      default:
        return { ...baseStyles, top: '20px', right: '20px' };
    }
  };

  return (
    <div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '8px', marginBottom: '20px' }}>
        <Button onClick={() => addToast('top-left')} size="Small">
          Top Left
        </Button>
        <Button onClick={() => addToast('top-center')} size="Small">
          Top Center
        </Button>
        <Button onClick={() => addToast('top-right')} size="Small">
          Top Right
        </Button>
        <Button onClick={() => addToast('bottom-left')} size="Small">
          Bottom Left
        </Button>
        <Button onClick={() => addToast('bottom-center')} size="Small">
          Bottom Center
        </Button>
        <Button onClick={() => addToast('bottom-right')} size="Small">
          Bottom Right
        </Button>
      </div>

      {/* Render toasts by position */}
      {['top-left', 'top-center', 'top-right', 'bottom-left', 'bottom-center', 'bottom-right'].map(position => {
        const positionToasts = toasts.filter(toast => toast.position === position);
        
        return positionToasts.length > 0 ? (
          <div key={position} style={getPositionStyles(position)}>
            {positionToasts.map((toast) => (
              <ToastNotification
                key={toast.id}
                style="Neutral"
                removeToast={() => removeToast(toast.id)}
                style={{ marginBottom: '8px' }}
              >
                {toast.message}
              </ToastNotification>
            ))}
          </div>
        ) : null;
      })}
    </div>
  );
}
```

### Custom Styled Toasts

```tsx
import { ToastNotification, Button, Icon } from '@delightui/components';

function CustomStyledToastExample() {
  const [toasts, setToasts] = useState<Array<{id: number, type: string, message: string, custom?: boolean}>>([]);

  const addToast = (type: 'Success' | 'Error' | 'Neutral', message: string, custom = false) => {
    const newToast = {
      id: Date.now(),
      type,
      message,
      custom
    };
    setToasts(prev => [...prev, newToast]);

    setTimeout(() => {
      removeToast(newToast.id);
    }, 5000);
  };

  const removeToast = (id: number) => {
    setToasts(prev => prev.filter(toast => toast.id !== id));
  };

  return (
    <div>
      <div style={{ display: 'flex', gap: '8px', marginBottom: '20px' }}>
        <Button onClick={() => addToast('Success', 'Standard success message')}>
          Standard Toast
        </Button>
        <Button onClick={() => addToast('Success', 'Custom styled success message', true)}>
          Custom Toast
        </Button>
      </div>

      <div style={{ position: 'fixed', top: '20px', right: '20px', zIndex: 1000 }}>
        {toasts.map((toast) => (
          <ToastNotification
            key={toast.id}
            style={toast.type as any}
            leadingIcon={<Icon name="CheckFilled" />}
            removeToast={() => removeToast(toast.id)}
            className={toast.custom ? 'custom-toast' : ''}
            style={{ 
              marginBottom: '8px',
              ...(toast.custom && {
                background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
                color: 'white',
                borderRadius: '12px',
                boxShadow: '0 8px 25px rgba(0,0,0,0.2)'
              })
            }}
          >
            {toast.message}
          </ToastNotification>
        ))}
      </div>
    </div>
  );
}
```