-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPatternHeader.tsx
More file actions
72 lines (67 loc) · 2.54 KB
/
Copy pathPatternHeader.tsx
File metadata and controls
72 lines (67 loc) · 2.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// ---------------------------------------------------------------------------
// PatternHeader
// ---------------------------------------------------------------------------
// Satellite-page header for an individual pattern. Server component.
//
// Emits the satellite page's single <h1> (the pattern name). The layer
// eyebrow is a non-heading styled span — DO NOT promote it to a heading
// (Lighthouse a11y enforces one <h1> per page).
//
// Renders alternative names inline as a comma-separated synonym list, since
// these are how readers find the pattern under names from other sources.
import { Link } from "next-view-transitions";
import type { LayerId, Pattern } from "@/data/agentic-design-patterns/types";
import { LAYERS } from "@/data/agentic-design-patterns/layers";
import { formatDate } from "@/lib/formatting";
interface PatternHeaderProps {
pattern: Pattern;
}
function getLayerLabel(layerId: LayerId): string {
const layer = LAYERS.find((l) => l.id === layerId);
if (!layer) return layerId;
return `Layer ${layer.number}: ${layer.title}`;
}
export function PatternHeader({ pattern }: PatternHeaderProps) {
const layerLabel = getLayerLabel(pattern.layerId);
const altNames = pattern.alternativeNames ?? [];
return (
<header className="flex flex-col gap-3">
{/* Eyebrow: layer attribution. Styled span (NOT a heading). */}
<span
className="font-mono text-xs font-semibold uppercase tracking-[0.1em] text-text-tertiary"
>
{layerLabel}
</span>
<h1 className="font-mono text-page-h1 font-semibold tracking-tight text-text-primary [text-wrap:balance]">
{pattern.name}
</h1>
{altNames.length > 0 && (
<p className="text-sm text-text-tertiary">
<span className="font-mono uppercase tracking-[0.05em]">Also known as:</span>{" "}
<span className="italic">{altNames.join(", ")}</span>
</p>
)}
{pattern.oneLineSummary && (
<p className="max-w-prose text-body leading-relaxed text-text-secondary [text-wrap:pretty]">
{pattern.oneLineSummary}
</p>
)}
<time
dateTime={pattern.dateModified}
className="text-sm tracking-[0.03em] text-text-tertiary"
>
Last edited {formatDate(pattern.dateModified)}
</time>
<p className="text-xs text-text-tertiary">
by{" "}
<Link
href="/about"
rel="author"
className="hover:text-accent transition-colors"
>
Julian (detached-node)
</Link>
</p>
</header>
);
}