{"version":3,"sources":["../src/index.ts"],"names":["roundNumber","value","__name","roundObjectValuesNumber","obj","cur","key","k","colorAlphaToHex","val","getColorFormat","color","analyzeColorBase","c","Color","rgb","rgbInfo","isTransparent","rgbString","hsl","hslInfo","hslString","hex","e","analyzeColor","loMemo","isColor","assertColor","getColorRgbInfo","getColorHslInfo","hasOpacity","getColorLuminosity","isDarkColor","isLightColor","convertColor","format","convertTransparentColorToHex","isColorContrastEnough","foregroundColor","bgColor","f","b"],"mappings":"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","file":"index.mjs","sourcesContent":["import Color from 'color';\nimport loMemo from 'lodash/memoize.js';\n// need to leave this imported even though it doesn't look like it's being used for proper typing of `lodash/memoize`\n\nexport type ColorRgbInfo = {\n  /** From 0 - 255 */\n  r: number;\n  /** From 0 - 255 */\n  g: number;\n  /** From 0 - 255 */\n  b: number;\n  /** From 0 - 1 */\n  alpha?: number;\n};\n\nexport type ColorHslInfo = {\n  /** From 0 - 255 */\n  h: number;\n  /** From 0 - 255 */\n  s: number;\n  /** From 0 - 255 */\n  l: number;\n  /** From 0 - 1 */\n  alpha?: number;\n};\n\nexport type ColorFormat = 'hex' | 'hsl' | 'rgb';\n\n/**\n * If a number is less than 1, round it to a hundredth (i.e. 0.87), else round to nearest integer.\n */\nfunction roundNumber(value: number): number {\n  return value < 1 ? Number(value.toFixed(2)) : Math.round(value);\n}\n\nfunction roundObjectValuesNumber<Obj extends Record<string, number>>(\n  obj: Obj,\n): Record<keyof Obj, number> {\n  return Object.entries(obj).reduce(\n    (cur, [key, value]) => {\n      const k = key as keyof Obj;\n      cur[k] = roundNumber(value);\n      return cur;\n    },\n    {} as Record<keyof Obj, number>,\n  );\n}\n\n/**\n * Convert a transparency to the 7th & 8th character for an 8 digit hex color\n * @link https://gist.github.com/lopspower/03fb1cc0ac9f32ef38f4\n */\nfunction colorAlphaToHex(value: number): string {\n  let val = Math.max(0, value);\n  val = Math.min(val, 255);\n  val = Math.ceil(val);\n  return (\n    '0123456789ABCDEF'.charAt((val - (val % 16)) / 16) +\n    '0123456789ABCDEF'.charAt(val % 16)\n  );\n}\n\nfunction getColorFormat(color: string): ColorFormat | null {\n  if (color.startsWith('#')) return 'hex';\n  if (color.startsWith('rgb')) return 'rgb';\n  if (color.startsWith('hsl')) return 'hsl';\n  return null;\n}\n\nfunction analyzeColorBase(color: string) {\n  try {\n    const c = Color(color);\n    const rgb = c.rgb();\n    const rgbInfo = roundObjectValuesNumber(\n      rgb.object() as unknown as ColorRgbInfo,\n    );\n    const isTransparent =\n      typeof rgbInfo.alpha === 'number' && rgbInfo.alpha !== 1;\n    const rgbString = isTransparent\n      ? `rgba(${rgbInfo.r}, ${rgbInfo.g}, ${rgbInfo.b}, ${rgbInfo.alpha})`\n      : `rgb(${rgbInfo.r}, ${rgbInfo.g}, ${rgbInfo.b})`;\n    const hsl = c.hsl();\n    const hslInfo = roundObjectValuesNumber(\n      hsl.object() as unknown as ColorHslInfo,\n    );\n    const hslString = isTransparent\n      ? `hsla(${hslInfo.h}, ${hslInfo.s}%, ${hslInfo.l}%, ${hslInfo.alpha})`\n      : `hsl(${hslInfo.h}, ${hslInfo.s}%, ${hslInfo.l}%)`;\n    let hex = c.hex();\n    if (isTransparent) {\n      // 6 => 8 character transparent hex\n      hex = `${hex}${colorAlphaToHex(rgbInfo.alpha * 256)}`;\n    }\n    return {\n      original: color,\n      format: getColorFormat(color),\n      rgbInfo,\n      rgbString,\n      hslInfo,\n      hslString,\n      hex,\n      isTransparent,\n      luminosity: c.luminosity(),\n      isDark: c.isDark(),\n      isLight: c.isLight(),\n      color: c,\n    };\n  } catch (e) {\n    throw new Error(\n      `Could not analyze the color \"${color}\" - ${\n        e instanceof Error ? e.message : ''\n      }`,\n    );\n  }\n}\n\nexport const analyzeColor = loMemo(analyzeColorBase);\n\n/**\n * Is a valid css color\n */\nexport function isColor(color: string): boolean {\n  try {\n    analyzeColor(color);\n    return true;\n  } catch (e) {\n    return false;\n  }\n}\n\nexport function assertColor(color: string): asserts color is string {\n  analyzeColor(color);\n}\n\n/**\n * @deprecated - use `analyzeColor`\n * @see analyzeColor\n */\nexport function getColorRgbInfo(color: string): ColorRgbInfo {\n  return analyzeColor(color).rgbInfo;\n}\n\n/**\n * @deprecated - use `analyzeColor`\n * @see analyzeColor\n */\nexport function getColorHslInfo(color: string): ColorHslInfo {\n  return analyzeColor(color).hslInfo;\n}\n\n/**\n * Has Opacity\n * Returns true if a color has opacity\n * @deprecated - use `analyzeColor`\n * @see analyzeColor\n */\nexport function hasOpacity(color: string): boolean {\n  return !analyzeColor(color).isTransparent;\n}\n\n/**\n * @deprecated - use `analyzeColor`\n * @see analyzeColor\n */\nexport function getColorLuminosity(color: string): number {\n  return analyzeColor(color).luminosity;\n}\n\n/**\n * Color Contrast\n * @deprecated - use `analyzeColor`\n * @see analyzeColor\n * @param color - color value to check. supports any number of formats (hex, rgb, hsl, etc)\n * @returns {boolean} - true if the color is \"dark\" (ie. you should use a lighter color on top) and false if the color is light.\n */\nexport function isDarkColor(color: string): boolean {\n  return analyzeColor(color).isDark;\n}\n\n/**\n * Color Contrast\n * @deprecated - use `analyzeColor`\n * @see analyzeColor\n * @param color - color value to check. supports any number of formats (hex, rgb, hsl, etc)\n * @returns {boolean} - true if the color is \"light\" (ie. you should use a darker color on top) and false if the color is dark.\n */\nexport function isLightColor(color: string): boolean {\n  return analyzeColor(color).isLight;\n}\n\n/**\n * @deprecated - use `analyzeColor`\n * @see analyzeColor\n */\nexport function convertColor({\n  color,\n  format,\n}: {\n  color: string;\n  format: ColorFormat;\n}): string {\n  assertColor(color);\n  switch (format) {\n    case 'rgb': {\n      const rgb = getColorRgbInfo(color);\n      return Color(rgb).string();\n    }\n    case 'hsl': {\n      const hsl = getColorHslInfo(color);\n      return Color(hsl).string();\n    }\n    case 'hex':\n    default:\n      return Color(color).hex();\n  }\n}\n\n/**\n * @deprecated - use `analyzeColor`\n * @see analyzeColor\n */\nexport function convertTransparentColorToHex(color: string): string {\n  return analyzeColor(color).hex;\n}\n\n/**\n * Contrast checking.\n *\n * IMPORTANT: CANNOT USE ALPHA CHANNELS IN CONTRAST CALCULATIONS.\n * This can only compare 2 SOLID colors.\n */\nexport function isColorContrastEnough({\n  foregroundColor,\n  bgColor,\n}: {\n  foregroundColor: string;\n  bgColor: string;\n}): boolean {\n  const f = analyzeColor(foregroundColor);\n  const b = analyzeColor(bgColor);\n\n  // https://www.w3.org/TR/WCAG20/#contrast-ratiodef\n  // (L1 + 0.05) / (L2 + 0.05), where\n  // L1 is the relative luminance of the lighter of the colors, and\n  // L2 is the relative luminance of the darker of the colors.\n  const contrast = f.color.contrast(b.color);\n\n  // https://webaim.org/resources/contrastchecker/\n  return contrast >= 4.5;\n}\n"]}