DittoTones

repository·main·Indexed 41 days ago

https://github.com/meodai/dittotones

A library that transforms any color into a full, accessible palette by mapping the target hue onto the perceptual DNA (Lightness and Chroma curves in Oklch space) of design systems. Version 0.13.0 includes pre-configured ramps for Tailwind CSS v3 and v4, Radix Colors, Flexoki, Shoelace, and Web Awesome.

Tokens
4.2K
Snippets
17
Records
21
Agent score
99%

What's inside DittoTones

  1. Create custom ramps for DittoTones

    main

    You can use your own design system by providing a Map<string, Ramp>.

    Constraints:

    1. Consistent Keys: All ramps in the Map must share the exact same shade keys. The constructor will throw if they differ.
    2. Neutral Ramp: Include at least one neutral (gray) ramp. If the input color has very low chroma, dittoTones will match it against the least chromatic ramp available.
    import { DittoTones } from 'dittotones';
    import { parse, oklch, type Oklch } from 'culori';
    
    const customRamps = new Map([
      [
        'brand',
        {
          '50': oklch(parse('oklch(98% 0.01 250)')) as Oklch,
          '500': oklch(parse('#3B82F6')) as Oklch,
          '950': oklch(parse('oklch(25% 0.05 250)')) as Oklch,
        },
      ],
    ]);
    
    const ditto = new DittoTones({ ramps: customRamps });
  2. Install dittoTones

    main

    Install the dittotones library via npm to transform any color into a full palette based on the perceptual DNA of a design system.

    npm install dittotones
  3. Understand the Ramp data structure

    main

    A Ramp is a type definition representing a collection of color steps. It is a Record<string, Oklch> where:

    • The key is a string representing the step number (e.g., '1', '2', ..., '12').
    • The value is an Oklch object (from the culori library) representing the color at that step.

    This structure allows for easy programmatic access to color scales by step index.

  4. Configure DittoTones options

    main

    When instantiating DittoTones, you can pass an options object to customize the generation behavior:

    • ramps: A Map<string, Ramp> of reference palettes.
    • preserveHueOffsets (boolean): If true, preserves hue shifts from reference ramps across the scale (e.g., if a design system's dark shades shift toward purple). Defaults to false.
    • gamutMap (boolean): If true, maps output colors to the sRGB gamut by reducing chroma to prevent out-of-gamut colors when converting to hex. Defaults to true.
    const ditto = new DittoTones({
      ramps: myRamps,
      preserveHueOffsets: true,
      gamutMap: false,
    });
  5. Use the DittoTones API to generate a color palette

    main

    To generate a palette, instantiate DittoTones with a set of reference ramps, then call .generate(color) with your target color. The result contains a scale object where keys are shade names (e.g., '50', '500') and values are Oklch color objects. You can use the culori library to format these objects into CSS or Hex strings.

    import { DittoTones } from 'dittotones';
    import { tailwindRamps } from 'dittotones/ramps/tailwind';
    import { formatCss, formatHex } from 'culori';
    
    const ditto = new DittoTones({ ramps: tailwindRamps });
    
    const result = ditto.generate('#F97316');
    
    // result.scale contains Oklch color objects
    for (const [shade, color] of Object.entries(result.scale)) {
      console.log(`${shade}: ${formatHex(color)}`);
      // 500: #f97316
    }
    
    // Or keep them as CSS oklch() strings:
    for (const [shade, color] of Object.entries(result.scale)) {
      console.log(`${shade}: ${formatCss(color)}`);
    }
  6. Understand the GenerateResult object

    main

    The .generate() method returns a GenerateResult object containing details about the input and the generated scale:

    • inputColor: The parsed Oklch version of your input.
    • matchedShade: The string key of the shade that most closely matched your input (e.g., `
  7. Reference of bundled ramps

    main

    The following design systems are available as bundled ramps:

    ImportDesign systemRampsShade keys
    dittotones/ramps/tailwindTailwind CSS v42250–950 (11 steps)
    dittotones/ramps/tailwind-v3Tailwind CSS v32250–950 (11 steps)
    dittotones/ramps/radixRadix Colors311–12
    dittotones/ramps/flexokiFlexoki950–950 (13 steps)
    dittotones/ramps/shoelaceShoelace1005–95
    dittotones/ramps/wa-defaultWeb Awesome (default)1005–95
    dittotones/ramps/wa-brightWeb Awesome (bright)1005–95
  8. Import bundled design system ramps

    main

    dittoTones provides pre-configured ramps for several design systems as subpaths. Importing via subpaths ensures you only bundle the data you actually use.

    import { tailwindRamps } from 'dittotones/ramps/tailwind';
    import { radixRamps } from 'dittotones/ramps/radix';
    import flexokiRamps from 'dittotones/ramps/flexoki'; // default export works too
  9. Use pre-configured Radix color ramps via radixRamps

    main

    The radixRamps constant provides a collection of pre-configured color ramps based on the Radix color system. It is exported as a Map<string, Ramp>, where each key is a color name and the value is a Ramp object containing OKLCH color values indexed by their step number (e.g., '1' through '12').

    Available color keys include:

    • Neutrals: gray, mauve, slate, sage, olive, sand
    • Warm/Red tones: tomato, red, ruby, crimson, pink, plum
    • Purples/Blues: purple, violet, iris, indigo, blue, cyan
    • Greens/Teals: teal, jade, green, grass, mint, lime
    • Earth/Yellow/Orange: bronze, gold, brown, sky, yellow, amber, orange
    import radixRamps from './ramps/radix';
    
    // Access a specific color ramp
    const blueRamp = radixRamps.get('blue');
    
    if (blueRamp) {
      // Access a specific step in the ramp (e.g., step 1 or 12)
      const step1 = blueRamp['1'];
      const step12 = blueRamp['12'];
      console.log(step1);
    }
  10. Use the pre-configured Shoelace color ramps

    main

    The shoelaceRamps constant provides a collection of pre-configured color ramps based on the Shoelace design system. It is exported as a Map<string, Ramp>, where each key in the map corresponds to a color name (from shoelaceColors) and the value is a Ramp object. A Ramp is a record mapping shade names (strings) to Oklch color objects.

    To use these ramps, iterate over the map or access specific color ramps by their key name.

    import shoelaceRamps from './ramps/shoelace';
    
    // Access a specific ramp by its key (e.g., 'blue')
    const blueRamp = shoelaceRamps.get('blue');
    
    if (blueRamp) {
      // Access a specific shade within the ramp
      const shade500 = blueRamp['500'];
      console.log(shade500);
    }
  11. Generate a color scale with generate()

    main

    The generate(color: string) method takes a color string (e.g., CSS color, hex, or oklch string) and returns a GenerateResult. It finds the closest matching shade and ramp(s) to create a new, re-scaled color palette that matches the input color's lightness and chroma.

    Return Value: GenerateResult

    • inputColor: The parsed Oklch representation of the input.
    • matchedShade: The name of the shade (key) that best matched the input.
    • method: The matching strategy used: 'exact', 'single', or 'blend'.
    • sources: An array of { name: string; diff: number; weight: number } describing which ramps contributed to the result.
    • scale: A Record<string, Oklch> containing the newly generated color scale using the original shade keys.
    const result = dt.generate('oklch(0.5 0.1 250)');
    
    console.log(result.matchedShade); // e.g., '500'
    console.log(result.scale);        // { '100': Oklch, '500': Oklch, ... }
  12. Use the pre-configured tailwindV3Ramps color ramps

    main

    The tailwindV3Ramps constant provides a collection of pre-configured color ramps based on Tailwind CSS v3 color palettes. Each entry in the Map is keyed by the color name (e.g., 'blue', 'red') and contains a Ramp object where keys are shade identifiers (e.g., '50', '500', '900') and values are Oklch color objects. This is useful for applying Tailwind-inspired color scales using OKLCH color space logic.

    import tailwindV3Ramps from './src/ramps/tailwind-v3';
    
    // Access a specific color ramp
    const blueRamp = tailwindV3Ramps.get('blue');
    
    if (blueRamp) {
      const shade500 = blueRamp['500'];
      console.log(shade500); // Returns an Oklch object
    }