getContrastingTextColor
Picks the Stash text color (white or ice-900) with the higher WCAG contrast against a given background.
The function is pure: no DOM access, SSR-safe, jsdom-safe.
Import
import { getContrastingTextColor } from '@leaflink/stash-utils/getContrastingTextColor';Input
The argument is a discriminated object — the caller declares which color format they're providing. No auto-detection.
| Format | Example |
|---|---|
hex | getContrastingTextColor({ hex: '#C801CC' }) |
rgb | getContrastingTextColor({ rgb: 'rgb(200 1 204)' }) |
hsl | getContrastingTextColor({ hsl: 'hsl(298 99% 40%)' }) |
oklch | getContrastingTextColor({ oklch: 'oklch(57.5% 0.208 257.5deg)' }) |
oklab | getContrastingTextColor({ oklab: 'oklab(0.6 0.1 -0.05)' }) |
stashToken | getContrastingTextColor({ stashToken: 'blue-500' }) |
For stashToken, you can pass a primary color name ('blue') — it resolves to the -500 shade — or any exact token ('blue-100' … 'blue-950'), or 'white' / 'black'.
Return
The function returns a frozen object with the picked color in four forms:
{
token: 'white' | 'ice-900', // for Tailwind: `text-${token}` / `bg-${token}`
cssVar: 'var(--stash-color-…)', // inline style; follows theme changes
oklch: 'oklch(…)', // canonical literal
hex: '#FFFFFF' | '#27282A', // hex shorthand
}Pick the property that matches how you'll consume it:
// Tailwind class composition
`text-${getContrastingTextColor({ stashToken: 'blue-500' }).token}` // → 'text-white'
// Inline style that follows theme changes
:style="{ color: getContrastingTextColor({ hex: '#abc123' }).cssVar }"
// Anywhere CSS isn't an option (canvas, SVG attrs, email)
ctx.fillStyle = getContrastingTextColor({ rgb: 'rgb(0 0 0)' }).hex;Fallback
When the input fails to parse, the function returns the dark text result and warns to the console (development only).
Playground
(Hex Value will take priority)
Note: Playground fields are listed in priority order.
INFO
Picks based on WCAG 2.x relative luminance and contrast ratio.