content-explorer/ui/components/SiteHeader.tsx
tegwick 85ec9fa867 Add keyboard search and the empty, loading, and error states.
CONTENT-WP-0002-T05 focuses search with slash, clears it with Escape, and wraps the header on a narrow screen.

Assistant: grok
Assistant-Session: 01a1346c-fdff-7741-b1af-b7283661554b
2026-10-13 23:16:43 +02:00

34 lines
1.6 KiB
TypeScript

"use client";
import { usePathname } from "next/navigation";
import type { DataspaceNav } from "@/lib/catalog";
/**
* Sticky header shell adapted from OnCo SiteHeader.
* Copyright (c) 2026 OnCo. MIT License. See ui/NOTICE.
* The OnCo mark and command palette are not included.
* Kind links come from the snapshot registry passed in by the layout.
*/
export function SiteHeader({ dataspaces }: { dataspaces: DataspaceNav[] }) {
const path = usePathname() ?? "/";
const active = dataspaces.find((item) => path === `/${item.id}` || path.startsWith(`/${item.id}/`)) ?? dataspaces.find((item) => item.id === "systems-thinking") ?? dataspaces[0];
return (
<header className="sticky top-0 z-40 border-b border-border bg-background/80 backdrop-blur-md supports-[backdrop-filter]:bg-background/75">
<div className="mx-auto flex min-h-14 max-w-7xl flex-wrap items-center gap-x-4 gap-y-1 px-4 py-2 sm:h-14 sm:flex-nowrap sm:gap-6 sm:px-6 sm:py-0">
<a href="/" className="inline-flex h-10 shrink-0 items-center rounded-lg font-semibold tracking-tight" aria-label="Content Explorer home">
<span className="text-[15px]">Content Explorer</span>
</a>
{active ? (
<nav aria-label="Primary" className="flex min-w-0 items-center gap-4 overflow-x-auto text-sm">
<a href={`/${active.id}/`} className="shrink-0 text-foreground">{active.title}</a>
{active.kinds.map((kind) => (
<a key={kind.id} href={kind.href} className="shrink-0 text-muted hover:text-foreground">
{kind.plural}
</a>
))}
</nav>
) : null}
</div>
</header>
);
}