import * as React from "react";
import { ColorPicker, Field } from "@/components/ui/color-picker-hex-swatches";
import { AlertTriangle, Check, FileSignature } from "lucide-react";
/* A brand theme editor. Drag in the square, pick a swatch, or type a hex:
"1ba" expands to #11bbaa and an invalid value never reaches your state.
The signing page on the right repaints as you change a colour, picks black
or white text for it, and reports the contrast ratio. */
function luminance(hex: string) {
const n = parseInt(hex.slice(1), 16);
const [r, g, b] = [(n >> 16) & 255, (n >> 8) & 255, n & 255].map((v) => {
const c = v / 255;
return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
});
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}
/* whichever of white and near-black reads better on the colour, and by how much */
function readable(hex: string) {
const L = luminance(hex);
const onWhite = 1.05 / (L + 0.05);
const onBlack = (L + 0.05) / 0.0556;
return onWhite >= onBlack ? { ink: "#ffffff", ratio: onWhite } : { ink: "#111111", ratio: onBlack };
}
const BRAND = ["#2563eb", "#1baf7a", "#eb6834", "#e87ba4", "#7c3aed", "#171717"];
const ACCENT = ["#f59e0b", "#14b8a6", "#ef4444", "#8b5cf6", "#0ea5e9", "#84cc16"];
export default function ColorPickerDemo() {
const [brand, setBrand] = React.useState("#2563eb");
const [accent, setAccent] = React.useState("#f59e0b");
const b = readable(brand);
const a = readable(accent);
return (
<div className="flex min-h-screen w-full items-center justify-center bg-background p-6">
<div className="grid w-full max-w-[780px] min-w-0 overflow-hidden rounded-[18px] [corner-shape:squircle] bg-card shadow-sm ring-1 ring-border sm:grid-cols-[300px_minmax(0,1fr)]">
<div className="p-6">
<h2 className="text-[17px] font-semibold tracking-[-0.01em]">Brand theme</h2>
<p className="mt-1 text-[13px] text-muted-foreground">Used on signing pages and emails your clients see.</p>
<div className="mt-6 grid gap-5">
<Field label="Brand colour" hint={`Text on it: ${b.ink === "#ffffff" ? "white" : "black"} · ${b.ratio.toFixed(1)}:1`}>
<ColorPicker value={brand} onValueChange={setBrand} swatches={BRAND} />
</Field>
<Field label="Accent colour" hint={`Text on it: ${a.ink === "#ffffff" ? "white" : "black"} · ${a.ratio.toFixed(1)}:1`}>
<ColorPicker value={accent} onValueChange={setAccent} swatches={ACCENT} />
</Field>
</div>
<p className="mt-6 flex items-center gap-1.5 text-[12px] text-muted-foreground" aria-live="polite">
{Math.min(b.ratio, a.ratio) >= 4.5 ? (
<><Check className="size-3.5" aria-hidden /> Both pass AA contrast</>
) : (
<><AlertTriangle className="size-3.5" aria-hidden /> One colour is below AA (4.5:1)</>
)}
</p>
</div>
<div className="border-t border-border bg-muted/40 p-6 sm:border-t-0 sm:border-l" aria-label="Preview">
<p className="mb-3 text-[11.5px] font-medium tracking-[0.06em] text-muted-foreground uppercase">Preview</p>
<div className="overflow-hidden rounded-[14px] [corner-shape:squircle] bg-background shadow-sm ring-1 ring-border">
<div className="flex items-center gap-2.5 px-4 py-3.5" style={{ background: brand, color: b.ink }}>
<span className="grid size-7 place-items-center rounded-[8px] [corner-shape:squircle] text-[12px] font-bold" style={{ background: b.ink, color: brand }}>
N
</span>
<span className="text-[13.5px] font-semibold">Northwind Studio</span>
<span className="ml-auto rounded-full px-2 py-0.5 text-[11px] font-semibold" style={{ background: accent, color: a.ink }}>
Action needed
</span>
</div>
<div className="grid gap-4 p-4">
<div className="flex items-start gap-3">
<span className="grid size-9 shrink-0 place-items-center rounded-[10px] [corner-shape:squircle] bg-muted">
<FileSignature className="size-4" aria-hidden />
</span>
<div className="min-w-0">
<p className="text-[13.5px] font-medium">Master services agreement</p>
<p className="text-[12.5px] text-muted-foreground">Daniel, this is ready for your signature.</p>
</div>
</div>
<div>
<div className="flex justify-between text-[11.5px] text-muted-foreground">
<span>2 of 3 signers</span>
<span>Due 12 Oct</span>
</div>
<div className="mt-1.5 h-1.5 overflow-hidden rounded-full bg-muted">
<div className="h-full w-2/3 rounded-full" style={{ background: accent }} />
</div>
</div>
<div className="flex items-center gap-3">
<span className="inline-flex h-9 items-center rounded-[10px] [corner-shape:squircle] px-3.5 text-[13px] font-medium" style={{ background: brand, color: b.ink }}>
Review and sign
</span>
<span className="text-[13px] font-medium underline underline-offset-4" style={{ textDecorationColor: brand }}>
Download PDF
</span>
</div>
</div>
</div>
</div>
</div>
</div>
);
}