Retour au catalogue
Header Breadcrumb
Header de page interne avec breadcrumb, titre et description. Navigation contextuelle.
headersimple Both Responsive a11y
minimalcorporateuniversalsaasstacked
Theme
"use client";
import { motion } from "framer-motion";
import { ChevronRight, Home } from "lucide-react";
interface BreadcrumbItem {
label: string;
href?: string;
}
interface HeaderBreadcrumbProps {
title?: string;
description?: string;
breadcrumbs?: BreadcrumbItem[];
}
const ease: [number, number, number, number] = [0.16, 1, 0.3, 1];
export default function HeaderBreadcrumb({
title = "Titre de la page",
description = "",
breadcrumbs = [],
}: HeaderBreadcrumbProps) {
return (
<section className="py-12 lg:py-16 px-6" style={{ background: "var(--color-background-alt)" }}>
<div className="mx-auto max-w-5xl">
{/* Breadcrumb */}
<motion.nav
initial={{ opacity: 0, y: -8 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.4, ease }}
className="flex items-center gap-1.5 mb-6 text-sm"
aria-label="Fil d'Ariane"
>
<a
href="/"
className="flex items-center gap-1 transition-colors"
style={{ color: "var(--color-foreground-muted)", textDecoration: "none" }}
>
<Home size={14} />
<span>Accueil</span>
</a>
{breadcrumbs.map((item, i) => (
<span key={i} className="flex items-center gap-1.5">
<ChevronRight size={14} style={{ color: "var(--color-foreground-light)" }} />
{item.href && i < breadcrumbs.length - 1 ? (
<a
href={item.href}
className="transition-colors"
style={{ color: "var(--color-foreground-muted)", textDecoration: "none" }}
>
{item.label}
</a>
) : (
<span
style={{
color: i === breadcrumbs.length - 1 ? "var(--color-foreground)" : "var(--color-foreground-muted)",
fontWeight: i === breadcrumbs.length - 1 ? 500 : 400,
}}
>
{item.label}
</span>
)}
</span>
))}
</motion.nav>
{/* Title */}
<motion.h1
initial={{ opacity: 0, y: 16 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, ease, delay: 0.08 }}
className="text-3xl md:text-4xl font-bold tracking-tight"
style={{ color: "var(--color-foreground)" }}
>
{title}
</motion.h1>
{/* Description */}
{description && (
<motion.p
initial={{ opacity: 0, y: 12 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, ease, delay: 0.16 }}
className="mt-3 text-base max-w-2xl"
style={{ color: "var(--color-foreground-muted)" }}
>
{description}
</motion.p>
)}
{/* Separator */}
<motion.div
initial={{ scaleX: 0 }}
animate={{ scaleX: 1 }}
transition={{ duration: 0.5, ease, delay: 0.24 }}
className="mt-8 h-px origin-left"
style={{ background: "var(--color-border)" }}
/>
</div>
</section>
);
}