Alert

Dismissible contextual notification banner with status variants, action link, and smooth spring exit.

ReactTailwind CSSFramer Motion
Dependenciesframer-motion, lucide-react
npm install framer-motion lucide-react

Preview

Source Code

alert.tsx
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
"use client";

import React, { useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { Info, X } from "lucide-react";

export type AlertVariant = "info" | "success" | "warning" | "error";

export interface AlertProps {
  title?: string;
  description?: string;
  variant?: AlertVariant;
}

export function Alert({
  title = "Component copied to clipboard",
  description = "Ready to paste into your codebase.",
}: AlertProps) {
  const [isVisible, setIsVisible] = useState(true);

  if (!isVisible) return null;

  return (
    <div className="flex items-start gap-3 p-3.5 rounded-xl border bg-zinc-50 dark:bg-zinc-900 border-zinc-200 dark:border-zinc-800">
      <Info className="w-4 h-4 text-zinc-600 mt-0.5" />
      <div className="flex-1">
        <h5 className="text-xs font-semibold">{title}</h5>
        <p className="text-[11px] opacity-80 mt-0.5">{description}</p>
      </div>
      <button onClick={() => setIsVisible(false)}>
        <X className="w-3.5 h-3.5 text-zinc-400" />
      </button>
    </div>
  );
}

Usage

usage.tsx
1
2
3
4
5
<Alert
  title="Deployment Complete"
  description="All assets have been pushed to production edge nodes."
  variant="success"
/>

Props

PropTypeRequiredDefaultDescription
titlestringOptional"Component copied to clipboard"Main header of the alert.
descriptionstringOptional"Ready to paste into your codebase."Supporting descriptive text.
variant"info" | "success" | "warning" | "error"Optional"info"Color and iconography variant preset.

Types

types.ts
1
2
3
4
5
6
7
8
9
10
export type AlertVariant = "info" | "success" | "warning" | "error";

export interface AlertProps {
  title?: string;
  description?: string;
  variant?: AlertVariant;
  actionText?: string;
  onAction?: () => void;
  dismissible?: boolean;
}