// components/PageHeader.tsx // Page-level heading strip. Used on top of every screen — title + // short subtitle, with an optional right-aligned action. import { ReactNode } from "react"; interface PageHeaderProps { eyebrow?: string; title: ReactNode; subtitle?: ReactNode; action?: ReactNode; } export default function PageHeader({ eyebrow, title, subtitle, action }: PageHeaderProps) { // Subtitle is often a fragment of multiple children. Flatten // to a single array (Children.toArray on its own does NOT flatten // nested fragments — that bites the common // `<>......` pattern). Drop empty // entries, and lay them out as a flex row with separator dots so // they don't render flush against each other. const flatten = (node: ReactNode): ReactNode[] => { if (node === null || node === undefined || node === false) return []; if (Array.isArray(node)) { return node.flatMap((n) => flatten(n as ReactNode)); } return [node]; }; const items = flatten(subtitle); let subtitleNode: ReactNode = null; if (items.length === 0) { subtitleNode = null; } else if (items.length === 1) { subtitleNode = {items[0]}; } else { subtitleNode = ( {items.map((child, i) => ( {i > 0 ? : null} {child} ))} ); } return (
{eyebrow ? (

{eyebrow}

) : null}

{title}

{subtitleNode ? (
{subtitleNode}
) : null}
{action ?
{action}
: null}
); }