Skip to content

LoadingOverlay Component

Overview

The LoadingOverlay component provides a visually appealing loading indicator that appears when data is being fetched or processed. It works in conjunction with the LoadingContext to display a loading state across the application.

Implementation

import { motion, AnimatePresence } from 'framer-motion';
import { useLoading } from './LoadingContext';
import { useEffect, useState } from 'react';

type LoadingOverlayProps = {
  isInitialLoad?: boolean;
};

// Keep track of mounted instances to prevent multiple overlays
let mountedInstances = 0;

export const LoadingOverlay = ({ isInitialLoad = false }: LoadingOverlayProps) => {
  const { isLoading } from useLoading();
  const [shouldRender, setShouldRender] = useState(false);

  useEffect(() => {
    mountedInstances++;
    setShouldRender(mountedInstances === 1);

    return () => {
      mountedInstances--;
    };
  }, []);

  if (!shouldRender) return null;

  return (
    <AnimatePresence mode="wait">
      {(isLoading && !isInitialLoad) && (
        // Animation and rendering code
      )}
    </AnimatePresence>
  );
};

Props

Prop Type Default Description
isInitialLoad boolean false When set to true, prevents the overlay from displaying during initial application load

Features

  1. Singleton Pattern: The component implements a singleton pattern to ensure only one instance of the loading overlay is rendered at a time, even if multiple components include it.

  2. Animated Dots: Uses Framer Motion to create an animated loading indicator with three dots that pulse sequentially.

  3. Conditional Rendering: Only renders when the application is in a loading state (as determined by the LoadingContext).

  4. Initial Load Handling: Can be configured to not display during initial application load with the isInitialLoad prop.

Usage

import { LoadingOverlay } from '@/components/LoadingOverlay';

const AppLayout = () => {
  return (
    <div className="app-container">
      {/* App content */}
      <LoadingOverlay />
    </div>
  );
};

For initial loading screens:

import { LoadingOverlay } from '@/components/LoadingOverlay';

const AppLayout = () => {
  return (
    <div className="app-container">
      {/* App content */}
      <LoadingOverlay isInitialLoad={true} />
    </div>
  );
};

Integration with LoadingContext

The LoadingOverlay component relies on the LoadingContext for its state management. When the loading state is set to true in the context, the overlay automatically appears (unless isInitialLoad is true).

This creates a seamless loading experience where developers only need to modify the loading state through the context API, and the UI updates accordingly.