@webstudio-is/css-data 0.91.0 → 0.266.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 (95) hide show
  1. package/lib/index.js +17534 -15
  2. package/lib/types/__generated__/animatable-properties.d.ts +1 -0
  3. package/lib/types/__generated__/html.d.ts +2 -0
  4. package/lib/types/__generated__/keyword-values.d.ts +4 -358
  5. package/lib/types/__generated__/properties.d.ts +10 -3674
  6. package/lib/types/__generated__/property-value-descriptions.d.ts +7 -5446
  7. package/lib/types/__generated__/pseudo-classes.d.ts +1 -0
  8. package/lib/types/__generated__/pseudo-elements.d.ts +1 -0
  9. package/lib/types/__generated__/pseudo-selector-descriptions.d.ts +2 -0
  10. package/lib/types/__generated__/shorthand-properties.d.ts +1 -0
  11. package/lib/types/css-tree.d.ts +772 -0
  12. package/lib/types/index.d.ts +18 -3680
  13. package/lib/types/media-condition-simulator.d.ts +7 -0
  14. package/lib/types/parse-css-value.d.ts +8 -3
  15. package/lib/types/parse-css.d.ts +75 -6
  16. package/lib/types/property-parsers/conic-gradient.d.ts +3 -0
  17. package/lib/types/property-parsers/gradient-utils.d.ts +20 -0
  18. package/lib/types/property-parsers/grid-template-areas.d.ts +21 -0
  19. package/lib/types/property-parsers/grid-template-tracks.d.ts +128 -0
  20. package/lib/types/property-parsers/index.d.ts +6 -2
  21. package/lib/types/property-parsers/linear-gradient.d.ts +4 -0
  22. package/lib/types/property-parsers/radial-gradient.d.ts +3 -0
  23. package/lib/types/property-parsers/types.d.ts +28 -0
  24. package/lib/types/selector-validation.d.ts +13 -0
  25. package/lib/types/shorthands.d.ts +2 -0
  26. package/package.json +29 -33
  27. package/lib/__generated__/keyword-values.js +0 -5255
  28. package/lib/__generated__/properties.js +0 -3697
  29. package/lib/__generated__/property-value-descriptions.js +0 -2740
  30. package/lib/__generated__/units.js +0 -65
  31. package/lib/cjs/__generated__/keyword-values.js +0 -5275
  32. package/lib/cjs/__generated__/properties.js +0 -3717
  33. package/lib/cjs/__generated__/property-value-descriptions.js +0 -2760
  34. package/lib/cjs/__generated__/units.js +0 -85
  35. package/lib/cjs/custom-data.js +0 -64
  36. package/lib/cjs/html-check.js +0 -25
  37. package/lib/cjs/html.js +0 -581
  38. package/lib/cjs/index.js +0 -48
  39. package/lib/cjs/package.json +0 -1
  40. package/lib/cjs/parse-css-value.js +0 -152
  41. package/lib/cjs/parse-css.js +0 -136
  42. package/lib/cjs/popularity-index.js +0 -4633
  43. package/lib/cjs/property-parsers/background.js +0 -119
  44. package/lib/cjs/property-parsers/box-shadow.js +0 -129
  45. package/lib/cjs/property-parsers/index.js +0 -19
  46. package/lib/cjs/property-parsers/parsers.js +0 -26
  47. package/lib/cjs/property-parsers/to-longhand.js +0 -24
  48. package/lib/cjs/schema.js +0 -135
  49. package/lib/custom-data.js +0 -44
  50. package/lib/html-check.js +0 -2
  51. package/lib/html.js +0 -561
  52. package/lib/parse-css-value.js +0 -122
  53. package/lib/parse-css.js +0 -106
  54. package/lib/popularity-index.js +0 -4613
  55. package/lib/property-parsers/background.js +0 -89
  56. package/lib/property-parsers/box-shadow.js +0 -99
  57. package/lib/property-parsers/index.js +0 -2
  58. package/lib/property-parsers/parsers.js +0 -6
  59. package/lib/property-parsers/to-longhand.js +0 -4
  60. package/lib/schema.js +0 -115
  61. package/lib/types/custom-data.d.ts +0 -15
  62. package/lib/types/html-check.d.ts +0 -1
  63. package/lib/types/html.d.ts +0 -62
  64. package/lib/types/parse-css-value.test.d.ts +0 -1
  65. package/lib/types/parse-css.test.d.ts +0 -1
  66. package/lib/types/popularity-index.d.ts +0 -6
  67. package/lib/types/property-parsers/background.d.ts +0 -11
  68. package/lib/types/property-parsers/background.test.d.ts +0 -1
  69. package/lib/types/property-parsers/box-shadow.d.ts +0 -3
  70. package/lib/types/property-parsers/box-shadow.test.d.ts +0 -1
  71. package/lib/types/property-parsers/parsers.d.ts +0 -2
  72. package/lib/types/property-parsers/to-longhand.d.ts +0 -1
  73. package/lib/types/schema.d.ts +0 -3243
  74. package/src/__generated__/keyword-values.ts +0 -5253
  75. package/src/__generated__/properties.ts +0 -3696
  76. package/src/__generated__/property-value-descriptions.ts +0 -4008
  77. package/src/__generated__/units.ts +0 -63
  78. package/src/custom-data.ts +0 -57
  79. package/src/html-check.ts +0 -8
  80. package/src/html.ts +0 -617
  81. package/src/index.ts +0 -25
  82. package/src/parse-css-value.test.ts +0 -136
  83. package/src/parse-css-value.ts +0 -157
  84. package/src/parse-css.test.ts +0 -101
  85. package/src/parse-css.ts +0 -137
  86. package/src/popularity-index.ts +0 -4611
  87. package/src/property-parsers/README.md +0 -11
  88. package/src/property-parsers/background.test.ts +0 -184
  89. package/src/property-parsers/background.ts +0 -147
  90. package/src/property-parsers/box-shadow.test.ts +0 -294
  91. package/src/property-parsers/box-shadow.ts +0 -130
  92. package/src/property-parsers/index.ts +0 -2
  93. package/src/property-parsers/parsers.ts +0 -5
  94. package/src/property-parsers/to-longhand.ts +0 -4
  95. package/src/schema.ts +0 -193
@@ -1,136 +0,0 @@
1
- import { describe, test, expect } from "@jest/globals";
2
- import { parseCssValue } from "./parse-css-value";
3
-
4
- describe("Parse CSS value", () => {
5
- describe("number value", () => {
6
- test("unitless", () => {
7
- expect(parseCssValue("lineHeight", "10")).toEqual({
8
- type: "unit",
9
- unit: "number",
10
- value: 10,
11
- });
12
- });
13
- });
14
-
15
- describe("unit value", () => {
16
- test("with unit", () => {
17
- expect(parseCssValue("width", "10px")).toEqual({
18
- type: "unit",
19
- unit: "px",
20
- value: 10,
21
- });
22
- });
23
-
24
- test("empty input", () => {
25
- expect(parseCssValue("width", "")).toEqual({
26
- type: "invalid",
27
- value: "",
28
- });
29
- });
30
- });
31
-
32
- describe("keyword value", () => {
33
- test("keyword", () => {
34
- expect(parseCssValue("width", "auto")).toEqual({
35
- type: "keyword",
36
- value: "auto",
37
- });
38
- });
39
-
40
- test("keyword display block", () => {
41
- expect(parseCssValue("display", "block")).toEqual({
42
- type: "keyword",
43
- value: "block",
44
- });
45
- });
46
-
47
- test("keyword with unit", () => {
48
- expect(parseCssValue("width", "autopx")).toEqual({
49
- type: "invalid",
50
- value: "autopx",
51
- });
52
- });
53
-
54
- test("invalid", () => {
55
- // This will return px as a fallback unit, as number is not valid for width.
56
- expect(parseCssValue("width", "10")).toEqual({
57
- type: "invalid",
58
- value: "10",
59
- });
60
-
61
- // This will return number unit, as number is valid for aspectRatio.
62
- expect(parseCssValue("aspectRatio", "10")).toEqual({
63
- type: "unit",
64
- unit: "number",
65
- value: 10,
66
- });
67
- });
68
- });
69
-
70
- describe("Unparesd valid values", () => {
71
- test("Simple valid function values", () => {
72
- expect(parseCssValue("filter", "blur(4px)")).toEqual({
73
- type: "unparsed",
74
- value: "blur(4px)",
75
- });
76
-
77
- expect(parseCssValue("width", "calc(4px + 16em)")).toEqual({
78
- type: "unparsed",
79
- value: "calc(4px + 16em)",
80
- });
81
- });
82
-
83
- test("Multiple valid function values", () => {
84
- expect(
85
- parseCssValue(
86
- "filter",
87
- "blur(4px) drop-shadow(16px 16px 20px blue) opacity(25%)"
88
- )
89
- ).toEqual({
90
- type: "unparsed",
91
- value: "blur(4px) drop-shadow(16px 16px 20px blue) opacity(25%)",
92
- });
93
-
94
- expect(parseCssValue("filter", "blur(calc(4px + 16em))")).toEqual({
95
- type: "unparsed",
96
- value: "blur(calc(4px + 16em))",
97
- });
98
- });
99
-
100
- test("Invalid function values", () => {
101
- expect(parseCssValue("width", "blur(4)")).toEqual({
102
- type: "invalid",
103
- value: "blur(4)",
104
- });
105
- });
106
- });
107
-
108
- describe("Colors", () => {
109
- test("Color rgba values", () => {
110
- expect(parseCssValue("backgroundColor", "rgba(0,0,0,0)")).toEqual({
111
- type: "rgb",
112
- alpha: 0,
113
- b: 0,
114
- g: 0,
115
- r: 0,
116
- });
117
- });
118
-
119
- test("Color rgba values", () => {
120
- expect(parseCssValue("backgroundColor", "#00220011")).toEqual({
121
- type: "rgb",
122
- alpha: 0.07,
123
- b: 0,
124
- g: 34,
125
- r: 0,
126
- });
127
- });
128
-
129
- test("Color rgba values", () => {
130
- expect(parseCssValue("color", "red")).toEqual({
131
- type: "keyword",
132
- value: "red",
133
- });
134
- });
135
- });
136
- });
@@ -1,157 +0,0 @@
1
- import { colord } from "colord";
2
- import * as csstree from "css-tree";
3
- import hyphenate from "hyphenate-style-name";
4
- import warnOnce from "warn-once";
5
- import { keywordValues } from "./__generated__/keyword-values";
6
- import { units } from "./__generated__/units";
7
- import type { StyleProperty, StyleValue, Unit } from "./schema";
8
-
9
- const cssTryParseValue = (input: string) => {
10
- try {
11
- const ast = csstree.parse(input, { context: "value" });
12
- return ast;
13
- } catch {
14
- return undefined;
15
- }
16
- };
17
-
18
- export const isValidDeclaration = (
19
- property: string,
20
- value: string
21
- ): boolean => {
22
- const ast = cssTryParseValue(value);
23
-
24
- if (ast == null) {
25
- return false;
26
- }
27
-
28
- const cssPropertyName = hyphenate(property);
29
-
30
- const matchResult = csstree.lexer.matchProperty(cssPropertyName, ast);
31
-
32
- const isValidDeclaration = matchResult.matched != null;
33
-
34
- // @todo remove after fix https://github.com/csstree/csstree/issues/246
35
- if (isValidDeclaration && typeof CSSStyleValue !== "undefined") {
36
- try {
37
- CSSStyleValue.parse(cssPropertyName, value);
38
- } catch {
39
- warnOnce(
40
- true,
41
- `Css property "${property}" with value "${value}" is invalid according to CSSStyleValue.parse
42
- but valid according to csstree.lexer.matchProperty.`
43
- );
44
- return false;
45
- }
46
- }
47
-
48
- return isValidDeclaration;
49
- };
50
-
51
- export const parseCssValue = (
52
- property: StyleProperty, // Handles only long-hand values.
53
- input: string
54
- ): StyleValue => {
55
- const invalidValue = {
56
- type: "invalid",
57
- value: input,
58
- } as const;
59
-
60
- if (input.length === 0) {
61
- return invalidValue;
62
- }
63
-
64
- if (!isValidDeclaration(property, input)) {
65
- return invalidValue;
66
- }
67
-
68
- const ast = cssTryParseValue(input);
69
-
70
- if (ast == null) {
71
- warnOnce(
72
- true,
73
- `Can't parse css property "${property}" with value "${input}"`
74
- );
75
- return invalidValue;
76
- }
77
-
78
- if (
79
- ast != null &&
80
- ast.type === "Value" &&
81
- ast.children.first === ast.children.last
82
- ) {
83
- // Try extract units from 1st children
84
- const first = ast.children.first;
85
-
86
- if (first?.type === "Number") {
87
- return {
88
- type: "unit",
89
- unit: "number",
90
- value: Number(first.value),
91
- };
92
- }
93
-
94
- if (first?.type === "Dimension") {
95
- const unit = first.unit as (typeof units)[keyof typeof units][number];
96
-
97
- for (const unitGroup of Object.values(units)) {
98
- if (unitGroup.includes(unit as never)) {
99
- return {
100
- type: "unit",
101
- unit: unit as Unit,
102
- value: Number(first.value),
103
- };
104
- }
105
- }
106
- return invalidValue;
107
- }
108
-
109
- if (first?.type === "Percentage") {
110
- return {
111
- type: "unit",
112
- unit: "%",
113
- value: Number(first.value),
114
- };
115
- }
116
-
117
- if (first?.type === "Identifier") {
118
- const values = keywordValues[
119
- property as keyof typeof keywordValues
120
- ] as ReadonlyArray<string>;
121
- const lettersRegex = /[^a-zA-Z]+/g;
122
- const searchValues = values.map((value) =>
123
- value.replace(lettersRegex, "").toLowerCase()
124
- );
125
- const keywordInput = input.replace(lettersRegex, "").toLowerCase();
126
-
127
- const index = searchValues.indexOf(keywordInput);
128
-
129
- if (index > -1) {
130
- return {
131
- type: "keyword",
132
- value: values[index],
133
- };
134
- }
135
- }
136
- }
137
-
138
- // Probably a color (we can use csstree.lexer.matchProperty(cssPropertyName, ast) to extract the type but this looks much simpler)
139
- if (property.toLocaleLowerCase().includes("color")) {
140
- const mayBeColor = colord(input);
141
- if (mayBeColor.isValid()) {
142
- const rgb = mayBeColor.toRgb();
143
- return {
144
- type: "rgb",
145
- alpha: rgb.a,
146
- r: rgb.r,
147
- g: rgb.g,
148
- b: rgb.b,
149
- };
150
- }
151
- }
152
-
153
- return {
154
- type: "unparsed",
155
- value: input,
156
- };
157
- };
@@ -1,101 +0,0 @@
1
- import { describe, expect, test } from "@jest/globals";
2
- import { parseCss } from "./parse-css";
3
-
4
- describe("Parse CSS", () => {
5
- test("one class selector rules", () => {
6
- expect(parseCss(`.test { color: #ff0000 }`)).toMatchInlineSnapshot(`
7
- {
8
- "test": [
9
- {
10
- "property": "color",
11
- "value": {
12
- "alpha": 1,
13
- "b": 0,
14
- "g": 0,
15
- "r": 255,
16
- "type": "rgb",
17
- },
18
- },
19
- ],
20
- }
21
- `);
22
- });
23
-
24
- test("parses supported shorthand values", () => {
25
- expect(
26
- parseCss(
27
- `.test { background: #ff0000 linear-gradient(180deg, #11181C 0%, rgba(17, 24, 28, 0) 36.09%), #EBFFFC; }`
28
- ).test
29
- ).toMatchInlineSnapshot(`
30
- [
31
- {
32
- "property": "backgroundImage",
33
- "value": {
34
- "type": "layers",
35
- "value": [
36
- {
37
- "type": "unparsed",
38
- "value": "linear-gradient(180deg,#11181C 0%,rgba(17,24,28,0) 36.09%)",
39
- },
40
- ],
41
- },
42
- },
43
- {
44
- "property": "backgroundColor",
45
- "value": {
46
- "alpha": 1,
47
- "b": 252,
48
- "g": 255,
49
- "r": 235,
50
- "type": "rgb",
51
- },
52
- },
53
- ]
54
- `);
55
- });
56
-
57
- test("parses unsupported shorthand values", () => {
58
- expect(parseCss(`.test { padding: 4px }`).test[0]).toMatchInlineSnapshot(`
59
- {
60
- "property": "padding",
61
- "value": {
62
- "type": "unit",
63
- "unit": "px",
64
- "value": 4,
65
- },
66
- }
67
- `);
68
- });
69
-
70
- test("complex selector rules", () => {
71
- expect(parseCss(`.test, a, .test2, .test:hover { color: #ff0000 }`))
72
- .toMatchInlineSnapshot(`
73
- {
74
- "test": [
75
- {
76
- "property": "color",
77
- "value": {
78
- "alpha": 1,
79
- "b": 0,
80
- "g": 0,
81
- "r": 255,
82
- "type": "rgb",
83
- },
84
- },
85
- ],
86
- "test2": [
87
- {
88
- "property": "color",
89
- "value": {
90
- "alpha": 1,
91
- "b": 0,
92
- "g": 0,
93
- "r": 255,
94
- "type": "rgb",
95
- },
96
- },
97
- ],
98
- }
99
- `);
100
- });
101
- });
package/src/parse-css.ts DELETED
@@ -1,137 +0,0 @@
1
- import * as csstree from "css-tree";
2
- import { parseCssValue as parseCssValueLonghand } from "./parse-css-value";
3
- import * as parsers from "./property-parsers/parsers";
4
- import * as toLonghand from "./property-parsers/to-longhand";
5
- import { StyleValue, type Style as S, type StyleProperty } from "./schema";
6
-
7
- type Selector = string;
8
- type Style = {
9
- // @todo add support for states and media queries in addition to declarations
10
- property: StyleProperty;
11
- value: StyleValue;
12
- };
13
-
14
- export type Styles = Record<Selector, Style[]>;
15
-
16
- type Longhand = keyof typeof toLonghand;
17
-
18
- const parseCssValue = function parseCssValue(
19
- property: Longhand | StyleProperty,
20
- value: string
21
- ): S {
22
- const unwrap = toLonghand[property as Longhand];
23
-
24
- if (typeof unwrap === "function") {
25
- const longhands = unwrap(value);
26
-
27
- return Object.fromEntries(
28
- Object.entries(longhands).map(([property, value]) => {
29
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
30
- // @ts-ignore @todo remove this ignore: property is a `keyof typeof longhands` which is a key in parsers but TS can't infer the link
31
- const valueParser = parsers[property];
32
-
33
- if (typeof valueParser === "function") {
34
- return [property, valueParser(value)];
35
- }
36
-
37
- if (Array.isArray(value)) {
38
- return [
39
- property,
40
- {
41
- type: "invalid",
42
- value: value.join(""),
43
- },
44
- ];
45
- }
46
-
47
- if (!value) {
48
- return [property, { type: "invalid", value: "" }];
49
- }
50
-
51
- return [
52
- property,
53
- parseCssValueLonghand(property as StyleProperty, value),
54
- ];
55
- })
56
- );
57
- }
58
-
59
- return {
60
- [property]: parseCssValueLonghand(property as StyleProperty, value),
61
- };
62
- };
63
-
64
- const cssTreeTryParse = (input: string) => {
65
- try {
66
- const ast = csstree.parse(input);
67
- return ast;
68
- } catch {
69
- return undefined;
70
- }
71
- };
72
-
73
- export const parseCss = function cssToWS(css: string) {
74
- const ast = cssTreeTryParse(css);
75
-
76
- let selectors: Selector[] = [];
77
- const styles: Styles = {};
78
-
79
- if (ast === undefined) {
80
- return styles;
81
- }
82
-
83
- csstree.walk(ast, (node, item) => {
84
- if (node.type === "SelectorList") {
85
- selectors = [];
86
- }
87
- if (node.type === "ClassSelector") {
88
- if (!item.prev && !item.next) {
89
- selectors.push(node.name);
90
- }
91
- return;
92
- }
93
-
94
- if (node.type === "Declaration") {
95
- const stringValue = csstree.generate(node.value);
96
-
97
- const parsedCss = parseCssValue(
98
- node.property as Longhand | StyleProperty,
99
- stringValue
100
- );
101
-
102
- (Object.entries(parsedCss) as [StyleProperty, StyleValue][]).forEach(
103
- ([property, value]) => {
104
- try {
105
- StyleValue.parse(value);
106
- selectors.forEach((selector) => {
107
- if (Array.isArray(styles[selector])) {
108
- styles[selector].push({
109
- property,
110
- value,
111
- });
112
- } else {
113
- styles[selector] = [{ property, value }];
114
- }
115
- });
116
- } catch (error) {
117
- if (process.env.NODE_ENV !== "production") {
118
- // eslint-disable-next-line no-console
119
- console.warn(
120
- true,
121
- `Declaration parsing for \`${selectors.join(", ")}.${
122
- node.property
123
- }: ${stringValue}\` failed:\n\n${JSON.stringify(
124
- parsedCss,
125
- null,
126
- 2
127
- )}`
128
- );
129
- }
130
- }
131
- }
132
- );
133
- }
134
- });
135
-
136
- return styles;
137
- };