← Back to docs

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 pass

Notes

  • 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.