Retour au catalogue
Breadcrumb Animated
Breadcrumb avec animation slide-in sur chaque element et separateurs chevron.
breadcrumbsimple Both Responsive a11y
minimaluniversalstacked
Theme
"use client";
import { useState, useEffect } from "react";
import { ChevronRight, Home } from "lucide-react";
interface BreadcrumbItem {
label: string;
href?: string;
icon?: "home";
}
interface BreadcrumbAnimatedProps {
items?: BreadcrumbItem[];
}
const mockItems: BreadcrumbItem[] = [
{ label: "Accueil", href: "#", icon: "home" },
{ label: "Produits", href: "#" },
{ label: "Electronique", href: "#" },
{ label: "Smartphones" },
];
export default function BreadcrumbAnimated({
items = mockItems,
}: BreadcrumbAnimatedProps) {
const [visibleCount, setVisibleCount] = useState(0);
useEffect(() => {
if (visibleCount < items.length) {
const timer = setTimeout(() => {
setVisibleCount((prev) => prev + 1);
}, 120);
return () => clearTimeout(timer);
}
}, [visibleCount, items.length]);
return (
<nav
className="py-4 px-6"
style={{ background: "var(--color-background)" }}
aria-label="Fil d'Ariane"
>
<ol className="flex items-center gap-1.5 text-sm">
{items.map((item, i) => {
const isVisible = i < visibleCount;
const isLast = i === items.length - 1;
return (
<li
key={i}
className="flex items-center gap-1.5 transition-all duration-300 ease-out"
style={{
opacity: isVisible ? 1 : 0,
transform: isVisible ? "translateX(0)" : "translateX(-12px)",
transitionDelay: `${i * 80}ms`,
}}
>
{i > 0 && (
<ChevronRight
size={14}
className="shrink-0"
style={{ color: "var(--color-foreground-light)" }}
/>
)}
{isLast ? (
<span
className="font-medium"
style={{ color: "var(--color-foreground)" }}
aria-current="page"
>
{item.label}
</span>
) : (
<a
href={item.href || "#"}
className="inline-flex items-center gap-1.5 transition-colors duration-200 hover:underline underline-offset-2"
style={{ color: "var(--color-foreground-muted)" }}
>
{item.icon === "home" && <Home size={14} />}
{item.label}
</a>
)}
</li>
);
})}
</ol>
<style>{`
@keyframes breadcrumb-slide-in {
from { opacity: 0; transform: translateX(-12px); }
to { opacity: 1; transform: translateX(0); }
}
`}</style>
</nav>
);
}