@webstudio-is/css-engine 0.257.0 → 0.258.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +132 -5
- package/lib/runtime.js +7 -1
- package/lib/types/color.d.ts +14 -0
- package/lib/types/color.test.d.ts +1 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/schema.d.ts +1 -1
- package/package.json +3 -2
package/lib/index.js
CHANGED
|
@@ -90,6 +90,12 @@ var toValue = (styleValue, transformValue) => {
|
|
|
90
90
|
let [c1, c2, c3] = value.components;
|
|
91
91
|
const alpha = typeof value.alpha === "number" ? value.alpha : toValue(value.alpha);
|
|
92
92
|
switch (value.colorSpace) {
|
|
93
|
+
case "hex": {
|
|
94
|
+
const toHex = (v) => Math.round(Math.min(Math.max(v, 0), 1) * 255).toString(16).padStart(2, "0");
|
|
95
|
+
const hex = `#${toHex(c1)}${toHex(c2)}${toHex(c3)}`;
|
|
96
|
+
const alphaNum = typeof alpha === "number" ? alpha : 1;
|
|
97
|
+
return alphaNum < 1 ? hex + toHex(alphaNum) : hex;
|
|
98
|
+
}
|
|
93
99
|
case "srgb": {
|
|
94
100
|
c1 = Math.round(c1 * 255);
|
|
95
101
|
c2 = Math.round(c2 * 255);
|
|
@@ -109,7 +115,7 @@ var toValue = (styleValue, transformValue) => {
|
|
|
109
115
|
case "oklch":
|
|
110
116
|
return `oklch(${c1} ${c2} ${c3} / ${alpha})`;
|
|
111
117
|
// Fall back to color() function for less common color spaces.
|
|
112
|
-
//
|
|
118
|
+
// colorjs uses internal short names that differ from CSS predefined color space identifiers.
|
|
113
119
|
case "p3":
|
|
114
120
|
return `color(display-p3 ${c1} ${c2} ${c3} / ${alpha})`;
|
|
115
121
|
case "a98rgb":
|
|
@@ -212,6 +218,7 @@ var ColorValue = z.object({
|
|
|
212
218
|
type: z.literal("color"),
|
|
213
219
|
// all these color spaces are defined by design tokens specification
|
|
214
220
|
colorSpace: z.union([
|
|
221
|
+
z.literal("hex"),
|
|
215
222
|
z.literal("srgb"),
|
|
216
223
|
z.literal("p3"),
|
|
217
224
|
z.literal("srgb-linear"),
|
|
@@ -371,12 +378,12 @@ var isLonghandValue = (value) => {
|
|
|
371
378
|
var mergeBorder = (styleMap, base) => {
|
|
372
379
|
const width = styleMap.get(`${base}-width`);
|
|
373
380
|
const style = styleMap.get(`${base}-style`);
|
|
374
|
-
const
|
|
375
|
-
if (isLonghandValue(width) && isLonghandValue(style) && isLonghandValue(
|
|
381
|
+
const color2 = styleMap.get(`${base}-color`);
|
|
382
|
+
if (isLonghandValue(width) && isLonghandValue(style) && isLonghandValue(color2)) {
|
|
376
383
|
styleMap.delete(`${base}-width`);
|
|
377
384
|
styleMap.delete(`${base}-style`);
|
|
378
385
|
styleMap.delete(`${base}-color`);
|
|
379
|
-
styleMap.set(base, { type: "tuple", value: [width, style,
|
|
386
|
+
styleMap.set(base, { type: "tuple", value: [width, style, color2] });
|
|
380
387
|
}
|
|
381
388
|
};
|
|
382
389
|
var mergeBox = (styleMap, base) => {
|
|
@@ -1058,6 +1065,116 @@ var generateAtomic = (sheet, options) => {
|
|
|
1058
1065
|
});
|
|
1059
1066
|
return { cssText, classes };
|
|
1060
1067
|
};
|
|
1068
|
+
|
|
1069
|
+
// src/color.ts
|
|
1070
|
+
import * as colorjs from "colorjs.io/fn";
|
|
1071
|
+
colorjs.ColorSpace.register(colorjs.sRGB);
|
|
1072
|
+
colorjs.ColorSpace.register(colorjs.sRGB_Linear);
|
|
1073
|
+
colorjs.ColorSpace.register(colorjs.HSL);
|
|
1074
|
+
colorjs.ColorSpace.register(colorjs.HWB);
|
|
1075
|
+
colorjs.ColorSpace.register(colorjs.Lab);
|
|
1076
|
+
colorjs.ColorSpace.register(colorjs.LCH);
|
|
1077
|
+
colorjs.ColorSpace.register(colorjs.OKLab);
|
|
1078
|
+
colorjs.ColorSpace.register(colorjs.OKLCH);
|
|
1079
|
+
colorjs.ColorSpace.register(colorjs.P3);
|
|
1080
|
+
colorjs.ColorSpace.register(colorjs.A98RGB);
|
|
1081
|
+
colorjs.ColorSpace.register(colorjs.ProPhoto);
|
|
1082
|
+
colorjs.ColorSpace.register(colorjs.REC_2020);
|
|
1083
|
+
colorjs.ColorSpace.register(colorjs.XYZ_D65);
|
|
1084
|
+
colorjs.ColorSpace.register(colorjs.XYZ_D50);
|
|
1085
|
+
colorjs.ColorSpace.registry["display-p3"] = colorjs.P3;
|
|
1086
|
+
colorjs.ColorSpace.registry["a98-rgb"] = colorjs.A98RGB;
|
|
1087
|
+
colorjs.ColorSpace.registry["prophoto-rgb"] = colorjs.ProPhoto;
|
|
1088
|
+
var color = colorjs;
|
|
1089
|
+
var registeredSpaces = /* @__PURE__ */ new Map([
|
|
1090
|
+
[colorjs.sRGB, "srgb"],
|
|
1091
|
+
[colorjs.sRGB_Linear, "srgb-linear"],
|
|
1092
|
+
[colorjs.HSL, "hsl"],
|
|
1093
|
+
[colorjs.HWB, "hwb"],
|
|
1094
|
+
[colorjs.Lab, "lab"],
|
|
1095
|
+
[colorjs.LCH, "lch"],
|
|
1096
|
+
[colorjs.OKLab, "oklab"],
|
|
1097
|
+
[colorjs.OKLCH, "oklch"],
|
|
1098
|
+
[colorjs.P3, "p3"],
|
|
1099
|
+
[colorjs.A98RGB, "a98rgb"],
|
|
1100
|
+
[colorjs.ProPhoto, "prophoto"],
|
|
1101
|
+
[colorjs.REC_2020, "rec2020"],
|
|
1102
|
+
[colorjs.XYZ_D65, "xyz-d65"],
|
|
1103
|
+
[colorjs.XYZ_D50, "xyz-d50"]
|
|
1104
|
+
]);
|
|
1105
|
+
var toColorSpace = (space) => {
|
|
1106
|
+
const id = registeredSpaces.get(space);
|
|
1107
|
+
if (id === void 0) {
|
|
1108
|
+
throw new Error(`Unregistered color space: ${space.id}`);
|
|
1109
|
+
}
|
|
1110
|
+
return id;
|
|
1111
|
+
};
|
|
1112
|
+
var toColorComponent = (value) => Math.round((value ?? 0) * 1e4) / 1e4;
|
|
1113
|
+
var srgbColor = (r, g, b, alpha = 1) => ({
|
|
1114
|
+
space: colorjs.sRGB,
|
|
1115
|
+
coords: [r, g, b],
|
|
1116
|
+
alpha
|
|
1117
|
+
});
|
|
1118
|
+
var transparentColor = srgbColor(0, 0, 0, 0);
|
|
1119
|
+
var whiteColor = srgbColor(1, 1, 1, 1);
|
|
1120
|
+
var resolveColorViaCanvas = (colorString) => {
|
|
1121
|
+
if (typeof document === "undefined") {
|
|
1122
|
+
return;
|
|
1123
|
+
}
|
|
1124
|
+
const canvas = document.createElement("canvas");
|
|
1125
|
+
canvas.width = 1;
|
|
1126
|
+
canvas.height = 1;
|
|
1127
|
+
const ctx = canvas.getContext("2d");
|
|
1128
|
+
if (!ctx) {
|
|
1129
|
+
return;
|
|
1130
|
+
}
|
|
1131
|
+
ctx.fillStyle = colorString;
|
|
1132
|
+
ctx.fillRect(0, 0, 1, 1);
|
|
1133
|
+
const [r, g, b, a] = ctx.getImageData(0, 0, 1, 1).data;
|
|
1134
|
+
return srgbColor(
|
|
1135
|
+
(r ?? 0) / 255,
|
|
1136
|
+
(g ?? 0) / 255,
|
|
1137
|
+
(b ?? 0) / 255,
|
|
1138
|
+
(a ?? 255) / 255
|
|
1139
|
+
);
|
|
1140
|
+
};
|
|
1141
|
+
var parseColor = (cssString) => {
|
|
1142
|
+
try {
|
|
1143
|
+
return colorjs.to(cssString, "srgb");
|
|
1144
|
+
} catch {
|
|
1145
|
+
return resolveColorViaCanvas(cssString) ?? transparentColor;
|
|
1146
|
+
}
|
|
1147
|
+
};
|
|
1148
|
+
var colorDistance = (a, b) => {
|
|
1149
|
+
const [ar, ag, ab] = a.coords;
|
|
1150
|
+
const [br, bg, bb] = b.coords;
|
|
1151
|
+
return Math.sqrt(
|
|
1152
|
+
((ar ?? 0) - (br ?? 0)) ** 2 + ((ag ?? 0) - (bg ?? 0)) ** 2 + ((ab ?? 0) - (bb ?? 0)) ** 2 + ((a.alpha ?? 1) - (b.alpha ?? 1)) ** 2
|
|
1153
|
+
);
|
|
1154
|
+
};
|
|
1155
|
+
var lerpColor = (a, b, ratio) => {
|
|
1156
|
+
const lerp = (start, end, t) => start * (1 - t) + end * t;
|
|
1157
|
+
return {
|
|
1158
|
+
space: a.space,
|
|
1159
|
+
coords: [
|
|
1160
|
+
lerp(a.coords[0] ?? 0, b.coords[0] ?? 0, ratio),
|
|
1161
|
+
lerp(a.coords[1] ?? 0, b.coords[1] ?? 0, ratio),
|
|
1162
|
+
lerp(a.coords[2] ?? 0, b.coords[2] ?? 0, ratio)
|
|
1163
|
+
],
|
|
1164
|
+
alpha: lerp(a.alpha ?? 1, b.alpha ?? 1, ratio)
|
|
1165
|
+
};
|
|
1166
|
+
};
|
|
1167
|
+
var serializeColor = (color2) => {
|
|
1168
|
+
const [r, g, b] = color2.coords;
|
|
1169
|
+
const red = Math.round((r ?? 0) * 255);
|
|
1170
|
+
const green = Math.round((g ?? 0) * 255);
|
|
1171
|
+
const blue = Math.round((b ?? 0) * 255);
|
|
1172
|
+
const alpha = color2.alpha ?? 1;
|
|
1173
|
+
if (alpha < 1) {
|
|
1174
|
+
return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
|
|
1175
|
+
}
|
|
1176
|
+
return `rgb(${red}, ${green}, ${blue})`;
|
|
1177
|
+
};
|
|
1061
1178
|
export {
|
|
1062
1179
|
ColorValue,
|
|
1063
1180
|
FakeStyleElement,
|
|
@@ -1074,6 +1191,8 @@ export {
|
|
|
1074
1191
|
UnitValue,
|
|
1075
1192
|
UnparsedValue,
|
|
1076
1193
|
VarFallback,
|
|
1194
|
+
color,
|
|
1195
|
+
colorDistance,
|
|
1077
1196
|
compareMedia,
|
|
1078
1197
|
createRegularStyleSheet,
|
|
1079
1198
|
cssWideKeywords,
|
|
@@ -1082,9 +1201,17 @@ export {
|
|
|
1082
1201
|
generateAtomic,
|
|
1083
1202
|
generateStyleMap,
|
|
1084
1203
|
hyphenateProperty,
|
|
1204
|
+
lerpColor,
|
|
1085
1205
|
matchMedia,
|
|
1086
1206
|
mergeStyles,
|
|
1207
|
+
parseColor,
|
|
1087
1208
|
prefixStyles,
|
|
1209
|
+
serializeColor,
|
|
1210
|
+
srgbColor,
|
|
1211
|
+
toColorComponent,
|
|
1212
|
+
toColorSpace,
|
|
1088
1213
|
toValue,
|
|
1089
|
-
toVarFallback
|
|
1214
|
+
toVarFallback,
|
|
1215
|
+
transparentColor,
|
|
1216
|
+
whiteColor
|
|
1090
1217
|
};
|
package/lib/runtime.js
CHANGED
|
@@ -63,6 +63,12 @@ var toValue = (styleValue, transformValue) => {
|
|
|
63
63
|
let [c1, c2, c3] = value.components;
|
|
64
64
|
const alpha = typeof value.alpha === "number" ? value.alpha : toValue(value.alpha);
|
|
65
65
|
switch (value.colorSpace) {
|
|
66
|
+
case "hex": {
|
|
67
|
+
const toHex = (v) => Math.round(Math.min(Math.max(v, 0), 1) * 255).toString(16).padStart(2, "0");
|
|
68
|
+
const hex = `#${toHex(c1)}${toHex(c2)}${toHex(c3)}`;
|
|
69
|
+
const alphaNum = typeof alpha === "number" ? alpha : 1;
|
|
70
|
+
return alphaNum < 1 ? hex + toHex(alphaNum) : hex;
|
|
71
|
+
}
|
|
66
72
|
case "srgb": {
|
|
67
73
|
c1 = Math.round(c1 * 255);
|
|
68
74
|
c2 = Math.round(c2 * 255);
|
|
@@ -82,7 +88,7 @@ var toValue = (styleValue, transformValue) => {
|
|
|
82
88
|
case "oklch":
|
|
83
89
|
return `oklch(${c1} ${c2} ${c3} / ${alpha})`;
|
|
84
90
|
// Fall back to color() function for less common color spaces.
|
|
85
|
-
//
|
|
91
|
+
// colorjs uses internal short names that differ from CSS predefined color space identifiers.
|
|
86
92
|
case "p3":
|
|
87
93
|
return `color(display-p3 ${c1} ${c2} ${c3} / ${alpha})`;
|
|
88
94
|
case "a98rgb":
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as colorjs from "colorjs.io/fn";
|
|
2
|
+
export type { PlainColorObject, ColorConstructor, ColorSpace, Coords, } from "colorjs.io/fn";
|
|
3
|
+
import type { ColorSpace, PlainColorObject } from "colorjs.io/fn";
|
|
4
|
+
import type { ColorValue } from "./schema";
|
|
5
|
+
export declare const color: typeof colorjs;
|
|
6
|
+
export declare const toColorSpace: (space: ColorSpace) => ColorValue["colorSpace"];
|
|
7
|
+
export declare const toColorComponent: (value: undefined | null | number) => number;
|
|
8
|
+
export declare const srgbColor: (r: number, g: number, b: number, alpha?: number) => PlainColorObject;
|
|
9
|
+
export declare const transparentColor: import("colorjs.io/src/color.js").PlainColorObject;
|
|
10
|
+
export declare const whiteColor: import("colorjs.io/src/color.js").PlainColorObject;
|
|
11
|
+
export declare const parseColor: (cssString: string) => PlainColorObject;
|
|
12
|
+
export declare const colorDistance: (a: PlainColorObject, b: PlainColorObject) => number;
|
|
13
|
+
export declare const lerpColor: (a: PlainColorObject, b: PlainColorObject, ratio: number) => PlainColorObject;
|
|
14
|
+
export declare const serializeColor: (color: PlainColorObject) => string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/lib/types/index.d.ts
CHANGED
package/lib/types/schema.d.ts
CHANGED
|
@@ -94,7 +94,7 @@ declare const RgbValue: z.ZodObject<{
|
|
|
94
94
|
export type RgbValue = z.infer<typeof RgbValue>;
|
|
95
95
|
export type ColorValue = {
|
|
96
96
|
type: "color";
|
|
97
|
-
colorSpace: "srgb" | "p3" | "srgb-linear" | "hsl" | "hwb" | "lab" | "lch" | "oklab" | "oklch" | "a98rgb" | "prophoto" | "rec2020" | "xyz-d65" | "xyz-d50";
|
|
97
|
+
colorSpace: "hex" | "srgb" | "p3" | "srgb-linear" | "hsl" | "hwb" | "lab" | "lch" | "oklab" | "oklch" | "a98rgb" | "prophoto" | "rec2020" | "xyz-d65" | "xyz-d50";
|
|
98
98
|
components: [number, number, number];
|
|
99
99
|
alpha: number | VarValue;
|
|
100
100
|
hidden?: boolean;
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webstudio-is/css-engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.258.0",
|
|
4
4
|
"description": "CSS Renderer for Webstudio",
|
|
5
5
|
"author": "Webstudio <github@webstudio.is>",
|
|
6
6
|
"homepage": "https://webstudio.is",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@emotion/hash": "^0.9.2",
|
|
10
|
+
"colorjs.io": "^0.6.1",
|
|
10
11
|
"zod": "^3.24.2",
|
|
11
|
-
"@webstudio-is/fonts": "0.
|
|
12
|
+
"@webstudio-is/fonts": "0.258.0"
|
|
12
13
|
},
|
|
13
14
|
"devDependencies": {
|
|
14
15
|
"@types/react": "^18.2.70",
|