Skip to content

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

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

FormatExample
hexgetContrastingTextColor({ hex: '#C801CC' })
rgbgetContrastingTextColor({ rgb: 'rgb(200 1 204)' })
hslgetContrastingTextColor({ hsl: 'hsl(298 99% 40%)' })
oklchgetContrastingTextColor({ oklch: 'oklch(57.5% 0.208 257.5deg)' })
oklabgetContrastingTextColor({ oklab: 'oklab(0.6 0.1 -0.05)' })
stashTokengetContrastingTextColor({ 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:

ts
{
  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:

ts
// 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

Select a Stash Color, or input a valid Hex Value
(Hex Value will take priority)

Note: Playground fields are listed in priority order.