Recipe: Color contrast checker integration
Embed a live WCAG contrast checker into any Meridian dashboard view using a lightweight, zero-dependency utility.
Overview
This recipe wires a pure-function contrast calculator into a reactive preview panel. It accepts hex foreground and background values, computes the luminance ratio per WCAG 2.1, and renders the pass/fail verdict alongside the ratio score.
Step 1 — Luminance utility
function relativeLuminance(hex: string): number {
const [r, g, b] = hex.match(/\w\w/g)!.map((c) => {
const s = parseInt(c, 16) / 255;
return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
});
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
}Step 2 — Ratio & verdict
function contrastRatio(fg: string, bg: string) {
const l1 = relativeLuminance(fg);
const l2 = relativeLuminance(bg);
const ratio = (Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05);
return {
ratio: ratio.toFixed(2),
aa: ratio >= 4.5,
aaLarge: ratio >= 3,
aaa: ratio >= 7,
};
}Step 3 — Preview panel
Render a live swatch bound to two color inputs. Display the ratio and WCAG level badges using native Tailwind classes — no external component library needed.
Preview
Ratio: 8.59
AA passAAA passNotes
- WCAG 2.1 AA requires 4.5:1 for normal text, 3:1 for large text.
- AAA requires 7:1 for normal text, 4.5:1 for large text.
- Keep the utility pure — no DOM access, no React hooks — for reuse across server and client contexts.