const { useState } = React;
const SpecHeader = ({ spec, navLinks, activeNav, onNavChange, functionalities }) => {
const [expanded, setExpanded] = useState(false);
const totalReq = functionalities.reduce((sum, func) => sum + func.requirements.filter(r => r.level === "required").length, 0);
const totalRec = functionalities.reduce((sum, func) => sum + func.requirements.filter(r => r.level === "recommended").length, 0);
const totalAll = totalReq + totalRec || 1;
const formatDate = (dateString) => {
if (!dateString) return "";
return new Date(dateString).toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" });
};
const PersonList = ({ people }) => (
{people.map((person, index) => (
{person.identifier ? (
{person.name}
) : (
{person.name}
)}
{person.affiliation && (
{" "}·{" "}
{person.affiliation.name}
)}
{index < people.length - 1 && ·}
))}
);
return (
{spec.identifier || spec.namespace || spec.bbKey || ""}
{spec.bbName ? spec.bbName.slice(0, 1).toUpperCase() : "S"}
{spec.name || "Specification Viewer"}
{spec.version && (
v{spec.version}
)}
{spec.status && (
✓ {spec.status}
)}
{spec.publishedDate && (
Published {formatDate(spec.publishedDate)}
)}
{spec.description && (
<>
{spec.description}
>
)}
{expanded && (
{[
{ label: "Authors", people: spec.authors },
{ label: "Editors", people: spec.editors },
{ label: "Reviewers", people: spec.reviewers },
].filter(group => group.people?.length).map(({ label, people }) => (
))}
{(spec.namespace || spec.identifier) && (
URN
{spec.identifier || spec.namespace}
)}
)}
At a Glance
Functionalities
{functionalities.length}
Required
{totalReq}
Recommended
{totalRec}
Total
{totalReq + totalRec}
);
};
window.SpecComponents = window.SpecComponents || {};
window.SpecComponents.SpecHeader = SpecHeader;