Rewrite components/ui/* (Button, Card, Badge, PageHeader, EmptyState, Skeleton) against the chunk-1 tokens instead of hardcoded gray-9xx classes, and drop the remaining font-mono from label/heading text. Add the three colour-blindness-validated encoding components from UI_REDESIGN.md §2.3: - components/marks/SeverityMark.tsx — glyph (filled triangle / outline triangle / outline circle) + optional spine + optional label, from the four-level severity ladder. Colour is never the only channel. - components/marks/TypeGlyph.tsx — five stroked SVG glyphs (fire, police, ems, collision, other) in currentColor. Incident type is now shape, not hue, since five hues can't clear an all-pairs CVD gate. - components/marks/NodeMark.tsx — diamond at four weights (filled+ring / filled / hollow / hollow-dashed). Green is gone from node state entirely. lib/severity.tsx now renders through SeverityMark; SEVERITY_COLORS reads the validated sev-moderate/sev-major tokens with routine/minor neutral. IncidentBadges.tsx's TypeBadge is reimplemented on TypeGlyph instead of a coloured pill. Per UI_REDESIGN.md chunk 2.
25 lines
827 B
TypeScript
25 lines
827 B
TypeScript
import type { ReactNode } from "react";
|
|
|
|
interface PageHeaderProps {
|
|
title: ReactNode;
|
|
description?: ReactNode;
|
|
badge?: ReactNode;
|
|
action?: ReactNode;
|
|
}
|
|
|
|
/** Standard page title row — title + optional badge on the left, primary action on the right. */
|
|
export function PageHeader({ title, description, badge, action }: PageHeaderProps) {
|
|
return (
|
|
<div className="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-3">
|
|
<div className="min-w-0">
|
|
<div className="flex items-center gap-3 flex-wrap">
|
|
<h1 className="text-xl font-semibold text-ink">{title}</h1>
|
|
{badge}
|
|
</div>
|
|
{description && <p className="text-ink-muted text-sm mt-1 max-w-2xl">{description}</p>}
|
|
</div>
|
|
{action && <div className="shrink-0">{action}</div>}
|
|
</div>
|
|
);
|
|
}
|