Retour au catalogue
Banner Floating
Banniere flottante en bas de page avec animation slide-up et bouton de fermeture.
bannerssimple Both Responsive a11y
minimaluniversalstacked
Theme
"use client";
import { useState } from "react";
import { X, ArrowRight, Bell } from "lucide-react";
interface BannerFloatingProps {
text?: string;
linkLabel?: string;
linkUrl?: string;
dismissible?: boolean;
}
export default function BannerFloating({
text = "Mise a jour importante : de nouvelles fonctionnalites sont disponibles.",
linkLabel = "Decouvrir",
linkUrl = "#",
dismissible = true,
}: BannerFloatingProps) {
const [visible, setVisible] = useState(true);
if (!visible) return null;
return (
<div className="fixed bottom-6 left-1/2 z-50 w-[calc(100%-3rem)] max-w-xl"
style={{
transform: "translateX(-50%)",
animation: "banner-float-in 0.5s cubic-bezier(0.16,1,0.3,1)",
}}
>
<div
className="flex items-center gap-3 px-5 py-3.5 rounded-2xl shadow-2xl"
style={{
background: "var(--color-background-card)",
border: "1px solid var(--color-border)",
backdropFilter: "blur(12px)",
}}
>
<div
className="w-9 h-9 rounded-xl flex items-center justify-center shrink-0"
style={{ background: "var(--color-accent-subtle)" }}
>
<Bell size={16} style={{ color: "var(--color-accent)" }} />
</div>
<div className="flex-1 min-w-0">
<p
className="text-sm font-medium leading-snug"
style={{ color: "var(--color-foreground)" }}
>
{text}
</p>
</div>
{linkLabel && (
<a
href={linkUrl}
className="flex items-center gap-1 text-sm font-semibold whitespace-nowrap shrink-0 transition-opacity duration-200 hover:opacity-80"
style={{ color: "var(--color-accent)" }}
>
{linkLabel}
<ArrowRight size={14} />
</a>
)}
{dismissible && (
<button
onClick={() => setVisible(false)}
className="p-1.5 rounded-lg cursor-pointer shrink-0 transition-colors duration-150"
style={{ color: "var(--color-foreground-light)" }}
aria-label="Fermer"
>
<X size={16} />
</button>
)}
</div>
<style>{`
@keyframes banner-float-in {
from {
opacity: 0;
transform: translateX(-50%) translateY(100%);
}
to {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
}
`}</style>
</div>
);
}