DEV Community

Cover image for Daily UI - Day 11: Flash Message
Johnny Santamaria
Johnny Santamaria

Posted on

Daily UI - Day 11: Flash Message

The Challenge

Today's challenge was to design a Flash Message component. Flash messages are brief notifications that appear temporarily to provide feedback to users about their actions or system status. They're crucial for maintaining a good user experience by keeping users informed about the results of their interactions.

My Approach

I decided to create a reusable Flash Message component using React and Tailwind CSS. The component needed to:

  1. Support different message types (success, error, warning, info)

  2. Auto-dismiss after a configurable duration

  3. Allow manual dismissal

  4. Be visually distinct based on the message type

  5. Include appropriate icons for each type

  6. Animate in and out smoothly

--

The implementation

First, let's create the Flash Message component using React, Tailwind CSS, and Lucide icons for a clean, modern look:

import React, { useEffect } from 'react';
import { X, CheckCircle, AlertCircle, AlertTriangle, Info } from 'lucide-react';

/**
 * FlashMessage Component
 * Displays a temporary notification message that automatically dismisses after a specified duration.
 * 
 * @param {Object} props
 * @param {string} props.message - The message to display in the flash notification
 * @param {('info'|'success'|'error'|'warning')} [props.type='info'] - The type of message which determines its styling
 * @param {number} [props.duration=5000] - Duration in milliseconds before the message auto-dismisses
 * @param {Function} props.onDismiss - Callback function to execute when the message is dismissed
 */
const FlashMessage = ({ 
  message, 
  type = 'info', 
  duration = 5000, 
  onDismiss 
}) => {
  // Set up auto-dismiss timer
  useEffect(() => {
    // Only set timer if duration is provided
    if (duration !== null) {
      const timer = setTimeout(() => {
        onDismiss();
      }, duration);

      // Cleanup timer on component unmount or when duration/onDismiss changes
      return () => clearTimeout(timer);
    }
  }, [duration, onDismiss]);

  /**
   * Returns the appropriate icon component based on message type
   * @returns {React.ReactElement} Icon component
   */
  const getIcon = () => {
    switch (type) {
      case 'success':
        return <CheckCircle className="w-5 h-5" />;
      case 'error':
        return <AlertCircle className="w-5 h-5" />;
      case 'warning':
        return <AlertTriangle className="w-5 h-5" />;
      default:
        return <Info className="w-5 h-5" />;
    }
  };

  /**
   * Returns the appropriate Tailwind CSS classes based on message type
   * @returns {string} Combined CSS classes
   */
  const getStyles = () => {
    // Base styles applied to all message types
    const baseStyles = "fixed top-4 right-4 flex items-center gap-2 p-4 rounded-lg shadow-lg";

    // Add type-specific styling
    switch (type) {
      case 'success':
        return `${baseStyles} bg-green-100 text-green-800 border border-green-200`;
      case 'error':
        return `${baseStyles} bg-red-100 text-red-800 border border-red-200`;
      case 'warning':
        return `${baseStyles} bg-yellow-100 text-yellow-800 border border-yellow-200`;
      default: // info
        return `${baseStyles} bg-blue-100 text-blue-800 border border-blue-200`;
    }
  };

  // Render the flash message with appropriate styling and icon
  return (
    <div className={getStyles()}>
      {getIcon()}
      <span className="text-sm font-medium">{message}</span>
      {/* Dismiss button */}
      <button
        onClick={onDismiss}
        className="ml-2 p-1 hover:bg-black/5 rounded-full transition-colors"
      >
        <X className="w-4 h-4" />
      </button>
    </div>
  );
};

export default FlashMessage;

Enter fullscreen mode Exit fullscreen mode

To demonstrate the Flash Message component in action, here's a simple demo page:


import React, { useState } from 'react';
import FlashMessage from './FlashMessage';

/**
 * Demo Component
 * Demonstrates the usage of the FlashMessage component with different message types.
 * Includes buttons to trigger different types of flash messages.
 */
const Demo = () => {
  // State to manage the currently displayed flash message
  const [flash, setFlash] = useState(null);

  /**
   * Shows a flash message of the specified type
   * @param {('success'|'error'|'warning'|'info')} type - The type of flash message to display
   */
  const showFlash = (type) => {
    setFlash({
      type,
      message: `This is a ${type} message!`,
    });
  };

  return (
    <div className="p-8">
      {/* Container for flash message trigger buttons */}
      <div className="space-x-4">
        {/* Success message button */}
        <button
          onClick={() => showFlash('success')}
          className="px-4 py-2 bg-green-500 text-white rounded-lg"
        >
          Show Success
        </button>

        {/* Error message button */}
        <button
          onClick={() => showFlash('error')}
          className="px-4 py-2 bg-red-500 text-white rounded-lg"
        >
          Show Error
        </button>

        {/* Warning message button */}
        <button
          onClick={() => showFlash('warning')}
          className="px-4 py-2 bg-yellow-500 text-white rounded-lg"
        >
          Show Warning
        </button>

        {/* Info message button */}
        <button
          onClick={() => showFlash('info')}
          className="px-4 py-2 bg-blue-500 text-white rounded-lg"
        >
          Show Info
        </button>
      </div>

      {/* Render FlashMessage component when flash state is set */}
      {flash && (
        <FlashMessage
          type={flash.type}
          message={flash.message}
          onDismiss={() => setFlash(null)} // Reset flash state to remove message
        />
      )}
    </div>
  );
};

export default Demo;


Enter fullscreen mode Exit fullscreen mode

Daily UI Day 11_page 1

Daily UI Day 11_page 2

Daily UI Day 11_page 3

Daily UI Day 11_page 4

Daily UI Day 11_page 5

--

Key Features

  1. Type-based Styling: Each message type has its own color scheme and icon for clear visual distinction

  2. Auto-dismiss: Messages automatically disappear after 5 seconds (configurable)

  3. Manual Dismiss: Users can click the X button to dismiss messages early

  4. Responsive Design: Works well on all screen sizes

  5. Accessibility: Uses semantic HTML and provides clear visual feedback

  6. Smooth Animations: Transitions smoothly when appearing and disappearing

Next Steps

  1. Add support for stacking multiple messages
    Implement more sophisticated animations

  2. Add support for custom icons

  3. Create a context-based system for showing messages from anywhere in the app

  4. Add support for actions within the message (e.g., Undo button)

Conclusion

Flash Messages are crucial to modern web applications, providing immediate feedback to users about their actions. This implementation provides a solid foundation that can be easily extended and customized for different use cases.

--

This is Day 10 of the Daily UI Challenge, 10 percent of the challenge completed! Check back tomorrow for the next challenge!

Top comments (0)