omgovich / colord

👑 A tiny yet powerful tool for high-performance color manipulations and conversions
https://colord.omgovich.ru
MIT License
1.67k stars 49 forks source link

Support hex codes without the # #66

Closed marcofugaro closed 3 years ago

marcofugaro commented 3 years ago

Hey! Love this library! We're using it to handle a color picker component!

The user has an input to write an hex color in, and then we pass it to colord:

colord('#f00')

We are using the names plugin as well, to let the user input css names:

colord('red')

However we wanted the user to be able to type hex strings without the # as well, and we're having trouble doing this because we can't just slap # at the start of the string since the color could be a name as well.

colord('f00') // ==> currently invalid color

Would be awesome if colord would support this usecase as well, maybe with a plugin?

omgovich commented 3 years ago

Hi! Previously (in v1.x) Colord worked as you described, but this behavior causes a lot of weird errors in many projects, so since v2 Colord strictly follows CSS <color> specs. According to the specs, hexadecimal colors must have # prefix.

The easiest way for you is to use Colord v1.7.2.

Or you can define your own local plugin:

// utils/colord.js
import { colord, extend } from 'colord';
import namesPlugin from 'colord/plugins/names';

const lazyHexMatcher = /^([0-9a-f]{3,6})$/i;

const parseLazyHex = (value: string) => {
  const match = lazyHexMatcher.exec(value);

  if (!match) return null;

  const hex = match[1];

  if (hex.length === 3) {
    return {
      r: parseInt(hex[0] + hex[0], 16),
      g: parseInt(hex[1] + hex[1], 16),
      b: parseInt(hex[2] + hex[2], 16),
      a: 1,
    };
  }

  if (hex.length === 6) {
    return {
      r: parseInt(hex.substr(0, 2), 16),
      g: parseInt(hex.substr(2, 2), 16),
      b: parseInt(hex.substr(4, 2), 16),
      a: 1,
    };
  }

  return null;
};

const lazyHexPlugin = (ColordClass, parsers) => {
  parsers.string.push([parseLazyHex, "hex"]);
};

extend([lazyHexPlugin, namesPlugin])

export * from 'colord'
// anyOtherFile.js
import { colord } from "./utils/colord.js"

colord('fff').toHslString() // "hls(0, 0%, 100%)"
marcofugaro commented 3 years ago

Thanks! Any chance you can make this into an importable plugin as well? It's a feature that was dropped, would be useful if it was at least optional.

omgovich commented 3 years ago

We're trying to be focused on the CSS specs, so providing any logic that doesn't follow those rules might mislead the developers using the library and cause errors in their projects. We already had pretty big issues in the past because of the lazy parsing, so I think we not having non-strict hex parsing in plans at the moment.

marcofugaro commented 3 years ago

Got it, thanks for the plugin!