Color utilities

Convert colors, measure contrast, build palettes, and generate full themes from your own code, with the functions Chameleon builds its themes with. To theme your components from a seed color, start with Theming.

What you can build⁠

  • A color picker. toneStrip, chromaStrip, and hueStrip return the gradient stops for each slider. maxChromaAt returns the highest chroma sRGB can hold at a hue and tone, so the chroma slider never offers a color a hex string can't express.
  • Accessible color pairs. contrastRatioFromHex measures WCAG contrast and apcaContrast measures APCA (the Accessible Perceptual Contrast Algorithm). foregroundTone finds the text tone that reaches a target WCAG ratio on a background, and solveRole finds one color that stays readable on every surface it can land on.
  • A palette from a photo. seedColorFromImage picks the best seed color from an image, and quantizeAndScore returns several, ranked.
  • A theme from a brand color. generateThemeCssFromHex writes every --ct-sys-color-* custom property as a stylesheet that follows the user's light or dark setting, with fixed light and dark declarations alongside.

Hex, ARGB, and HCT⁠

Besides CSS hex strings, functions take and return colors in two forms:

  • ARGB packs a color into one 32-bit unsigned integer: alpha in the top byte, then red, green, and blue. Opaque purple is 0xff6750a4. Convert to and from a CSS hex string with argbFromHex and hexFromArgb.
  • HCT describes a color by hue, chroma, and tone, as an object { hue, chroma, tone }. Google created it for Material Design and explains it in The Science of Color & Design.

Work in HCT whenever you change one property of a color and need the others to stay put:

  • Hue is the angle on the color wheel, from 0 to 360 degrees.
  • Chroma is colorfulness, from 0 for a gray to about 120. The highest chroma available depends on hue and tone; maxChromaAt returns the maximum chroma for a specific hue and tone.
  • Tone is perceived lightness, from 0 for black to 100 for white. WCAG contrast between two colors depends on their tones alone, so choose tones for contrast first and hues second.

Build time or run time⁠

The same functions, with the same names and signatures, ship in two packages. Which one you use depends on when you know your colors.

  • At build time, when you know the themes before the app ships. Generate them in a Node or Deno build script with @materia-technologies-inc/chameleon-build-utilities/color, which requires a license grant, and serve the result as a stylesheet. The page loads with its colors ready and does no color work in the browser. Prefer this, above all for the first theme your app shows.
  • At run time, when the theme depends on something the app learns while it runs, such as a color the user picks or an image they upload. Import the same functions from @materia-technologies-inc/chameleon-components-web, the package that registers the components.

The build package doesn't have the Async functions, and the functions that decode an image don't work outside a browser.

Built on Material Color Utilities⁠

Chameleon's color utilities extend Google's Material Color Utilities by adding:

  • Complete theme stylesheets from a seed color. generateThemeSheet writes every --ct-sys-color-* role into a stylesheet you can serve as it is: it follows the user's light or dark setting, can be pinned to light or dark, steps up to higher contrast when the user asks for more, and works in browsers with or without light-dark() support. generateThemeCssFromHex gives you one theme's CSS to place yourself.
  • Information, success, and warning color roles, alongside error.
  • The Chord theme variant.
  • APCA contrast, alongside WCAG contrast.
  • The contrast solvers solveRole and solveLadder.
  • Strip and batch functions that compute a run of colors in one call, such as toneStrip, maxChromaStrip, and hctBatchFromArgbF32, for example to draw the gradients behind a color picker's sliders.

Using the color utilities⁠

In the browserIn a build scriptAPI reference

If your page already loads Chameleon, the color functions are already installed. Import them from the same package:

import { argbFromHex, hctFromArgb } from "@materia-technologies-inc/chameleon-components-web";
content_copy

Calling a color function in the browser needs no license grant. The package itself needs a browser, because importing it registers every cw-* element; in a build script, use the build package (the In a build script tab).

Pick a readable text color⁠

Keep a background's hue, and find the tone that reaches a WCAG contrast of 4.5:1 against it:

import {
  argbFromHct,
  argbFromHex,
  foregroundTone,
  hctFromArgb,
  hexFromArgb,
} from "@materia-technologies-inc/chameleon-components-web";

const background = hctFromArgb(argbFromHex("#6750a4"));
const tone = foregroundTone(background.tone, 4.5);
const text = hexFromArgb(argbFromHct(background.hue, 16, tone));
// text is "#ded5ee", which measures 4.56:1 on #6750a4
content_copy

Draw a tone slider⁠

Give a slider track the full range of tones at a color's hue and chroma, in 11 stops:

import { argbFromHex, hctFromArgb, hexFromArgb, toneStrip } from "@materia-technologies-inc/chameleon-components-web";

const { hue, chroma } = hctFromArgb(argbFromHex("#6750a4"));
const stops = Array.from(toneStrip(hue, chroma, 0, 100, 11), hexFromArgb);
document.querySelector(".tone-track").style.background = `linear-gradient(to right, ${stops.join(", ")})`;
// stops run from "#000000" through "#6750a4" to "#ffffff"
content_copy

Take a seed color from a photo⁠

Pass a file straight from a file input; the browser decodes it:

import { hexFromArgb, seedColorFromImage } from "@materia-technologies-inc/chameleon-components-web";

const picker = document.createElement("input");
picker.type = "file";
picker.accept = "image/*";
picker.addEventListener("change", async () => {
  const file = picker.files?.[0];
  if (file) {
    const seed = await seedColorFromImage(file);
    console.log(hexFromArgb(seed));
  }
});
document.body.append(picker);
content_copy

Keep the page responsive⁠

Eight heavy functions also come in an Async form, such as generateThemeSheetAsync and quantizePixelsAsync. Call that form while the user is interacting with the page. It takes the same arguments, returns a promise of the same result, and does its work on a worker. Where your Content Security Policy doesn't allow worker-src blob:, it runs on the page's thread and still returns the right result.

Use the build package to compute colors in a script that runs on Node 20 or newer, or on Deno, such as a script that writes your theme stylesheet before you deploy.

Install the packages⁠

Install the build package and the grant tooling as development dependencies. The color functions won't run without the grant tooling.

npm install --save-dev @materia-technologies-inc/chameleon-build-utilities @materia-technologies-inc/chameleon-grant
content_copy

License the script⁠

Set the CHAMELEON_LICENSE_TOKEN environment variable to your build token, as every Chameleon build requires; License your build shows how. Importing the color functions obtains a license grant with that token. Without the token, the import throws before any of your code runs:

[chameleon-build-utilities] No grant is available: CHAMELEON_LICENSE_TOKEN is not set. Set it to your build token (it must reach a non-interactive shell).
content_copy
  • A script still runs offline for up to 15 days after its last connected run.
  • A refused token stops the script, as it stops any Chameleon build.

Use the build package for build scripts that run, produce a result, and then exit, rather than for long-running servers.

Write a theme stylesheet⁠

Save this as theme.mjs and run it with node theme.mjs to write a stylesheet that follows the user's light or dark setting:

import { writeFile } from "node:fs/promises";
import { generateThemeCssFromHex } from "@materia-technologies-inc/chameleon-build-utilities/color";

const theme = generateThemeCssFromHex("#6750a4");
await writeFile("theme.css", theme.system);
// theme.css sets every --ct-sys-color-* property on :root
content_copy

theme.light and theme.dark are declaration blocks with no selector, for a region fixed to light or dark. Write one inside your own rule, such as [data-theme="dark"] { … }.

Convert and compare colors⁠

Save this as palette.mjs and run it with node palette.mjs:

import {
  argbFromHct,
  argbFromHex,
  contrastRatioFromHex,
  hctFromArgb,
  hexFromArgb,
} from "@materia-technologies-inc/chameleon-build-utilities/color";

// Hex to HCT
const { hue, chroma, tone } = hctFromArgb(argbFromHex("#6750a4"));
console.log(Math.round(hue), Math.round(chroma), Math.round(tone)); // 299 48 40

// The same hue and chroma at tone 90, back to hex
const light = hexFromArgb(argbFromHct(hue, chroma, 90));
console.log(light); // #e9ddff

// The WCAG contrast ratio between the two
console.log(contrastRatioFromHex("#6750a4", light).toFixed(2)); // 4.98
content_copy

Take colors from an image⁠

A script has no browser to decode an image, so seedColorFromImage, quantizeImage, quantizeAndScore, and pixelsFromImage throw there. Decode it with any image library that returns raw RGBA bytes, pack each pixel into an ARGB integer with argbFromRgb, and pass the array to seedColorFromPixels, quantizePixels, or quantizeAndScorePixels.

Conversion⁠

Move a color between a CSS hex string, separate red, green, and blue channels, and an ARGB integer.

argbFromHex⁠

Convert a CSS hex color string to an ARGB integer. Accepts 3, 4, 6, or 8 hex digit formats with or without leading '#'.

function argbFromHex(hex: string): number;
content_copy
  • hex: CSS hex color string (for example, '#c0ffee', '#fff', 'c0ffee')
  • Returns: ARGB color as a 32-bit unsigned integer (alpha defaults to 0xFF for 3/6-digit input)

hexFromArgb⁠

Convert an ARGB integer to a CSS hex color string.

function hexFromArgb(argb: number): string;
content_copy
  • argb: ARGB color as a 32-bit unsigned integer
  • Returns: CSS hex color string (for example, '#c0ffee'): always lowercase, 6-digit, without alpha

argbFromRgb⁠

Create an ARGB color from RGB components. Alpha is set to 255 (fully opaque).

function argbFromRgb(r: number, g: number, b: number): number;
content_copy
  • r: Red component (0–255)
  • g: Green component (0–255)
  • b: Blue component (0–255)
  • Returns: ARGB color as a 32-bit unsigned integer

blendColors⁠

foreground composited over background at alpha, as #rrggbb.

function blendColors(foreground: string, background: string, alpha: number): string;
content_copy

HCT⁠

Convert to and from hue, chroma, and tone, and find how much chroma sRGB can hold.

HctColor⁠

A color as hue, chroma, and tone. Hue is 0–360 degrees, chroma is colorfulness, typically 0–120, and tone is perceptual lightness, 0–100.

interface HctColor {
    hue: number;
    chroma: number;
    tone: number;
}
content_copy

hctFromArgb⁠

Convert an ARGB color to HCT components.

function hctFromArgb(argb: number): HctColor;
content_copy
  • argb: ARGB color as a 32-bit unsigned integer
  • Returns: HCT color with hue (0–360), chroma (0-~120), tone (0–100)

argbFromHct⁠

Convert HCT components to an ARGB color.

function argbFromHct(hue: number, chroma: number, tone: number): number;
content_copy
  • hue: Hue in degrees (0–360)
  • chroma: Chroma (colorfulness, typically 0–120)
  • tone: Tone (lightness L*, 0–100)
  • Returns: ARGB color as a 32-bit unsigned integer

solveHct⁠

A color from hue, chroma and tone, reporting what was actually achieved.

function solveHct(hue: number, chroma: number, tone: number): {
    argb: number;
    hue: number;
    chroma: number;
    tone: number;
};
content_copy
  • hue: Hue in degrees (0–360)
  • chroma: Requested chroma
  • tone: Tone (0–100)
  • Returns: The packed color, and the hue, chroma and tone sRGB actually held

colorsAt⁠

Gamut-clamped colors from HCT, reporting what was achieved, in one call.

function colorsAt(requests: readonly ColorRequest[]): readonly SolvedColor[];
content_copy
  • requests: The colors wanted.
  • Returns: One entry per request, in order.

ColorRequest⁠

A color asked for in HCT, for colorsAt.

interface ColorRequest {
    hue: number;
    chroma: number;
    tone: number;
}
content_copy

SolvedColor⁠

A color, and what sRGB actually held.

interface SolvedColor {
    argb: number;
    hue: number;
    chroma: number;
    tone: number;
}
content_copy

hctBatchFromArgbF32⁠

Convert an array of ARGB colors to HCT components (f32 output) in a single call. Returns a flat Float32Array: [hue0, chroma0, tone0, ...]

function hctBatchFromArgbF32(argbs: Uint32Array | number[], out?: Float32Array): Float32Array;
content_copy

argbBatchFromHct⁠

Convert arrays of HCT components to ARGB colors in a single call.

function argbBatchFromHct(hues: Float64Array | Float32Array | number[], chromas: Float64Array | Float32Array | number[], tones: Float64Array | Float32Array | number[], out?: Uint32Array): Uint32Array;
content_copy

maxChromaAt⁠

The highest chroma sRGB actually holds at this hue and tone.

function maxChromaAt(hue: number, tone: number): number;
content_copy
  • hue: Hue in degrees (0–360)
  • tone: Tone (0–100)
  • Returns: Chroma at the gamut boundary; 0 at tone 0 and tone 100.

maxChromaStrip⁠

The gamut boundary across a range of tones, in one call.

function maxChromaStrip(hue: number, startTone: number, endTone: number, steps: number, out?: Float64Array): Float64Array;
content_copy
  • hue: Hue in degrees (0–360)
  • startTone: Starting tone (0–100)
  • endTone: Ending tone (0–100)
  • steps: Number of samples, minimum 2
  • out: Optional output buffer to write into instead of allocating
  • Returns: Chroma at the boundary for each tone

peakChromaRamp⁠

The tone carrying the most chroma, for each of several hues, in one call.

function peakChromaRamp(hues: readonly number[], startTone: number, toneStep: number, steps: number, chromaCeiling: number): readonly PeakChroma[];
content_copy
  • hues: Hues in degrees. Used verbatim.
  • startTone: First tone of the search grid.
  • toneStep: Distance between grid tones.
  • steps: How many grid tones.
  • chromaCeiling: Upper bound on the chroma taken from any tone.
  • Returns: One entry per hue, in order.

PeakChroma⁠

The most-chroma tone found at one hue, and the color there.

interface PeakChroma {
    argb: number;
    tone: number;
    chroma: number;
    hue: number;
    achievedChroma: number;
    achievedTone: number;
}
content_copy
  • argb: The color.
  • tone: The grid tone that won.
  • chroma: min(ceiling, boundary at that tone).
  • hue: Hue, as sRGB actually held it.
  • achievedChroma: Chroma, as sRGB actually held it.
  • achievedTone: Tone, as sRGB actually held it.

Contrast⁠

Measure contrast between colors or tones, and solve for a color that reaches a contrast you state.

contrastRatio⁠

The WCAG contrast ratio between two tones, 1.0 to 21.0.

function contrastRatio(toneA: number, toneB: number): number;
content_copy
  • toneA: First tone (0–100)
  • toneB: Second tone (0–100)

contrastRatioFromHex⁠

WCAG 2.x contrast between two hex colors, 1 to 21.

function contrastRatioFromHex(a: string, b: string): number;
content_copy

wcagRatioArgb⁠

WCAG 2.x contrast between two ARGB colors, measured from their 8-bit sRGB channels, 1 to 21.

function wcagRatioArgb(a: number, b: number): number;
content_copy

apcaContrast⁠

APCA Lc, W3C draft 0.1.9, as an absolute value.

function apcaContrast(text: string, background: string): number;
content_copy

apcaLcArgb⁠

APCA Lc, W3C draft 0.1.9, between two ARGB colors, as an absolute value.

function apcaLcArgb(text: number, background: number): number;
content_copy

relativeLuminance⁠

WCAG 2.x relative luminance, 0 to 1.

function relativeLuminance(hex: string): number;
content_copy

toneFromLuminance⁠

The tone whose luminance is y: the inverse of relativeLuminance up to the perceptual transfer, that is, CIE Y to CIE L*.

function toneFromLuminance(y: number): number;
content_copy

lighterTone⁠

The tone above tone that reaches ratio against it.

function lighterTone(tone: number, ratio: number): number;
content_copy
  • tone: The tone to contrast against (0–100)
  • ratio: Target contrast ratio (1.0–21.0)
  • Returns: The tone, or -1 if no lighter tone reaches the ratio

darkerTone⁠

The tone below tone that reaches ratio against it.

function darkerTone(tone: number, ratio: number): number;
content_copy
  • tone: The tone to contrast against (0–100)
  • ratio: Target contrast ratio (1.0–21.0)
  • Returns: The tone, or -1 if no darker tone reaches the ratio

foregroundTone⁠

A foreground tone that reaches ratio against a background tone.

function foregroundTone(backgroundTone: number, ratio: number): number;
content_copy
  • backgroundTone: The background tone (0–100)
  • ratio: Target contrast ratio (1.0–21.0)

solveRole⁠

The first tone along a walk, at this hue and chroma, that clears every contrast floor against every surface, solved and audited in one call.

function solveRole(request: RoleRequest): RoleSolution;
content_copy
  • request: The color asked for, the surfaces, the floors and the walk.
  • Returns: The color, how it was arrived at, and what it achieved.

RoleRequest⁠

Everything solveRole needs.

interface RoleRequest {
    hue: number;
    chroma: number;
    surfaces: readonly number[];
    floors: readonly ContrastFloor[];
    from: number;
    to: number;
    step: number;
    boundSlack: number;
    fallbackMode: RoleFallbackModeValue;
    fallbackArgb?: number;
}
content_copy
  • hue: Hue in degrees. Used verbatim.
  • chroma: Chroma asked for. Clamped to the sRGB boundary at each candidate tone.
  • surfaces: Every surface the role may be drawn on. Every floor must clear on each.
  • floors: The minima to clear, in any mix of readings.
  • from: Where the design would like the color to sit.
  • to: The far end of the tone window, inclusive.
  • step: Signed tone step. Negative walks down toward dark, positive walks up.
  • boundSlack: Tones to back the WCAG start bound off by, toward from.
  • fallbackMode: What to return when nothing clears.
  • fallbackArgb: The color for RoleFallbackMode.Fixed. Ignored otherwise.

RoleSolution⁠

A solved role, with what it cost and what it achieved.

interface RoleSolution {
    argb: number;
    tone: number;
    hue: number;
    chroma: number;
    achievedTone: number;
    status: RoleStatusValue;
    candidates: number;
    floorMinima: readonly number[];
}
content_copy
  • argb: The color.
  • tone: The walk tone that won. For a fixed fallback this is achievedTone.
  • hue: Hue, as sRGB actually held it.
  • chroma: Chroma, as sRGB actually held it.
  • achievedTone: Tone, as sRGB actually held it.
  • status: How the answer was arrived at.
  • candidates: How many tones were evaluated.
  • floorMinima: The WORST reading the returned color achieved over all surfaces, one per floor, in the order the floors were given and each in its own metric.

ContrastFloor⁠

A minimum a candidate color must clear, in one reading.

interface ContrastFloor {
    metric: ContrastMetricValue;
    minimum: number;
}
content_copy

solveLadder⁠

A ladder of surfaces matched on contrast STEPS rather than on tones.

function solveLadder(request: LadderRequest): readonly LadderStep[];
content_copy
  • request: The ground, the grid, and the rungs.
  • Returns: One entry per rung, in order.

LadderRequest⁠

Everything solveLadder needs.

interface LadderRequest {
    ground: number;
    gridFirst: number;
    gridStep: number;
    gridCount: number;
    window: number;
    rungs: readonly LadderRung[];
}
content_copy
  • ground: Output index 0. Not itself solved; rungs step off it.
  • gridFirst: Tone at grid index 0.
  • gridStep: Distance between adjacent grid tones.
  • gridCount: How many grid tones there are.
  • window: Grid indices either side of each root to evaluate.
  • rungs: What to solve, in order.

LadderRung⁠

One rung of a matched ladder: a color to solve, its parent, and the step.

interface LadderRung {
    hue: number;
    chroma: number;
    parent: number;
    ratio: number;
}
content_copy
  • hue: Hue of the rung. Used verbatim.
  • chroma: Chroma asked for. Clamped to the sRGB boundary at each candidate tone.
  • parent: Index into the OUTPUT ladder: 0 is the ground, k >= 1 is rung k - 1. Must name a rung already solved, so the shape is a tree: several rungs may hang off the ground.
  • ratio: The WCAG contrast step to reproduce against that parent.

LadderStep⁠

One solved rung.

interface LadderStep {
    argb: number;
    tone: number;
    hue: number;
    chroma: number;
    achievedTone: number;
    ratio: number;
}
content_copy
  • argb: The color.
  • tone: The grid tone it sits on.
  • hue: Hue, as sRGB actually held it.
  • chroma: Chroma, as sRGB actually held it.
  • achievedTone: Tone, as sRGB actually held it.
  • ratio: The contrast actually achieved against the parent.

Tones and palettes⁠

Build strips of colors for sliders and swatches, and Material's standard tonal palette.

toneStrip⁠

Generates a gradient of ARGB colors varying tone at a fixed hue and chroma. Made for tone sliders in color pickers.

function toneStrip(hue: number, chroma: number, startTone: number, endTone: number, steps: number): Uint32Array;
content_copy
  • hue: Hue in degrees (0–360)
  • chroma: Chroma (colorfulness)
  • startTone: Starting tone (0–100)
  • endTone: Ending tone (0–100)
  • steps: Number of gradient stops (for example, 101 for 0–100 inclusive)
  • Returns: Array of ARGB colors

chromaStrip⁠

Generates a gradient of ARGB colors varying chroma at a fixed hue and tone. Made for chroma sliders.

function chromaStrip(hue: number, tone: number, startChroma: number, endChroma: number, steps: number): Uint32Array;
content_copy
  • hue: Hue in degrees (0–360)
  • tone: Tone (0–100)
  • startChroma: Starting chroma (typically 0)
  • endChroma: Ending chroma (typically 100–150)
  • steps: Number of gradient stops
  • Returns: Array of ARGB colors

hueStrip⁠

Generates a gradient of ARGB colors varying hue at a fixed chroma and tone. Made for hue sliders covering the full 360 degrees.

function hueStrip(chroma: number, tone: number, steps: number): Uint32Array;
content_copy
  • chroma: Chroma (colorfulness)
  • tone: Tone (0–100)
  • steps: Number of hue stops (for example, 360 for 1° resolution)
  • Returns: Array of ARGB colors covering hue 0° to 360°

tonalPaletteMaterialTones⁠

Material Design 3 standard tonal palette tones. Returns 13 ARGB colors at tones: 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 95, 99, 100

function tonalPaletteMaterialTones(hue: number, chroma: number): Uint32Array;
content_copy
  • hue: Hue angle (0–360)
  • chroma: Chroma value
  • Returns: Array of 13 ARGB colors at Material Design standard tones

Schemes and themes⁠

Generate color schemes and theme stylesheets from a seed color. For when to use each and what the options do, see the Color tab of Theming.

generateThemeSheet⁠

Generates one stylesheet carrying every theme, following the OS scheme and overridable per subtree. Given two contrast levels, it emits the higher one under prefers-contrast: more; a stylesheet holds at most two.

function generateThemeSheet(themes: readonly ThemeSpec[], options?: ThemeSheetOptions): string;
content_copy
  • themes: The themes to emit, in cascade order.
  • options: Sheet-wide defaults and emission control.
  • Returns: The complete stylesheet.

generateThemeSheetAsync⁠

generateThemeSheet, off the main thread. The heaviest call here: a stylesheet for every theme given, at the contrast levels given, up to two.

In the browser package only.

function generateThemeSheetAsync(themes: readonly ThemeSpec[], options?: ThemeSheetOptions): Promise<string>;
content_copy
  • themes: The themes to emit, in cascade order.
  • options: Sheet-wide defaults and emission control.

ThemeSpec⁠

One theme in a generateThemeSheet call.

interface ThemeSpec {
    readonly selector: string | readonly string[];
    readonly seed: string | number | HctColor;
    readonly variant?: ColorThemeVariantType;
    readonly specification?: ColorSpecificationType;
    readonly contrasts?: readonly ContrastValue[];
    readonly declarations?: Readonly<Record<string, string>>;
    readonly overrides?: Readonly<Record<string, SchemeOverride>>;
}
content_copy
  • selector: The selector(s) this theme's tokens are declared on: a full CSS selector or a list of them, never a bare class name.
  • seed: The source color: a CSS hex string, an ARGB integer, or an HCT triple.
  • variant: Theme variant. Defaults to the sheet-wide variant.
  • specification: Color specification. Defaults to the sheet-wide specification.
  • contrasts: Contrast levels this theme is generated at. Defaults to the sheet-wide contrasts.
  • declarations: Declarations emitted with this theme that are not colors: corner shapes, radius scales, typefaces.
  • overrides: Per-token color overrides, applied to the generated token maps before any block is assembled.

ThemeSheetOptions⁠

Sheet-wide options for generateThemeSheet.

interface ThemeSheetOptions {
    readonly variant?: ColorThemeVariantType;
    readonly specification?: ColorSpecificationType;
    readonly contrasts?: readonly ContrastValue[];
    readonly compat?: boolean;
    readonly colorSchemeSelector?: string | null;
    readonly forcing?: {
        readonly light: string;
        readonly dark: string;
    } | null;
    readonly layer?: string;
    readonly onWarning?: (message: string) => void;
}
content_copy
  • variant: Default variant for themes that do not set one.
  • specification: Default specification for themes that do not set one.
  • contrasts: Default contrast levels for themes that do not set their own.
  • compat: When true (the default), emit the plain-hex baseline and prefers-color-scheme block alongside the light-dark() upgrade, so a browser without light-dark() still gets a fully themed page.
  • colorSchemeSelector: The selector color-scheme: light dark is declared on. Defaults to :root.
  • forcing: Class names for the two scheme-forcing rules, or null to emit neither. Defaults to .theme-light and .theme-dark.
  • layer: Wrap the whole sheet in @layer <name>.
  • onWarning: Where a contrast warning goes. Defaults to console.warn.

SchemeOverride⁠

An override of one color token: the same value in both schemes, or one scheme pinned and the other left generated.

type SchemeOverride = string | {
    readonly light?: string;
    readonly dark?: string;
};
content_copy

generateThemeCssFromHex⁠

Generates theme CSS (light, dark and system-following) from a hex seed color.

function generateThemeCssFromHex(hexColor: string, request?: ThemeCssRequest): ColorThemeCss;
content_copy
  • hexColor: The base color for the theme as a CSS compliant hex color (for example, #c0ffee).
  • request: Variant, specification, contrast, selector and compat, all optional.
  • Returns: The generated theme CSS (see ColorThemeCss).

generateThemeCssFromHexAsync⁠

generateThemeCssFromHex, off the main thread. Light, dark and system-following CSS from a hex seed.

In the browser package only.

function generateThemeCssFromHexAsync(hexColor: string, request?: ThemeCssRequest): Promise<ColorThemeCss>;
content_copy
  • hexColor: The base color for the theme as a CSS compliant hex color (for example, #c0ffee).
  • request: Variant, specification, contrast, selector and compat, all optional.

generateThemeCssFromHct⁠

Generates theme CSS (light, dark and system-following) from an HCT seed color.

function generateThemeCssFromHct(hctColor: HctColor, request?: ThemeCssRequest): ColorThemeCss;
content_copy
  • hctColor: The base color for the theme as an HCT color ({hue, chroma, tone}).
  • request: Variant, specification, contrast, selector and compat, all optional.
  • Returns: The generated theme CSS (see ColorThemeCss).

generateThemeCssFromArgb⁠

Generates theme CSS (light, dark and system-following) from an ARGB seed color.

function generateThemeCssFromArgb(argb: number, request?: ThemeCssRequest): ColorThemeCss;
content_copy
  • argb: The base color as an ARGB integer.
  • request: Variant, specification, contrast, selector and compat, all optional.
  • Returns: The generated theme CSS (see ColorThemeCss).

generateThemeCssFromArgbAsync⁠

generateThemeCssFromArgb, off the main thread. The same as the hex form, from a packed ARGB integer.

In the browser package only.

function generateThemeCssFromArgbAsync(argb: number, request?: ThemeCssRequest): Promise<ColorThemeCss>;
content_copy
  • argb: The base color as an ARGB integer.
  • request: Variant, specification, contrast, selector and compat, all optional.

ThemeCssRequest⁠

Request form for generateThemeCssFromHex, FromHct and FromArgb.

interface ThemeCssRequest {
    readonly variant?: ColorThemeVariantType;
    readonly spec?: ColorSpecificationType;
    readonly contrast?: number;
    readonly selector?: string;
    readonly compat?: boolean;
}
content_copy
  • variant: Theme variant. Defaults to ColorThemeVariant.Expressive.
  • spec: Color specification. Defaults to ColorSpecification.MaterialExpressive2025.
  • contrast: Contrast level (-1 to 1; standard values: 0, 0.5, 1). Defaults to 0.
  • selector: Selector the system stylesheet targets. Defaults to :root.
  • compat: When true (the default), system includes the prefers-color-scheme baseline so browsers without light-dark() still get a fully themed light/dark experience. Set to false for evergreen-only targets to emit just the lean light-dark() rule.

ColorThemeCss⁠

CSS for a generated color theme in its three delivery modes.

interface ColorThemeCss {
    readonly light: string;
    readonly dark: string;
    readonly system: string;
}
content_copy
  • light: Declarations forcing the light theme (color-scheme: light + hex values).
  • dark: Declarations forcing the dark theme (color-scheme: dark + hex values).
  • system: A complete stylesheet following the system light/dark setting, targeting options.selector (default :root). Unlike light/dark this is not a bare declaration block, because the compatibility structure requires @media/@supports at-rules, which cannot nest inside a declaration list.

ColorThemeCssOptions⁠

Options for generateThemeCssFromArgb and friends.

interface ColorThemeCssOptions {
    readonly selector?: string;
    readonly compat?: boolean;
}
content_copy
  • selector: Selector the system stylesheet targets. Defaults to :root.
  • compat: When true (the default), system includes the prefers-color-scheme baseline so browsers without light-dark() still get a fully themed light/dark experience. Set to false for evergreen-only targets to emit just the lean light-dark() rule.

generateDynamicThemeFromHex⁠

Generates a dynamic theme based on the provided hex color and theme variant.

function generateDynamicThemeFromHex(hexColor: string, request?: DynamicThemeRequest): ColorThemeSet;
content_copy
  • hexColor: The base color for the theme as a CSS compliant hex color (for example, #c0ffee).
  • request: Variant and specification, both optional.
  • Returns: The generated theme.

generateDynamicThemeFromHct⁠

Generates a dynamic theme based on the provided HCT color and theme variant.

function generateDynamicThemeFromHct(hctColor: HctColor, request?: DynamicThemeRequest): ColorThemeSet;
content_copy
  • hctColor: The base color for the theme as an HCT color ({hue, chroma, tone}).
  • request: Variant and specification, both optional.
  • Returns: The generated theme.

generateDynamicThemeFromArgb⁠

Generates a dynamic theme based on the provided ARGB color and theme variant.

function generateDynamicThemeFromArgb(argb: number, request?: DynamicThemeRequest): ColorThemeSet;
content_copy
  • argb: The base color as an ARGB integer.
  • request: Variant and specification, both optional.
  • Returns: The generated theme.

generateDynamicThemeTokensFromHex⁠

Generates tokens for a dynamic theme based on the provided hex color and theme variant.

function generateDynamicThemeTokensFromHex(hexColor: string, request?: DynamicThemeRequest): Map<ColorThemeName, string>;
content_copy
  • hexColor: The base color for the theme as a CSS compliant hex color (for example, #c0ffee).
  • request: Variant and specification, both optional.
  • Returns: Map of theme name (for example, lightDefault) to its CSS declarations string.

generateDynamicThemeTokensFromHct⁠

Generates tokens for a dynamic theme based on the provided HCT color and theme variant.

function generateDynamicThemeTokensFromHct(hctColor: HctColor, request?: DynamicThemeRequest): Map<ColorThemeName, string>;
content_copy
  • hctColor: The base color for the theme as an HCT color ({hue, chroma, tone}).
  • request: Variant and specification, both optional.
  • Returns: Map of theme name (for example, lightDefault) to its CSS declarations string.

DynamicThemeRequest⁠

Request form for generateDynamicThemeFromHex, FromHct, FromArgb and the generateDynamicThemeTokens* siblings.

interface DynamicThemeRequest {
    readonly variant?: ColorThemeVariantType;
    readonly spec?: ColorSpecificationType;
}
content_copy
  • variant: Theme variant. Defaults to ColorThemeVariant.Expressive.
  • spec: Color specification. Defaults to ColorSpecification.MaterialExpressive2025.

ColorThemeSet⁠

Represents a set of light and dark color themes, each in default, medium and high contrast. See Material Design Color System for more details.

interface ColorThemeSet {
    readonly lightDefault: ColorTokens;
    readonly lightMedium: ColorTokens;
    readonly lightHigh: ColorTokens;
    readonly darkDefault: ColorTokens;
    readonly darkMedium: ColorTokens;
    readonly darkHigh: ColorTokens;
}
content_copy
  • lightDefault: The default light theme.
  • lightMedium: The medium contrast light theme.
  • lightHigh: The high contrast light theme.
  • darkDefault: The default dark theme.
  • darkMedium: The medium contrast dark theme.
  • darkHigh: The high contrast dark theme.

ColorThemeName⁠

Name of one of the six themes in a ColorThemeSet.

type ColorThemeName = keyof ColorThemeSet;
content_copy

ColorTokens⁠

Represents a set of color tokens for a specific theme.

interface ColorTokens extends Map<string, string> {
}
content_copy

createSchemeSet⁠

Creates color schemes for one or more contrast levels, returning light and dark for each. It returns ARGB numbers only: to produce a stylesheet, use generateThemeCssFromHex or generateThemeSheet.

function createSchemeSet(argb: number, variant: ColorThemeVariantType, contrasts: number[], spec?: ColorSpecificationType): SchemeSetResult;
content_copy
  • argb: Source color as ARGB
  • variant: Color theme variant (use ColorThemeVariant enum)
  • contrasts: Array of contrast levels (each -1 to 1; standard values: 0, 0.5, 1)
  • spec: Color specification (use ColorSpecification enum, defaults to MaterialExpressive2025). Read by Expressive, Neutral, TonalSpot and Vibrant; discarded by the other six variants, which always resolve to MaterialYou2021.
  • Returns: SchemeSetResult with schemes[i].light / schemes[i].dark for each contrast

createSchemeSetAsync⁠

createSchemeSet, off the main thread. Every scheme for one seed at the contrast levels given.

In the browser package only.

function createSchemeSetAsync(argb: number, variant: ColorThemeVariantType, contrasts: number[], spec?: ColorSpecificationType): Promise<SchemeSetResult>;
content_copy
  • argb: Source color as ARGB
  • variant: Color theme variant (use ColorThemeVariant enum)
  • contrasts: Array of contrast levels (each -1 to 1; standard values: 0, 0.5, 1)
  • spec: Color specification (use ColorSpecification enum, defaults to MaterialExpressive2025). Read by Expressive, Neutral, TonalSpot and Vibrant; discarded by the other six variants, which always resolve to MaterialYou2021.

createScheme⁠

Creates a single color scheme, light or dark, at one contrast level.

function createScheme(argb: number, variant: ColorThemeVariantType, isDark: boolean, contrast: number, spec?: ColorSpecificationType): SchemeColors;
content_copy
  • argb: Source color as ARGB
  • variant: Color theme variant (use ColorThemeVariant enum)
  • isDark: true for dark scheme, false for light
  • contrast: Contrast level (-1 to 1; standard values: 0, 0.5, 1)
  • spec: Color specification (use ColorSpecification enum, defaults to MaterialExpressive2025). Read by Expressive, Neutral, TonalSpot and Vibrant only; Chord, Content, Fidelity, FruitSalad, Monochrome and Rainbow discard it and always resolve to MaterialYou2021. See createSchemeSet for why.
  • Returns: A single SchemeColors object with all Material 3 color roles

SchemeSetResult⁠

Result of scheme set generation. Contains one pair of light/dark schemes per requested contrast level.

interface SchemeSetResult {
    schemes: Array<{
        light: SchemeColors;
        dark: SchemeColors;
    }>;
}
content_copy
  • schemes: One entry per requested contrast level, in the same order as the contrasts array.

SchemeColors⁠

All Material Design color roles including severity (information, success, warning). Returned by createSchemeSet(): each scheme contains all roles. Property names are CSS custom property names (kebab-case with --ct-sys-color- prefix).

interface SchemeColors {
    "--ct-sys-color-background": number;
    "--ct-sys-color-error": number;
    "--ct-sys-color-error-container": number;
    "--ct-sys-color-error-dim": number;
    "--ct-sys-color-information": number;
    "--ct-sys-color-information-container": number;
    "--ct-sys-color-inverse-on-surface": number;
    "--ct-sys-color-inverse-primary": number;
    "--ct-sys-color-inverse-surface": number;
    "--ct-sys-color-neutral-palette-key-color": number;
    "--ct-sys-color-neutral-variant-palette-key-color": number;
    "--ct-sys-color-on-background": number;
    "--ct-sys-color-on-error": number;
    "--ct-sys-color-on-error-container": number;
    "--ct-sys-color-on-information": number;
    "--ct-sys-color-on-information-container": number;
    "--ct-sys-color-on-primary": number;
    "--ct-sys-color-on-primary-container": number;
    "--ct-sys-color-on-primary-fixed": number;
    "--ct-sys-color-on-primary-fixed-variant": number;
    "--ct-sys-color-on-secondary": number;
    "--ct-sys-color-on-secondary-container": number;
    "--ct-sys-color-on-secondary-fixed": number;
    "--ct-sys-color-on-secondary-fixed-variant": number;
    "--ct-sys-color-on-success": number;
    "--ct-sys-color-on-success-container": number;
    "--ct-sys-color-on-surface": number;
    "--ct-sys-color-on-surface-variant": number;
    "--ct-sys-color-on-tertiary": number;
    "--ct-sys-color-on-tertiary-container": number;
    "--ct-sys-color-on-tertiary-fixed": number;
    "--ct-sys-color-on-tertiary-fixed-variant": number;
    "--ct-sys-color-on-warning": number;
    "--ct-sys-color-on-warning-container": number;
    "--ct-sys-color-outline": number;
    "--ct-sys-color-outline-variant": number;
    "--ct-sys-color-primary": number;
    "--ct-sys-color-primary-container": number;
    "--ct-sys-color-primary-dim": number;
    "--ct-sys-color-primary-fixed": number;
    "--ct-sys-color-primary-fixed-dim": number;
    "--ct-sys-color-primary-palette-key-color": number;
    "--ct-sys-color-scrim": number;
    "--ct-sys-color-secondary": number;
    "--ct-sys-color-secondary-container": number;
    "--ct-sys-color-secondary-dim": number;
    "--ct-sys-color-secondary-fixed": number;
    "--ct-sys-color-secondary-fixed-dim": number;
    "--ct-sys-color-secondary-palette-key-color": number;
    "--ct-sys-color-shadow": number;
    "--ct-sys-color-success": number;
    "--ct-sys-color-success-container": number;
    "--ct-sys-color-surface": number;
    "--ct-sys-color-surface-bright": number;
    "--ct-sys-color-surface-container": number;
    "--ct-sys-color-surface-container-high": number;
    "--ct-sys-color-surface-container-highest": number;
    "--ct-sys-color-surface-container-low": number;
    "--ct-sys-color-surface-container-lowest": number;
    "--ct-sys-color-surface-dim": number;
    "--ct-sys-color-surface-tint": number;
    "--ct-sys-color-surface-variant": number;
    "--ct-sys-color-tertiary": number;
    "--ct-sys-color-tertiary-container": number;
    "--ct-sys-color-tertiary-dim": number;
    "--ct-sys-color-tertiary-fixed": number;
    "--ct-sys-color-tertiary-fixed-dim": number;
    "--ct-sys-color-tertiary-palette-key-color": number;
    "--ct-sys-color-warning": number;
    "--ct-sys-color-warning-container": number;
}
content_copy

SCHEME_ROLE_COUNT⁠

The number of color roles in one scheme.

const SCHEME_ROLE_COUNT = 70;
content_copy

schemeColorsFromArray⁠

Converts a flat array of ARGB values, 70 per scheme, to a SchemeColors object.

function schemeColorsFromArray(data: Uint32Array, offset?: number): SchemeColors;
content_copy

variantHonorsColorSpecification⁠

Whether variant reads the ColorSpecification a caller passes to createScheme / createSchemeSet, or silently discards it and resolves to MaterialYou2021 regardless of what was passed.

function variantHonorsColorSpecification(variant: ColorThemeVariantType): boolean;
content_copy

Image quantization⁠

Reduce an image to its representative colors, and pick the best seed colors from them.

seedColorFromImage⁠

Get the single best theme seed color from an image.

function seedColorFromImage(image: ImageSource, options?: ImageDecodeOptions): Promise<number>;
content_copy
  • image: Image to process (see ImageSource)
  • options: Decode options (ImageDecodeOptions)
  • Returns: Best ARGB color for theme generation

seedColorFromPixels⁠

Get the single best theme seed color from raw ARGB pixels.

function seedColorFromPixels(pixels: Uint32Array | number[]): number;
content_copy
  • pixels: Array of ARGB colors from the image
  • Returns: Best ARGB color for theme generation

seedColorFromPixelsAsync⁠

seedColorFromPixels, off the main thread. Quantizes, scores and returns the one best seed.

In the browser package only.

function seedColorFromPixelsAsync(pixels: Uint32Array | number[]): Promise<number>;
content_copy
  • pixels: Array of ARGB colors from the image

quantizeAndScore⁠

Quantize and score an image in one call to get the best theme seed colors.

function quantizeAndScore(image: ImageSource, maxColors?: number, desiredCount?: number, options?: ImageDecodeOptions): Promise<Uint32Array>;
content_copy
  • image: Image to process (see ImageSource)
  • maxColors: Maximum colors to use in quantization (typically 128)
  • desiredCount: Number of seed colors to return (typically 1–4)
  • options: Decode options (ImageDecodeOptions)
  • Returns: Array of ARGB colors, best for theming first

quantizeAndScorePixels⁠

Quantize and score raw ARGB pixels in one call to get the best theme seed colors.

function quantizeAndScorePixels(pixels: Uint32Array | number[], maxColors?: number, desiredCount?: number): Uint32Array;
content_copy
  • pixels: Array of ARGB colors from the image
  • maxColors: Maximum colors to use in quantization (typically 128)
  • desiredCount: Number of seed colors to return (typically 1–4)
  • Returns: Array of ARGB colors, best for theming first

quantizeAndScorePixelsAsync⁠

quantizeAndScorePixels, off the main thread. Prefer it to quantizing and scoring separately.

In the browser package only.

function quantizeAndScorePixelsAsync(pixels: Uint32Array | number[], maxColors?: number, desiredCount?: number): Promise<Uint32Array>;
content_copy
  • pixels: Array of ARGB colors from the image
  • maxColors: Maximum colors to use in quantization (typically 128)
  • desiredCount: Number of seed colors to return (typically 1–4)

quantizeImage⁠

Quantize an image to extract representative colors.

function quantizeImage(image: ImageSource, maxColors?: number, options?: ImageDecodeOptions): Promise<QuantizationResult>;
content_copy
  • image: Image to quantize (see ImageSource)
  • maxColors: Maximum number of colors to return (typically 128)
  • options: Decode options (ImageDecodeOptions)
  • Returns: Quantized colors with their pixel populations, most common first

quantizePixels⁠

Quantize raw ARGB pixels to extract representative colors.

function quantizePixels(pixels: Uint32Array | number[], maxColors?: number): QuantizationResult;
content_copy
  • pixels: Array of ARGB colors from the image (one per pixel). Can be Uint32Array or number[]. Transparent pixels (alpha < 255) are ignored.
  • maxColors: Maximum number of colors to return (typically 128)
  • Returns: Quantized colors with their pixel populations, most common first

quantizePixelsAsync⁠

quantizePixels, off the main thread. Tens of milliseconds on a photograph, and the call most worth moving.

In the browser package only.

function quantizePixelsAsync(pixels: Uint32Array | number[], maxColors?: number): Promise<QuantizationResult>;
content_copy
  • pixels: Array of ARGB colors from the image (one per pixel). Can be Uint32Array or number[]. Transparent pixels (alpha < 255) are ignored.
  • maxColors: Maximum number of colors to return (typically 128)

scoreColors⁠

Score quantized colors for their suitability as theme seed colors.

function scoreColors(colors: Uint32Array | number[], populations: Uint32Array | number[], desiredCount?: number): Uint32Array;
content_copy
  • colors: Array of ARGB colors (for example, quantizeImage(...).colors)
  • populations: Pixel count per color (for example, quantizeImage(...).populations)
  • desiredCount: Number of colors to return (typically 4)
  • Returns: Array of top ARGB colors, best first

scoreColorsAsync⁠

scoreColors, off the main thread. Ranks quantized colors by how well they seed a theme.

In the browser package only.

function scoreColorsAsync(colors: Uint32Array | number[], populations: Uint32Array | number[], desiredCount?: number): Promise<Uint32Array>;
content_copy
  • colors: Array of ARGB colors (for example, quantizeImage(...).colors)
  • populations: Pixel count per color (for example, quantizeImage(...).populations)
  • desiredCount: Number of colors to return (typically 4)

pixelsFromImage⁠

Decode an image and return its pixels as an ARGB array ready for quantization.

function pixelsFromImage(image: ImageSource, options?: ImageDecodeOptions): Promise<Uint32Array>;
content_copy
  • image: Image to decode (see ImageSource)
  • options: Decode options (ImageDecodeOptions)
  • Returns: Uint32Array of ARGB pixels

imageDataToArgb⁠

Convert ImageData from a Canvas to an ARGB pixel array.

function imageDataToArgb(imageData: ImageData): Uint32Array;
content_copy
  • imageData: ImageData from CanvasRenderingContext2D.getImageData()
  • Returns: Uint32Array of ARGB pixels

ImageSource⁠

An image in any form the browser can decode or draw.

type ImageSource = Blob | ArrayBuffer | ArrayBufferView | ImageBitmap | ImageData | HTMLImageElement | HTMLCanvasElement | OffscreenCanvas;
content_copy

ImageDecodeOptions⁠

Options for decoding an ImageSource before quantization.

interface ImageDecodeOptions {
    maxDimension?: number;
}
content_copy
  • maxDimension: Longest edge (in pixels) the image is downscaled to before quantization. Quantization quality is insensitive to resolution, so downscaling large photos dramatically reduces work with no visible effect on the resulting theme. Set to 0 to disable downscaling. Default: 128.

QuantizationResult⁠

Result of image quantization containing colors and their populations.

interface QuantizationResult {
    colors: Uint32Array;
    populations: Uint32Array;
}
content_copy
  • colors: Array of quantized ARGB colors, sorted by population (most common first)
  • populations: Pixel count for each color (parallel to colors)

Enums and constants⁠

Named values the functions above take and return.

ColorThemeVariant⁠

Color theme variants: how a scheme is derived from its seed color.

const ColorThemeVariant: {
    readonly Chord: "chord";
    readonly Content: "content";
    readonly Expressive: "expressive";
    readonly Fidelity: "fidelity";
    readonly FruitSalad: "fruit-salad";
    readonly Monochrome: "monochrome";
    readonly Neutral: "neutral";
    readonly Rainbow: "rainbow";
    readonly TonalSpot: "tonal-spot";
    readonly Vibrant: "vibrant";
};
content_copy
  • Chord: Three peer hues: the seed, plus 80 and 160 degrees around the color wheel. Each is carried at the same fraction of its own gamut as the seed, so a muted seed yields a muted scheme.
  • Content: A theme that places the source color in the primaryContainer token.
  • Expressive: A theme that is intentionally detached from the source color.
  • Fidelity: A theme that places the source color in the primaryContainer token.
  • FruitSalad: A playful theme: the source color's hue does not appear in the scheme.
  • Monochrome: A grayscale theme.
  • Neutral: A near grayscale color theme.
  • Rainbow: A playful theme: the source color's hue does not appear in the theme.
  • TonalSpot: A theme with low to medium colorfulness and a Tertiary TonalPalette with a hue related to the source color.
  • Vibrant: A theme that maxes out colorfulness at each position in the Primary Tonal Palette.

ColorThemeVariantType⁠

Type for variables that hold a ColorThemeVariant value.

type ColorThemeVariantType = (typeof ColorThemeVariant)[keyof typeof ColorThemeVariant];
content_copy

ColorSpecification⁠

Material color scheme specifications.

const ColorSpecification: {
    readonly MaterialYou2021: "material-you-2021";
    readonly MaterialExpressive2025: "material-expressive-2025";
};
content_copy
  • MaterialYou2021: The 2021 Material You specification.
  • MaterialExpressive2025: The 2025 Material Expressive specification.

ColorSpecificationType⁠

Type for variables that hold a ColorSpecification value.

type ColorSpecificationType = (typeof ColorSpecification)[keyof typeof ColorSpecification];
content_copy

ContrastLevel⁠

Contrast levels Material specifies.

const ContrastLevel: {
    readonly Standard: 0;
    readonly Medium: 0.5;
    readonly High: 1;
};
content_copy
  • Standard: The contrast the schemes are designed at.
  • Medium: Halfway between standard and high.
  • High: Material's high-contrast scheme.

ContrastLevelType⁠

Type for variables that hold a ContrastLevel value.

type ContrastLevelType = (typeof ContrastLevel)[keyof typeof ContrastLevel];
content_copy

ContrastRange⁠

The inclusive bounds of a contrast value. Beyond them, the contrast stops changing.

const ContrastRange: {
    readonly Minimum: -1;
    readonly Maximum: 1;
};
content_copy
  • Minimum: Lower bound. Below this the curve returns its low anchor unchanged.
  • Maximum: Upper bound. Above this the curve returns its high anchor unchanged.

ContrastValue⁠

A contrast level: a named ContrastLevel member, or any scalar within ContrastRange.

type ContrastValue = ContrastLevelType | number;
content_copy

ContrastMetric⁠

Which reading a ContrastFloor is stated in.

const ContrastMetric: {
    readonly Wcag21: 0;
    readonly ApcaW3cDraft019: 1;
};
content_copy
  • Wcag21: WCAG 2.x ratio over 8-bit sRGB channels, 1 to 21. Symmetric.
  • ApcaW3cDraft019: APCA Lc, W3C draft 0.1.9, 0 to ~106. Text first, then background.

ContrastMetricValue⁠

Type for variables that hold a ContrastMetric value.

type ContrastMetricValue = (typeof ContrastMetric)[keyof typeof ContrastMetric];
content_copy

RoleFallbackMode⁠

What solveRole returns when the walk clears nothing.

const RoleFallbackMode: {
    readonly Fixed: 0;
    readonly BestWcagSoFar: 1;
};
content_copy
  • Fixed: Return the stated color.
  • BestWcagSoFar: Return the evaluated candidate with the highest minimum WCAG ratio.

RoleFallbackModeValue⁠

Type for variables that hold a RoleFallbackMode value.

type RoleFallbackModeValue = (typeof RoleFallbackMode)[keyof typeof RoleFallbackMode];
content_copy

RoleStatus⁠

How a RoleSolution was arrived at.

const RoleStatus: {
    readonly Cleared: 0;
    readonly BestEffort: 1;
    readonly Fallback: 2;
};
content_copy
  • Cleared: A walked candidate cleared every floor against every surface.
  • BestEffort: Nothing cleared; the best candidate seen came back.
  • Fallback: Nothing cleared; the stated fallback color came back.

RoleStatusValue⁠

Type for variables that hold a RoleStatus value.

type RoleStatusValue = (typeof RoleStatus)[keyof typeof RoleStatus];
content_copy

License and setup⁠

Establish the license grant in a build script, and prepare the color utilities ahead of the first call.

ensureGrant⁠

Obtains and verifies the license grant, once per process. Importing the build package already calls it, so a missing or refused grant fails at the import; await it by name where a script wants that step to be explicit.

In the build package only.

function ensureGrant(): Promise<void>;
content_copy

initColorUtilities⁠

Prepares the color utilities ahead of the first call. Optional: every function prepares them on first use, so call this only to move that cost earlier.

In the build package only.

function initColorUtilities(source?: string | WebAssembly.Module): Promise<void>;
content_copy
  • source: A URL to load the compiled color utilities from, or a WebAssembly.Module from compiledColorUtilities. Omit it to use the copy built into the package.

compiledColorUtilities⁠

The compiled color utilities as a WebAssembly.Module, for passing to a worker, which then calls initColorUtilities with it and starts without compiling a second time.

In the build package only.

function compiledColorUtilities(): Promise<WebAssembly.Module>;
content_copy

isInitialized⁠

Whether the color utilities have been prepared, by initColorUtilities or by a first call.

In the build package only.

function isInitialized(): boolean;
content_copy

warmColorUtilities⁠

Runs one throwaway scheme on the worker the *Async functions use, so their first real call is faster. Optional, safe to call more than once, and safe to call anywhere, including at the top of a bundle.

In the browser package only.

function warmColorUtilities(): void;
content_copy

warmColorUtilitiesAsync⁠

Warms the worker the *Async functions use, resolving once it has answered. It never rejects. It doesn't make a synchronous call faster.

In the browser package only.

function warmColorUtilitiesAsync(): Promise<void>;
content_copy