Skip to main content

Overview

The ColorUtils class provides a complete suite of color utilities including format conversion (hex, RGB, HSL), color manipulation (lighten, darken, mix), accessibility checks (WCAG contrast), and palette generation. All methods are static and work isomorphically in Node.js and browsers.

Import

import { ColorUtils } from 'bytekit';

Usage

Color Conversion

// Hex to RGB
const rgb = ColorUtils.hexToRgb('#ff5733');
console.log(rgb); // { r: 255, g: 87, b: 51 }

// RGB to Hex
const hex = ColorUtils.rgbToHex(255, 87, 51);
console.log(hex); // '#ff5733'

// Hex to HSL
const hsl = ColorUtils.hexToHsl('#ff5733');
console.log(hsl); // { h: 11, s: 100, l: 60 }

// HSL to Hex
const hexFromHsl = ColorUtils.hslToHex(11, 100, 60);
console.log(hexFromHsl); // '#ff5733'

Color Manipulation

const baseColor = '#3498db';

// Lighten
const lighter = ColorUtils.lighten(baseColor, 20);
console.log(lighter); // Lighter shade

// Darken
const darker = ColorUtils.darken(baseColor, 20);
console.log(darker); // Darker shade

// Saturate/Desaturate
const saturated = ColorUtils.saturate(baseColor, 30);
const desaturated = ColorUtils.desaturate(baseColor, 30);
const grayscale = ColorUtils.grayscale(baseColor);

// Invert
const inverted = ColorUtils.invert(baseColor);

// Complement (opposite on color wheel)
const complement = ColorUtils.complement(baseColor);

// Mix two colors
const mixed = ColorUtils.mix('#ff0000', '#0000ff', 50); // Purple

Accessibility

const bgColor = '#3498db';
const textColor = '#ffffff';

// Calculate contrast ratio
const contrast = ColorUtils.contrast(bgColor, textColor);
console.log(`Contrast ratio: ${contrast.toFixed(2)}:1`);

// Check WCAG compliance
const meetsAA = ColorUtils.meetsContrastAA(bgColor, textColor);
const meetsAAA = ColorUtils.meetsContrastAAA(bgColor, textColor);

console.log(`Meets WCAG AA: ${meetsAA}`);
console.log(`Meets WCAG AAA: ${meetsAAA}`);

// Get best text color for background
const textColorForBg = ColorUtils.textColor('#3498db');
console.log(textColorForBg); // '#ffffff' or '#000000'

// Check if color is light or dark
const isLight = ColorUtils.isLight('#3498db');
const isDark = ColorUtils.isDark('#3498db');

Palette Generation

const baseColor = '#3498db';

// Generate harmonious palette
const palette = ColorUtils.palette(baseColor, 5);
console.log(palette); // Array of 5 colors

// Complementary colors
const complementary = ColorUtils.complementaryPalette(baseColor);
console.log(complementary); // [baseColor, complement]

// Triadic colors
const triadic = ColorUtils.triadicPalette(baseColor);
console.log(triadic); // [baseColor, +120°, +240°]

// Analogous colors
const analogous = ColorUtils.analogousPalette(baseColor, 30);
console.log(analogous); // [baseColor-30°, baseColor, baseColor+30°]

// Gradient
const gradient = ColorUtils.gradient('#ff0000', '#0000ff', 5);
console.log(gradient); // 5 colors from red to blue

// Shades and tints
const shades = ColorUtils.shades(baseColor, 5); // Darker variations
const tints = ColorUtils.tints(baseColor, 5); // Lighter variations

Random Colors

// Random color
const random = ColorUtils.random();
console.log(random); // e.g., '#a3f2b1'

// Random with specific lightness
const lightColor = ColorUtils.randomWithLightness(70); // Light color
const darkColor = ColorUtils.randomWithLightness(30); // Dark color

Parsing

// Parse various formats to hex
ColorUtils.parse('rgb(255, 87, 51)'); // '#ff5733'
ColorUtils.parse('hsl(11, 100%, 60%)'); // '#ff5733'
ColorUtils.parse('#ff5733'); // '#ff5733'
ColorUtils.parse('red'); // '#ff0000'

// Convert to CSS formats
ColorUtils.toCssRgb('#ff5733'); // 'rgb(255, 87, 51)'
ColorUtils.toCssHsl('#ff5733'); // 'hsl(11, 100%, 60%)'

// Validate hex
ColorUtils.isValidHex('#ff5733'); // true
ColorUtils.isValidHex('ff5733'); // false

API Reference

Conversion Methods

hexToRgb

hex
string
required
Hex color string (e.g., ‘#ff5733’ or ‘#f53’)
return
RGB | null
RGB object or null if invalid
interface RGB {
  r: number; // 0-255
  g: number; // 0-255
  b: number; // 0-255
}

hexToRgba

hex
string
required
Hex color with optional alpha (e.g., ‘#ff573380’)
return
RGBA | null
RGBA object or null if invalid
interface RGBA extends RGB {
  a: number; // 0-1
}

rgbToHex

r
number | RGB
required
Red value (0-255) or RGB object
g
number
Green value (0-255)
b
number
Blue value (0-255)
return
string
Hex color string
ColorUtils.rgbToHex(255, 87, 51); // '#ff5733'
ColorUtils.rgbToHex({ r: 255, g: 87, b: 51 }); // '#ff5733'

rgbToHsl / hslToRgb

Similar overloads for RGB ↔ HSL conversion.

Manipulation Methods

lighten / darken

color
string
required
Hex color string
percent
number
required
Percentage to lighten/darken (0-100)
return
string
Modified hex color
ColorUtils.lighten('#3498db', 20); // Lighter
ColorUtils.darken('#3498db', 20); // Darker

saturate / desaturate

color
string
required
Hex color string
percent
number
required
Percentage to adjust saturation
return
string
Modified hex color

mix

color1
string
required
First hex color
color2
string
required
Second hex color
weight
number
default:"50"
Mix weight (0-100), where 0 = all color1, 100 = all color2
return
string
Mixed hex color
ColorUtils.mix('#ff0000', '#0000ff', 50); // Purple
ColorUtils.mix('#ff0000', '#0000ff', 75); // More blue

complement / invert

color
string
required
Hex color string
return
string
Complementary/inverted hex color

Accessibility Methods

contrast

Calculate WCAG contrast ratio between two colors.
color1
string
required
First hex color
color2
string
required
Second hex color
return
number
Contrast ratio (1-21)
ColorUtils.contrast('#000000', '#ffffff'); // 21 (maximum)
ColorUtils.contrast('#777777', '#ffffff'); // ~4.48

meetsContrastAA / meetsContrastAAA

color1
string
required
First color (typically background)
color2
string
required
Second color (typically text)
largeText
boolean
default:"false"
Whether text is large (18pt+ or 14pt+ bold)
return
boolean
True if contrast meets WCAG standard
  • AA: 4.5:1 normal text, 3:1 large text
  • AAA: 7:1 normal text, 4.5:1 large text

textColor

Get optimal text color (black or white) for a background.
backgroundColor
string
required
Background hex color
return
string
‘#000000’ or ‘#ffffff’
ColorUtils.textColor('#3498db'); // '#ffffff'
ColorUtils.textColor('#ecf0f1'); // '#000000'

luminance

Calculate relative luminance (WCAG definition).
color
string
required
Hex color string
return
number
Luminance value (0-1)

isLight / isDark

color
string
required
Hex color string
return
boolean
True if color is light/dark

Generation Methods

palette

baseColor
string
required
Base hex color
count
number
default:"5"
Number of colors to generate
return
string[]
Array of harmonious hex colors

gradient

startColor
string
required
Start hex color
endColor
string
required
End hex color
steps
number
required
Number of gradient steps
return
string[]
Array of gradient colors
const gradient = ColorUtils.gradient('#ff0000', '#0000ff', 5);
// ['#ff0000', '#bf003f', '#7f007f', '#3f00bf', '#0000ff']

shades / tints

baseColor
string
required
Base hex color
count
number
default:"5"
Number of variations
return
string[]
Array of darker (shades) or lighter (tints) colors

Types

interface RGB {
  r: number; // 0-255
  g: number;
  b: number;
}

interface RGBA extends RGB {
  a: number; // 0-1
}

interface HSL {
  h: number; // 0-360
  s: number; // 0-100
  l: number; // 0-100
}

interface HSLA extends HSL {
  a: number; // 0-1
}

Use Cases

Theme Generation

function generateTheme(primaryColor: string) {
  return {
    primary: primaryColor,
    primaryLight: ColorUtils.lighten(primaryColor, 10),
    primaryDark: ColorUtils.darken(primaryColor, 10),
    secondary: ColorUtils.complement(primaryColor),
    text: ColorUtils.textColor(primaryColor),
    shades: ColorUtils.shades(primaryColor, 5),
    tints: ColorUtils.tints(primaryColor, 5)
  };
}

const theme = generateTheme('#3498db');

Accessible Color Picker

function ensureAccessibleColor(
  color: string,
  background: string
): string {
  if (ColorUtils.meetsContrastAA(color, background)) {
    return color;
  }
  
  // Try darkening
  let adjusted = ColorUtils.darken(color, 10);
  if (ColorUtils.meetsContrastAA(adjusted, background)) {
    return adjusted;
  }
  
  // Fallback to optimal text color
  return ColorUtils.textColor(background);
}

Color Palette Builder

class PaletteBuilder {
  constructor(private baseColor: string) {}
  
  complementary() {
    return ColorUtils.complementaryPalette(this.baseColor);
  }
  
  triadic() {
    return ColorUtils.triadicPalette(this.baseColor);
  }
  
  analogous() {
    return ColorUtils.analogousPalette(this.baseColor);
  }
  
  monochromatic() {
    const base = this.baseColor;
    return [
      ColorUtils.darken(base, 20),
      ColorUtils.darken(base, 10),
      base,
      ColorUtils.lighten(base, 10),
      ColorUtils.lighten(base, 20)
    ];
  }
}

Best Practices

  1. Always validate colors before manipulation
  2. Check accessibility for text/background combinations
  3. Use semantic naming for generated colors
  4. Cache conversions for repeated operations
  5. Test on actual devices for color perception