refactor(nexus): restyle theme palette grid with design.md language
This commit is contained in:
parent
0c1496d2fe
commit
d3141ac534
1 changed files with 48 additions and 34 deletions
|
|
@ -1,6 +1,11 @@
|
|||
import { Badge } from "@/components/ui/badge";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
/**
|
||||
* Palette role shape emitted by the theme-generation workshop.
|
||||
* Each role carries both a dark and light variant resolved as OKLCH + hex
|
||||
* alongside a WCAG AA pass/fail flag computed against the generated
|
||||
* background.
|
||||
*/
|
||||
export interface PaletteRole {
|
||||
name: string;
|
||||
dark: { oklch: string; hex: string; wcagAA: boolean };
|
||||
|
|
@ -18,9 +23,9 @@ const ROLE_LABELS: Record<string, string> = {
|
|||
surface: "Surface",
|
||||
overlay: "Overlay",
|
||||
text: "Text",
|
||||
"accent-1": "Accent-1",
|
||||
"accent-2": "Accent-2",
|
||||
"accent-3": "Accent-3",
|
||||
"accent-1": "Accent 1",
|
||||
"accent-2": "Accent 2",
|
||||
"accent-3": "Accent 3",
|
||||
};
|
||||
|
||||
function Swatch({
|
||||
|
|
@ -34,34 +39,35 @@ function Swatch({
|
|||
const label = ROLE_LABELS[role.name] ?? role.name;
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center gap-1" style={{ minWidth: 56 }}>
|
||||
<div
|
||||
className="flex flex-col gap-2 rounded-sm border border-border bg-card p-2"
|
||||
style={{ minWidth: 96 }}
|
||||
>
|
||||
<div
|
||||
className="rounded-md border border-border"
|
||||
className="rounded-sm border border-border"
|
||||
style={{
|
||||
width: 40,
|
||||
height: 40,
|
||||
height: 44,
|
||||
backgroundColor: entry.hex,
|
||||
minWidth: 40,
|
||||
minHeight: 40,
|
||||
}}
|
||||
title={`${label}: ${entry.hex}`}
|
||||
aria-label={`${label} swatch ${entry.hex}`}
|
||||
/>
|
||||
<span className="font-mono text-xs text-muted-foreground">
|
||||
{entry.hex}
|
||||
</span>
|
||||
{entry.wcagAA ? (
|
||||
<Badge
|
||||
variant="default"
|
||||
className="bg-[#40a02b] dark:bg-[#a6e3a1] text-white dark:text-black border-0 text-[10px] px-1.5 py-0"
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<span className="text-[11px] font-semibold uppercase tracking-[0.1em] text-foreground">
|
||||
{label}
|
||||
</span>
|
||||
<span className="font-mono text-[11px] text-muted-foreground">
|
||||
{entry.hex}
|
||||
</span>
|
||||
<span
|
||||
className={cn(
|
||||
"text-[10px] font-semibold uppercase tracking-[0.08em]",
|
||||
entry.wcagAA ? "text-primary" : "text-destructive",
|
||||
)}
|
||||
>
|
||||
AA
|
||||
</Badge>
|
||||
) : (
|
||||
<Badge variant="destructive" className="text-[10px] px-1.5 py-0">
|
||||
Fails AA
|
||||
</Badge>
|
||||
)}
|
||||
{entry.wcagAA ? "AA" : "Fails AA"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -75,8 +81,8 @@ function PaletteRow({
|
|||
}) {
|
||||
return (
|
||||
<div className="flex flex-col gap-2">
|
||||
<span className="text-xs font-medium text-muted-foreground capitalize">
|
||||
{variant}
|
||||
<span className="text-[12px] font-semibold uppercase tracking-[0.1em] text-muted-foreground">
|
||||
{variant === "dark" ? "Dark mode" : "Light mode"}
|
||||
</span>
|
||||
<div className="flex flex-row flex-wrap gap-2">
|
||||
{palette.map((role) => (
|
||||
|
|
@ -89,28 +95,36 @@ function PaletteRow({
|
|||
|
||||
export function ThemePaletteGrid({
|
||||
palette,
|
||||
variant = "dark",
|
||||
variant,
|
||||
className,
|
||||
}: ThemePaletteGridProps) {
|
||||
if (palette.length === 0) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-col items-center justify-center gap-2 rounded-lg border border-dashed border-border p-8 text-center",
|
||||
"flex flex-col items-center justify-center gap-2 rounded-sm border border-dashed border-border p-8 text-center",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<h3 className="text-base font-semibold text-foreground">
|
||||
No palette yet
|
||||
</h3>
|
||||
<p className="text-sm text-muted-foreground max-w-xs">
|
||||
Pick a seed color to generate a full OKLCH palette with dark and light
|
||||
variants.
|
||||
<h3 className="text-base font-bold text-foreground">No palette yet</h3>
|
||||
<p className="max-w-xs text-sm text-muted-foreground">
|
||||
Pick a seed color to generate a full OKLCH palette with dark and
|
||||
light variants.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// When variant is passed explicitly, render only that row. Otherwise show
|
||||
// both dark and light, so reviewers can compare the generated bundle.
|
||||
if (variant) {
|
||||
return (
|
||||
<div className={cn("flex flex-col gap-4", className)}>
|
||||
<PaletteRow palette={palette} variant={variant} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cn("flex flex-col gap-4", className)}>
|
||||
<PaletteRow palette={palette} variant="dark" />
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue