NRVM

Back to Discover
ReactIntermediate

Animated Toast

A minimalist notification pop-up.

Live Preview
Payment successfulYour receipt has been sent.
"use client";

import { motion, AnimatePresence } from "framer-motion";
import { useState, useEffect } from "react";
import { Check } from "lucide-react";

export function AnimatedToast() {
  const [isVisible, setIsVisible] = useState(true);

  // Auto-hide and show for preview loop
  useEffect(() => {
    const interval = setInterval(() => {
      setIsVisible((v) => !v);
    }, 3000);
    return () => clearInterval(interval);
  }, []);

  return (
    <div className="relative w-full h-full min-h-[200px] flex items-center justify-center">
      <AnimatePresence>
        {isVisible && (
          <motion.div
            initial={{ opacity: 0, y: 20, scale: 0.95 }}
            animate={{ opacity: 1, y: 0, scale: 1 }}
            exit={{ opacity: 0, y: -20, scale: 0.95 }}
            transition={{ type: "spring", stiffness: 300, damping: 25 }}
            className="flex items-center gap-3 rounded-lg border border-border bg-[#111111] px-4 py-3 shadow-lg"
          >
            <div className="flex h-6 w-6 items-center justify-center rounded-full bg-green-500/10">
              <Check className="h-4 w-4 text-green-500" />
            </div>
            <div className="flex flex-col">
              <span className="text-sm font-medium text-foreground">Payment successful</span>
              <span className="text-xs text-muted-foreground">Your receipt has been sent.</span>
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}