48 lines
1.5 KiB
TypeScript
48 lines
1.5 KiB
TypeScript
"use client";
|
|
|
|
import { ReactNode } from "react";
|
|
import { ChevronRight } from "lucide-react";
|
|
|
|
export type Crumb = { label: string; href?: string };
|
|
|
|
type PageHeadProps = {
|
|
crumbs?: Crumb[];
|
|
title: ReactNode;
|
|
sub?: ReactNode;
|
|
/**
|
|
* Right-aligned action area. Design-system rule:
|
|
* priority `secondary` → `secondary` → `primary`, max 3 buttons.
|
|
* Pass <button class="v5-btn …"> nodes (or shadcn Buttons that visually match).
|
|
*/
|
|
actions?: ReactNode;
|
|
className?: string;
|
|
};
|
|
|
|
export function PageHead({ crumbs, title, sub, actions, className = "" }: PageHeadProps) {
|
|
return (
|
|
<div className={`v5-page-head ${className}`}>
|
|
<div className="v5-page-head-l">
|
|
{crumbs && crumbs.length > 0 && (
|
|
<div className="v5-crumbs">
|
|
{crumbs.map((c, i) => (
|
|
<span key={i} style={{ display: "inline-flex", alignItems: "center", gap: ".35rem" }}>
|
|
{i > 0 && <ChevronRight size={10} className="sep" />}
|
|
{c.href ? (
|
|
<a href={c.href} style={{ color: "inherit", textDecoration: "none" }}>
|
|
{c.label}
|
|
</a>
|
|
) : (
|
|
<span>{c.label}</span>
|
|
)}
|
|
</span>
|
|
))}
|
|
</div>
|
|
)}
|
|
<div className="v5-page-title">{title}</div>
|
|
{sub && <div className="v5-page-sub">{sub}</div>}
|
|
</div>
|
|
{actions && <div className="v5-page-head-r">{actions}</div>}
|
|
</div>
|
|
);
|
|
}
|