58 lines
1.5 KiB
TypeScript
58 lines
1.5 KiB
TypeScript
import * as React from 'react';
|
|
import { clsx } from 'clsx';
|
|
|
|
export interface PageHeaderProps extends Omit<React.HTMLAttributes<HTMLElement>, 'title'> {
|
|
eyebrow?: React.ReactNode;
|
|
title: React.ReactNode;
|
|
description?: React.ReactNode;
|
|
actions?: React.ReactNode;
|
|
metadata?: React.ReactNode;
|
|
compact?: boolean;
|
|
}
|
|
|
|
export function PageHeader({
|
|
eyebrow,
|
|
title,
|
|
description,
|
|
actions,
|
|
metadata,
|
|
compact,
|
|
className,
|
|
...props
|
|
}: PageHeaderProps) {
|
|
return (
|
|
<header
|
|
className={clsx(
|
|
'flex min-w-0 flex-col gap-4 border-b border-[var(--bl-border)]',
|
|
compact ? 'pb-4' : 'pb-6',
|
|
'sm:flex-row sm:items-end sm:justify-between',
|
|
className
|
|
)}
|
|
{...props}
|
|
>
|
|
<div className="min-w-0">
|
|
{eyebrow && (
|
|
<div className="mb-2 text-xs font-semibold uppercase tracking-[0.08em] text-[var(--bl-text-secondary)]">
|
|
{eyebrow}
|
|
</div>
|
|
)}
|
|
<h1
|
|
className={clsx(
|
|
'm-0 text-[var(--bl-text-primary)]',
|
|
compact ? 'text-2xl font-semibold leading-8' : 'text-3xl font-semibold leading-10'
|
|
)}
|
|
>
|
|
{title}
|
|
</h1>
|
|
{description && (
|
|
<p className="mt-2 max-w-3xl text-sm leading-6 text-[var(--bl-text-secondary)]">
|
|
{description}
|
|
</p>
|
|
)}
|
|
{metadata && <div className="mt-3 flex flex-wrap gap-2">{metadata}</div>}
|
|
</div>
|
|
{actions && <div className="flex shrink-0 flex-wrap items-center gap-2">{actions}</div>}
|
|
</header>
|
|
);
|
|
}
|