All files / color parseToRgb.js

100% Statements 35/35
100% Branches 14/14
100% Functions 1/1
100% Lines 34/34
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88          18x 18x 18x 18x 18x 18x                           79x 77x 12x           65x 20x           45x 45x 5x           40x 40x 28x             12x 12x 4x 4x 4x 4x 4x 4x           8x 8x 4x 4x 4x 4x 4x 4x             4x        
// @flow
 
import hslToRgb from '../internalHelpers/_hslToRgb'
import type { RgbColor, RgbaColor } from '../types/color'
 
const hexRegex = /^#[a-fA-F0-9]{6}$/
const reducedHexRegex = /^#[a-fA-F0-9]{3}$/
const rgbRegex = /^rgb\((\d{1,3}), ?(\d{1,3}), ?(\d{1,3})\)$/
const rgbaRegex = /^rgba\((\d{1,3}), ?(\d{1,3}), ?(\d{1,3}), ?([-+]?[0-9]*[.]?[0-9]+)\)$/
const hslRegex = /^hsl\((\d{1,3}), ?(\d{1,3})%, ?(\d{1,3})%\)$/
const hslaRegex = /^hsla\((\d{1,3}), ?(\d{1,3})%, ?(\d{1,3})%, ?([-+]?[0-9]*[.]?[0-9]+)\)$/
 
/**
 * Returns an RgbColor or RgbaColor object. This utility function is only useful
 * if want to extract a color component. With the color util `toColorString` you
 * can convert a RgbColor or RgbaColor object back to a string.
 *
 * @example
 * // Assigns `{ red: 255, green: 0, blue: 0 }` to color1
 * const color1 = 'rgb(255, 0, 0)';
 * // Assigns `{ red: 92, green: 102, blue: 112, alpha: 0.75 }` to color2
 * const color2 = 'hsla(210, 10%, 40%, 0.75)';
 */
function parseToRgb(color: string): RgbColor | RgbaColor {
  if (typeof color !== 'string') throw new Error('Passed an incorrect argument to a color function, please pass a string representation of a color.')
  if (color.match(hexRegex)) {
    return {
      red: parseInt(`${color[1]}${color[2]}`, 16),
      green: parseInt(`${color[3]}${color[4]}`, 16),
      blue: parseInt(`${color[5]}${color[6]}`, 16),
    }
  }
  if (color.match(reducedHexRegex)) {
    return {
      red: parseInt(`${color[1]}${color[1]}`, 16),
      green: parseInt(`${color[2]}${color[2]}`, 16),
      blue: parseInt(`${color[3]}${color[3]}`, 16),
    }
  }
  const rgbMatched = rgbRegex.exec(color)
  if (rgbMatched) {
    return {
      red: parseInt(`${rgbMatched[1]}`, 10),
      green: parseInt(`${rgbMatched[2]}`, 10),
      blue: parseInt(`${rgbMatched[3]}`, 10),
    }
  }
  const rgbaMatched = rgbaRegex.exec(color)
  if (rgbaMatched) {
    return {
      red: parseInt(`${rgbaMatched[1]}`, 10),
      green: parseInt(`${rgbaMatched[2]}`, 10),
      blue: parseInt(`${rgbaMatched[3]}`, 10),
      alpha: parseFloat(`${rgbaMatched[4]}`, 10),
    }
  }
  const hslMatched = hslRegex.exec(color)
  if (hslMatched) {
    const hue = parseInt(`${hslMatched[1]}`, 10)
    const saturation = parseInt(`${hslMatched[2]}`, 10) / 100
    const lightness = parseInt(`${hslMatched[3]}`, 10) / 100
    const rgbColorString = `rgb(${hslToRgb(hue, saturation, lightness)})`
    const hslRgbMatched = rgbRegex.exec(rgbColorString)
    return {
      red: parseInt(`${hslRgbMatched[1]}`, 10),
      green: parseInt(`${hslRgbMatched[2]}`, 10),
      blue: parseInt(`${hslRgbMatched[3]}`, 10),
    }
  }
  const hslaMatched = hslaRegex.exec(color)
  if (hslaMatched) {
    const hue = parseInt(`${hslaMatched[1]}`, 10)
    const saturation = parseInt(`${hslaMatched[2]}`, 10) / 100
    const lightness = parseInt(`${hslaMatched[3]}`, 10) / 100
    const rgbColorString = `rgb(${hslToRgb(hue, saturation, lightness)})`
    const hslRgbMatched = rgbRegex.exec(rgbColorString)
    return {
      red: parseInt(`${hslRgbMatched[1]}`, 10),
      green: parseInt(`${hslRgbMatched[2]}`, 10),
      blue: parseInt(`${hslRgbMatched[3]}`, 10),
      alpha: parseFloat(`${hslaMatched[4]}`, 10),
    }
  }
  throw new Error('Couldn\'t parse the color string. Please provide the color as a string in hex, rgb, rgba, hsl or hsla notation.')
}
 
export default parseToRgb