Skip to content
File

Blob: src/sites/header.tsx

typescript60 lines
1import { Pilcrow } from "lucide-react";
2import { readSitesHeaderRenderState } from "./react-render-context";
3import { SiteIconMark } from "./icons";
4 
5function WorkspaceMark({ icon }: { icon: string | null }) {
6 if (icon) {
7 return (
8 <SiteIconMark
9 icon={icon}
10 imageClassName="site-workspace-mark-img block h-5 w-5"
11 glyphClassName="site-workspace-mark-glyph text-base leading-none"
12 imageSize={20}
13 />
14 );
15 }
16 
17 return (
18 <Pilcrow
19 className="site-workspace-mark-pilcrow h-5 w-5 shrink-0 text-accent-400"
20 strokeWidth={2}
21 aria-hidden="true"
22 />
23 );
24}
25 
26function WorkspaceIdentity({ workspaceName, workspaceIcon }: { workspaceName: string; workspaceIcon: string | null }) {
27 return (
28 <>
29 <WorkspaceMark icon={workspaceIcon} />
30 <span className="site-workspace-name font-display text-sm font-semibold tracking-tight">{workspaceName}</span>
31 </>
32 );
33}
34 
35export function SiteHeader() {
36 const header = readSitesHeaderRenderState();
37 if (!header) return null;
38 
39 const { workspaceName, workspaceIcon, homeHref, currentIsHome } = header;
40 const identity = <WorkspaceIdentity workspaceName={workspaceName} workspaceIcon={workspaceIcon} />;
41 
42 return (
43 <header className="site-header sticky top-0 z-50 w-full border-b border-zinc-800/60 bg-zinc-900/95 px-4 backdrop-blur-sm sm:px-8">
44 <div className="site-header-stage mx-auto flex h-14 w-full max-w-3xl items-center">
45 {currentIsHome ? (
46 <div className="flex items-center gap-2 text-zinc-200">{identity}</div>
47 ) : (
48 <a
49 href={homeHref}
50 className="flex items-center gap-2 rounded-md text-zinc-300 transition-colors hover:text-zinc-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-500/50 focus-visible:ring-offset-2 focus-visible:ring-offset-canvas"
51 aria-label="Workspace home"
52 >
53 {identity}
54 </a>
55 )}
56 </div>
57 </header>
58 );
59}