Skip to content

Commit

Permalink
Output 4 and 8 digit hex colors
Browse files Browse the repository at this point in the history
  • Loading branch information
omgovich committed May 24, 2021
1 parent dceafe2 commit 0c9e1cd
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 47 deletions.
2 changes: 1 addition & 1 deletion packages/postcss-colormin/src/__tests__/colours.js
Expand Up @@ -20,7 +20,7 @@ test(
test('should convert hsl to keyword', isEqual('hsl(0, 100%, 50%)', 'red'));

test(
'should convert fully oqaque hsl to keyword',
'should convert fully opaque hsl to keyword',
isEqual('hsla(0, 100%, 50%, 1)', 'red')
);

Expand Down
48 changes: 9 additions & 39 deletions packages/postcss-colormin/src/colours.js
@@ -1,45 +1,15 @@
import { colord, extend } from 'colord';
import namesPlugin from 'colord/plugins/names';
import toShorthand from './lib/toShorthand';
import { process } from './lib/color';
import getShortestString from './lib/getShortestString';

extend([namesPlugin]);
export default (input, isLegacy = false) => {
const instance = process(input);

export default (colour, isLegacy = false) => {
const parsed = colord(colour);

if (parsed.isValid()) {
const alpha = parsed.alpha();

if (alpha === 1) {
const toHex = toShorthand(parsed.toHex());
const toName = parsed.toName();
if (toName && toName.length < toHex.length) {
return toName;
} else {
return toHex;
}
} else {
const rgb = parsed.toRgb();

if (!isLegacy && !rgb.r && !rgb.g && !rgb.b && !alpha) {
return 'transparent';
}

let hsla = parsed.toHslString();
let rgba = parsed.toRgbString();

const shortestConversion = hsla.length < rgba.length ? hsla : rgba;

let result;
if (colour.length < shortestConversion.length) {
result = colour;
} else {
result = shortestConversion;
}
return result;
}
if (instance.isValid()) {
// Try to shorten the string if it is a valid CSS color value.
// Fall back to the original input if it's smaller or has equal length/
return getShortestString([input, instance.toShortString({ isLegacy })]);
} else {
// Possibly malformed, so pass through
return colour;
return input;
}
};
54 changes: 54 additions & 0 deletions packages/postcss-colormin/src/lib/color.js
@@ -0,0 +1,54 @@
import { colord, extend, getFormat } from 'colord';
import namesPlugin from 'colord/plugins/names';
import getShortestString from './getShortestString';

let minifierPlugin = (Colord) => {
/**
* Shortens a color to 3 or 4 digit hexadecimal string if it's possible.
* Returns the original (6 or 8 digit) hex if the it can't be shortened.
*/
Colord.prototype.toShortHex = function () {
let hex = this.toHex();
let [, r1, r2, g1, g2, b1, b2, a1, a2] = hex.split('');

// Check if the string can be shorten
if (r1 === r2 && g1 === g2 && b1 === b2) {
if (this.alpha() === 1) {
// Express as 3 digit hexadecimal string if the color doesn't have an alpha channel
return '#' + r1 + g1 + b1;
} else if (a1 === a2) {
// Format 4 digit hex
return '#' + r1 + g1 + b1 + a1;
}
}

return hex;
};

/**
* Returns the shortest representation of a color.
*/
Colord.prototype.toShortString = function ({ isLegacy }) {
let { r, g, b, a } = this.toRgb();

// Hexadecimal, RGB[A] and HSL[A] notations
let options = [this.toShortHex(), this.toRgbString(), this.toHslString()];

// CSS keywords
if (!isLegacy && r === 0 && g === 0 && b === 0 && a === 0) {
options.push('transparent');
} else if (a === 1) {
let name = this.toName();
if (name) {
options.push(name);
}
}

// Look for the shortest option
return getShortestString(options);
};
};

extend([namesPlugin, minifierPlugin]);

export { colord as process, getFormat };
16 changes: 16 additions & 0 deletions packages/postcss-colormin/src/lib/getShortestString.js
@@ -0,0 +1,16 @@
/**
* Returns the shortest string in array
*/
const getShortestString = (strings) => {
let shortest = null;

for (let string of strings) {
if (shortest === null || string.length < shortest.length) {
shortest = string;
}
}

return shortest;
};

export default getShortestString;
7 changes: 0 additions & 7 deletions packages/postcss-colormin/src/lib/toShorthand.js

This file was deleted.

0 comments on commit 0c9e1cd

Please sign in to comment.