@urvis/color
v0.1.3
Published
A **CSS Color Module 4** toolkit: parse, convert, serialize, gamut-map, interpolate, and analyze colors. A pure, tree-shakeable functional core with an ergonomic, **Temporal-shaped** immutable `Color` class on top.
Readme
@urvis/color
A CSS Color Module 4 toolkit: parse, convert, serialize, gamut-map,
interpolate, and analyze colors. A pure, tree-shakeable functional core with an
ergonomic, Temporal-shaped immutable Color class on top.
Two ways to use it
Import the functions for the smallest bundles (each color space is its own module — unused spaces drop out):
import { parse, convert, serialize } from "@urvis/color";
const c = parse("oklch(0.7 0.15 200)");
serialize(convert(c, "srgb"), "hex"); // "#00b0c4"Import Color for the object API (pulls in the full space registry):
import { Color } from "@urvis/color";
Color.from("#3366cc")
.to("oklch")
.with({ l: 0.8 })
.toGamut("srgb")
.toString("hex");Approximate gzipped cost: sRGB hex round-trip ~0.4 KB, a single space conversion
~0.6 KB, the whole Color class ~8.6 KB.
Spaces (full CSS Color 4)
Named colors, #hex, rgb()/rgba(), hsl(), hwb(), lab(), lch(),
oklab(), oklch(), and color() with srgb, srgb-linear, display-p3,
a98-rgb, prophoto-rgb, rec2020, xyz/xyz-d65, xyz-d50.
All conversions route through an XYZ-D65 hub (Bradford adaptation to/from D50 for Lab/LCH and ProPhoto); the sRGB family (srgb / srgb-linear / hsl / hwb) takes a direct, exact sRGB fast path.
Functional API
- Parse / serialize:
parse,tryParse,serialize - Convert:
convert(color, space) - Gamut:
inGamut(color, dest?),gamutMap(color, dest?)(CSS Color 4 OKLCH chroma-reduction algorithm) - Interpolate:
interpolate(a, b, { space, hue }),mix(a, b, amount?, opts?)(premultiplied alpha; hue methodsshorter/longer/increasing/decreasing) - Analysis:
deltaE(a, b, "76"|"2000"|"ok"),contrast(a, b, { algorithm: "wcag21"|"apca" }) - Manipulate:
lighten,darken,saturate,desaturate,rotateHue,complement,negate,alpha
The Color class
Immutable and frozen; every method returns a new Color.
| Category | Members |
|---|---|
| Construction | new Color(space, coords, alpha?), Color.from, Color.fromHex/fromRgb/fromHsl/fromHwb/fromLab/fromLch/fromOklab/fromOklch/fromXyz |
| Query | .space, .alpha, .coords, .get(channel), .inGamut(dest?) |
| Convert | .to(space), .toGamut(dest?), .toObject() |
| Update | .with({ ...channels, alpha }), .withAlpha(a) |
| Relations | .equals(other, epsilon?), .mix(other, amount?, opts?), .deltaE(other, method?), .contrast(other, opts?) |
| Manipulate | .lighten .darken .saturate .desaturate .rotateHue .complement .negate |
| Serialize | .toString(format?), .toJSON() (round-trips via Color.from), .valueOf() throws |
Deviations from Temporal: no compare() (color has no total order), no
add/subtract (use mix), and channels are read via .get() since they vary
by space.
