@webstudio-is/css-data 0.65.0 → 0.67.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.
Files changed (47) hide show
  1. package/lib/__generated__/keyword-values.js +2 -2
  2. package/lib/__generated__/properties.js +2 -2
  3. package/lib/cjs/__generated__/keyword-values.js +2 -2
  4. package/lib/cjs/__generated__/properties.js +2 -2
  5. package/lib/cjs/html.js +1 -3
  6. package/lib/cjs/index.js +3 -0
  7. package/lib/cjs/parse-css-value.js +152 -0
  8. package/lib/cjs/parse-css.js +125 -0
  9. package/lib/cjs/property-parsers/background.js +105 -0
  10. package/lib/cjs/property-parsers/index.js +18 -0
  11. package/lib/cjs/property-parsers/parsers.js +24 -0
  12. package/lib/cjs/property-parsers/to-longhand.js +24 -0
  13. package/lib/html.js +1 -3
  14. package/lib/index.js +3 -0
  15. package/lib/parse-css-value.js +122 -0
  16. package/lib/parse-css.js +95 -0
  17. package/lib/property-parsers/background.js +75 -0
  18. package/lib/property-parsers/index.js +1 -0
  19. package/lib/property-parsers/parsers.js +4 -0
  20. package/lib/property-parsers/to-longhand.js +4 -0
  21. package/lib/types/src/__generated__/keyword-values.d.ts +1 -1
  22. package/lib/types/src/__generated__/properties.d.ts +2 -2
  23. package/lib/types/src/index.d.ts +5 -2
  24. package/lib/types/src/parse-css-value.d.ts +3 -0
  25. package/lib/types/src/parse-css-value.test.d.ts +1 -0
  26. package/lib/types/src/parse-css.d.ts +9 -0
  27. package/lib/types/src/parse-css.test.d.ts +1 -0
  28. package/lib/types/src/property-parsers/background.d.ts +11 -0
  29. package/lib/types/src/property-parsers/background.test.d.ts +1 -0
  30. package/lib/types/src/property-parsers/index.d.ts +1 -0
  31. package/lib/types/src/property-parsers/parsers.d.ts +1 -0
  32. package/lib/types/src/property-parsers/to-longhand.d.ts +1 -0
  33. package/package.json +12 -4
  34. package/src/__generated__/keyword-values.ts +2 -2
  35. package/src/__generated__/properties.ts +2 -2
  36. package/src/html.ts +1 -3
  37. package/src/index.ts +6 -0
  38. package/src/parse-css-value.test.ts +136 -0
  39. package/src/parse-css-value.ts +157 -0
  40. package/src/parse-css.test.ts +101 -0
  41. package/src/parse-css.ts +124 -0
  42. package/src/property-parsers/README.md +11 -0
  43. package/src/property-parsers/background.test.ts +184 -0
  44. package/src/property-parsers/background.ts +132 -0
  45. package/src/property-parsers/index.ts +1 -0
  46. package/src/property-parsers/parsers.ts +4 -0
  47. package/src/property-parsers/to-longhand.ts +4 -0
@@ -0,0 +1,132 @@
1
+ import * as csstree from "css-tree";
2
+ import { parseCssValue } from "../parse-css-value";
3
+ import type {
4
+ InvalidValue,
5
+ LayersValue,
6
+ RgbValue,
7
+ UnparsedValue,
8
+ } from "../schema";
9
+
10
+ export const gradientNames = [
11
+ "conic-gradient",
12
+ "linear-gradient",
13
+ "radial-gradient",
14
+ "repeating-conic-gradient",
15
+ "repeating-linear-gradient",
16
+ "repeating-radial-gradient",
17
+ ];
18
+
19
+ export const parseBackground = (
20
+ background: string
21
+ ): {
22
+ backgroundImage: LayersValue | InvalidValue;
23
+ backgroundColor: RgbValue | undefined;
24
+ } => {
25
+ const { backgroundImage, backgroundColor: backgroundColorRaw } =
26
+ backgroundToLonghand(background);
27
+
28
+ const backgroundColor = backgroundColorRaw
29
+ ? (parseCssValue("backgroundColor", backgroundColorRaw) as RgbValue)
30
+ : undefined;
31
+
32
+ return {
33
+ backgroundImage: parseBackgroundImage(backgroundImage),
34
+ backgroundColor:
35
+ backgroundColor && backgroundColor.type === "rgb"
36
+ ? backgroundColor
37
+ : undefined,
38
+ };
39
+ };
40
+
41
+ export const backgroundToLonghand = (
42
+ background: string
43
+ ): {
44
+ backgroundImage: string[];
45
+ backgroundColor: string | undefined;
46
+ } => {
47
+ const layers: string[] = [];
48
+
49
+ let tokenStream = background.trim();
50
+
51
+ tokenStream = tokenStream.endsWith(";")
52
+ ? tokenStream.slice(0, -1)
53
+ : tokenStream;
54
+
55
+ // The user can copy the whole style together with the name of the property from figma or any other tool.
56
+ // We need to remove the property name from the string.
57
+ const cleanupKeywords = ["background:", "background-image:"];
58
+
59
+ for (const cleanupKeyword of cleanupKeywords) {
60
+ tokenStream = tokenStream.startsWith(cleanupKeyword)
61
+ ? tokenStream.slice(cleanupKeyword.length).trim()
62
+ : tokenStream;
63
+ }
64
+
65
+ const cssAst = csstree.parse(tokenStream, { context: "value" });
66
+
67
+ let backgroundColorRaw: string | undefined;
68
+
69
+ let nestingLevel = 0;
70
+
71
+ csstree.walk(cssAst, {
72
+ enter: (node, item, list) => {
73
+ if (node.type === "Function") {
74
+ if (gradientNames.includes(node.name)) {
75
+ layers.push(csstree.generate(node));
76
+ }
77
+
78
+ // If the depth is at level 0 and the next item is null, it's likely that the backgroundColor
79
+ // is written as rgba(x,y,z,a) or similar format.
80
+ // nestingLevel is used as a fast way to check existance of parent Function node
81
+ if (item.next === null && nestingLevel === 0) {
82
+ backgroundColorRaw = csstree.generate(node);
83
+ }
84
+
85
+ nestingLevel++;
86
+ }
87
+
88
+ if (node.type === "Hash" && item.next === null && nestingLevel === 0) {
89
+ // If the depth is at level 0 and the next item is null, it's likely that the backgroundColor
90
+ // is written as hex #XYZFGH
91
+ backgroundColorRaw = csstree.generate(node);
92
+ }
93
+ },
94
+ leave: (node, item, list) => {
95
+ if (node.type === "Function") {
96
+ nestingLevel--;
97
+ }
98
+ },
99
+ });
100
+
101
+ return {
102
+ backgroundImage: layers,
103
+ backgroundColor: backgroundColorRaw,
104
+ };
105
+ };
106
+
107
+ export const parseBackgroundImage = (
108
+ layers: string[]
109
+ ): LayersValue | InvalidValue => {
110
+ const backgroundImages: UnparsedValue[] = [];
111
+
112
+ for (const layer of layers) {
113
+ if (
114
+ gradientNames.some((gradientName) => layer.startsWith(gradientName)) ===
115
+ false
116
+ ) {
117
+ break;
118
+ }
119
+
120
+ const layerStyle = parseCssValue("backgroundImage", layer);
121
+
122
+ if (layerStyle.type !== "unparsed") {
123
+ break;
124
+ }
125
+
126
+ backgroundImages.push(layerStyle);
127
+ }
128
+
129
+ return backgroundImages.length > 0
130
+ ? { type: "layers", value: backgroundImages }
131
+ : { type: "invalid", value: layers.join(",") };
132
+ };
@@ -0,0 +1 @@
1
+ export * from "./background";
@@ -0,0 +1,4 @@
1
+ /*
2
+ Longhand properties parsers. Each named export should match a property name.
3
+ */
4
+ export { parseBackgroundImage as backgroundImage } from "./background";
@@ -0,0 +1,4 @@
1
+ /*
2
+ Shorthand properties unwrappers. Each named export should match a property name.
3
+ */
4
+ export { backgroundToLonghand as background } from "./background";