Skip to content

Commit

Permalink
Option to convert hex to rgba in final css
Browse files Browse the repository at this point in the history
  • Loading branch information
origami-z committed Feb 19, 2024
1 parent 47b36b6 commit 563fd6c
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 9 deletions.
55 changes: 49 additions & 6 deletions packages/export-variables-rest-api/src/colorUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,55 @@ export function stringifyRGBA(color: Color) {

// According https://design-tokens.github.io/community-group/format/#color
// Should only use hex
// // To RGBA
// if (a !== 1) {
// return `rgba(${[r, g, b]
// .map((n) => Math.round(n * 255))
// .join(", ")}, ${a.toFixed(4)})`;
// To RGBA
// if ("a" in color) {
// const { r, g, b, a } = color;

// if (a !== 1) {
// return `rgba(${[r, g, b]
// .map((n) => Math.round(n * 255))
// .join(", ")}, ${a.toFixed(4)})`;
// }
// // To RGB
// return `rgb(${[r, g, b].map((n) => Math.round(n * 255)).join(", ")})`;
// }
// // To RGB
// const { r, g, b } = color; // To HEX
// return `rgb(${[r, g, b].map((n) => Math.round(n * 255)).join(", ")})`;
}

const isValidHex = (hex: string) => /^#([A-Fa-f0-9]{3,4}){1,2}$/.test(hex);

const getChunksFromString = (st: string, chunkSize: number) =>
st.match(new RegExp(`.{${chunkSize}}`, "g"));

const convertHexUnitTo256 = (hexStr: string) =>
parseInt(hexStr.repeat(2 / hexStr.length), 16);

const getAlphaFloat = (a: number, alpha?: number) => {
if (typeof a !== "undefined") {
return a / 255;
}
if (typeof alpha != "number" || alpha < 0 || alpha > 1) {
return 1;
}
return alpha;
};

const to2Dp = (num: number) => {
return Number.parseInt((num * 100).toFixed(0)) / 100;
};

/** Based on https://stackoverflow.com/a/53936623 */
export const hexToRGBA = (hex: string, alpha?: number) => {
if (!isValidHex(hex)) {
throw new Error("Invalid HEX");
}
const chunkSize = Math.floor((hex.length - 1) / 3);
const hexArr = getChunksFromString(hex.slice(1), chunkSize);
const [r, g, b, a] = hexArr!.map(convertHexUnitTo256);
const alphaFloat = getAlphaFloat(a, alpha);
if (alphaFloat === 1) {
return `rgb(${r}, ${g}, ${b})`;
}
return `rgba(${r}, ${g}, ${b}, ${to2Dp(alphaFloat)})`;
};
15 changes: 12 additions & 3 deletions packages/export-variables-rest-api/src/tokenUtils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { z } from "zod";
import { toCamelCase } from "./modifyData";
import { hexToRGBA } from "./colorUtils";

export type TokenReservedKey = "$value" | "$type";
const ReferenceToken = z
Expand Down Expand Up @@ -77,7 +78,7 @@ export function generateCssFromJson(
if ($type === "color") {
const css = formatCssLine(
formatCssVarDeclaration(keys, prefix),
formatCssVarColorValue($value, prefix)
formatCssVarColorValue($value, prefix, true)
);
// console.debug("new color css", keys, css);
allCss.push(css);
Expand Down Expand Up @@ -119,12 +120,20 @@ export function formatCssVarDeclaration(
return `--${keysWithPrefix.map(toCamelCase).join("-")}`;
}

export function formatCssVarColorValue(value: string, prefix?: string): string {
export function formatCssVarColorValue(
value: string,
prefix?: string,
rgbaFormat?: boolean
): string {
if (isTokenValueReference(value)) {
return formatCssVarValueReference(value, prefix);
} else {
// assuming hex value already, defined by `ColorToken` regex
return value;
if (rgbaFormat) {
return hexToRGBA(value);
} else {
return value;
}
}
}

Expand Down

0 comments on commit 563fd6c

Please sign in to comment.