Retour au catalogue

Banner Gradient

Banniere avec fond degrade anime et bouton de fermeture.

bannerssimple Both Responsive a11y
minimaluniversalstacked
Theme
"use client";

import { useState } from "react";
import { X, ArrowRight, Sparkles } from "lucide-react";

interface BannerGradientProps {
  text?: string;
  linkLabel?: string;
  linkUrl?: string;
  dismissible?: boolean;
}

export default function BannerGradient({
  text = "Decouvrez notre nouvelle offre de lancement avec 30% de reduction.",
  linkLabel = "En profiter",
  linkUrl = "#",
  dismissible = true,
}: BannerGradientProps) {
  const [visible, setVisible] = useState(true);

  if (!visible) return null;

  return (
    <div
      className="relative overflow-hidden transition-all duration-300"
      style={{
        animation: "banner-gradient-in 0.4s ease-out",
      }}
    >
      {/* Animated gradient background */}
      <div
        className="absolute inset-0"
        style={{
          background: "linear-gradient(135deg, var(--color-accent), var(--color-accent-hover), var(--color-accent))",
          backgroundSize: "200% 200%",
          animation: "banner-gradient-shift 6s ease-in-out infinite",
        }}
      />

      {/* Subtle grain overlay */}
      <div
        className="absolute inset-0 opacity-10"
        style={{
          backgroundImage: "radial-gradient(circle at 20% 50%, rgba(255,255,255,0.15) 0%, transparent 50%), radial-gradient(circle at 80% 50%, rgba(255,255,255,0.1) 0%, transparent 50%)",
        }}
      />

      <div
        className="relative flex items-center justify-center gap-3 px-4 py-3"
        style={{
          maxWidth: "var(--container-max-width)",
          marginLeft: "auto",
          marginRight: "auto",
        }}
      >
        <Sparkles size={14} style={{ color: "var(--color-background)" }} />
        <p
          className="text-xs sm:text-sm font-medium"
          style={{ color: "var(--color-background)" }}
        >
          {text}
          {linkLabel && (
            <a
              href={linkUrl}
              className="inline-flex items-center gap-1 ml-2 font-bold underline underline-offset-2 transition-opacity duration-200 hover:opacity-80"
              style={{ color: "var(--color-background)" }}
            >
              {linkLabel}
              <ArrowRight className="h-3 w-3" />
            </a>
          )}
        </p>

        {dismissible && (
          <button
            onClick={() => setVisible(false)}
            className="absolute right-4 w-6 h-6 flex items-center justify-center cursor-pointer rounded-full transition-all duration-200 hover:scale-110"
            style={{
              color: "var(--color-background)",
              background: "rgba(255,255,255,0.15)",
            }}
            aria-label="Fermer"
          >
            <X className="h-3.5 w-3.5" />
          </button>
        )}
      </div>

      <style>{`
        @keyframes banner-gradient-shift {
          0%, 100% { background-position: 0% 50%; }
          50%      { background-position: 100% 50%; }
        }
        @keyframes banner-gradient-in {
          from { opacity: 0; transform: translateY(-100%); }
          to   { opacity: 1; transform: translateY(0); }
        }
      `}</style>
    </div>
  );
}

Avis