Retour au catalogue
Notification Banner
Banniere de notification en haut de page avec CTA, icone et animation de fermeture.
notificationsimple Both Responsive a11y
boldcorporatesaasecommerceuniversalstacked
Theme
"use client";
import { useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { X, ArrowRight, Megaphone } from "lucide-react";
interface NotificationBannerProps {
message?: string;
ctaLabel?: string;
ctaUrl?: string;
dismissible?: boolean;
variant?: "info" | "success" | "warning" | "accent";
}
const ease: [number, number, number, number] = [0.16, 1, 0.3, 1];
export default function NotificationBanner({
message = "Notification importante",
ctaLabel = "",
ctaUrl = "#",
dismissible = true,
variant = "accent",
}: NotificationBannerProps) {
const [visible, setVisible] = useState(true);
return (
<AnimatePresence>
{visible && (
<motion.div
initial={{ height: 0, opacity: 0 }}
animate={{ height: "auto", opacity: 1 }}
exit={{ height: 0, opacity: 0 }}
transition={{ duration: 0.3, ease }}
className="overflow-hidden"
>
<div
className="py-3 px-6"
style={{
background: variant === "accent" ? "var(--color-accent)" : "var(--color-background-alt)",
}}
>
<div className="mx-auto max-w-7xl flex items-center justify-center gap-3">
<Megaphone
size={16}
style={{
color: variant === "accent" ? "var(--color-background)" : "var(--color-accent)",
flexShrink: 0,
}}
/>
<p
className="text-sm font-medium"
style={{
color: variant === "accent" ? "var(--color-background)" : "var(--color-foreground)",
}}
>
{message}
</p>
{ctaLabel && (
<a
href={ctaUrl}
className="inline-flex items-center gap-1 text-sm font-semibold underline underline-offset-2"
style={{
color: variant === "accent" ? "var(--color-background)" : "var(--color-accent)",
}}
>
{ctaLabel}
<ArrowRight size={14} />
</a>
)}
{dismissible && (
<button
onClick={() => setVisible(false)}
className="ml-auto flex-shrink-0"
style={{
color: variant === "accent" ? "var(--color-background)" : "var(--color-foreground-muted)",
}}
>
<X size={16} />
</button>
)}
</div>
</div>
</motion.div>
)}
</AnimatePresence>
);
}