@webstudio-is/css-engine 0.4.1 → 0.15.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/cjs/core/css-engine.cjs +1 -1
- package/lib/cjs/core/rules.cjs +10 -9
- package/lib/cjs/core/to-value.cjs +17 -1
- package/lib/core/css-engine.js +1 -1
- package/lib/core/rules.js +10 -9
- package/lib/core/to-value.js +17 -1
- package/package.json +1 -1
- package/src/core/css-engine.test.ts +87 -12
- package/src/core/css-engine.ts +1 -1
- package/src/core/rules.ts +17 -6
- package/src/core/to-value.ts +27 -1
|
@@ -114,7 +114,7 @@ class CssEngine {
|
|
|
114
114
|
for (const plaintextRule of __privateGet(this, _plainRules).values()) {
|
|
115
115
|
css.push(plaintextRule.cssText);
|
|
116
116
|
}
|
|
117
|
-
for (const mediaRule of __privateGet(this, _mediaRules).values()) {
|
|
117
|
+
for (const mediaRule of import_rules.MediaRule.sort(__privateGet(this, _mediaRules).values())) {
|
|
118
118
|
const { cssText } = mediaRule;
|
|
119
119
|
if (cssText !== "") {
|
|
120
120
|
css.push(cssText);
|
package/lib/cjs/core/rules.cjs
CHANGED
|
@@ -50,7 +50,7 @@ __export(rules_exports, {
|
|
|
50
50
|
module.exports = __toCommonJS(rules_exports);
|
|
51
51
|
var import_hyphenate_style_name = __toESM(require("hyphenate-style-name"), 1);
|
|
52
52
|
var import_to_value = require("./to-value");
|
|
53
|
-
var _styleMap, _isDirty, _string, _onChange,
|
|
53
|
+
var _styleMap, _isDirty, _string, _onChange, _mediaType;
|
|
54
54
|
class StylePropertyMap {
|
|
55
55
|
constructor() {
|
|
56
56
|
__privateAdd(this, _styleMap, /* @__PURE__ */ new Map());
|
|
@@ -109,12 +109,16 @@ class StyleRule {
|
|
|
109
109
|
_onChange = new WeakMap();
|
|
110
110
|
class MediaRule {
|
|
111
111
|
constructor(options = {}) {
|
|
112
|
-
__privateAdd(this, _options, void 0);
|
|
113
112
|
this.rules = [];
|
|
114
113
|
__privateAdd(this, _mediaType, void 0);
|
|
115
|
-
|
|
114
|
+
this.options = options;
|
|
116
115
|
__privateSet(this, _mediaType, options.mediaType ?? "all");
|
|
117
116
|
}
|
|
117
|
+
static sort(mediaRules) {
|
|
118
|
+
return Array.from(mediaRules).sort((ruleA, ruleB) => {
|
|
119
|
+
return (ruleA.options.minWidth ?? -Number.MAX_SAFE_INTEGER) - (ruleB.options.minWidth ?? -Number.MAX_SAFE_INTEGER);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
118
122
|
insertRule(rule) {
|
|
119
123
|
this.rules.push(rule);
|
|
120
124
|
return rule;
|
|
@@ -128,7 +132,7 @@ class MediaRule {
|
|
|
128
132
|
rules.push(` ${rule.cssText}`);
|
|
129
133
|
}
|
|
130
134
|
let conditionText = "";
|
|
131
|
-
const { minWidth, maxWidth } =
|
|
135
|
+
const { minWidth, maxWidth } = this.options;
|
|
132
136
|
if (minWidth !== void 0) {
|
|
133
137
|
conditionText = `min-width: ${minWidth}px`;
|
|
134
138
|
}
|
|
@@ -145,7 +149,6 @@ ${rules.join(
|
|
|
145
149
|
}`;
|
|
146
150
|
}
|
|
147
151
|
}
|
|
148
|
-
_options = new WeakMap();
|
|
149
152
|
_mediaType = new WeakMap();
|
|
150
153
|
class PlaintextRule {
|
|
151
154
|
constructor(cssText) {
|
|
@@ -155,14 +158,12 @@ class PlaintextRule {
|
|
|
155
158
|
}
|
|
156
159
|
class FontFaceRule {
|
|
157
160
|
constructor(options) {
|
|
158
|
-
|
|
159
|
-
__privateSet(this, _options2, options);
|
|
161
|
+
this.options = options;
|
|
160
162
|
}
|
|
161
163
|
get cssText() {
|
|
162
|
-
const { fontFamily, fontStyle, fontWeight, fontDisplay, src } =
|
|
164
|
+
const { fontFamily, fontStyle, fontWeight, fontDisplay, src } = this.options;
|
|
163
165
|
return `@font-face {
|
|
164
166
|
font-family: ${fontFamily}; font-style: ${fontStyle}; font-weight: ${fontWeight}; font-display: ${fontDisplay}; src: ${src};
|
|
165
167
|
}`;
|
|
166
168
|
}
|
|
167
169
|
}
|
|
168
|
-
_options2 = new WeakMap();
|
|
@@ -25,6 +25,9 @@ var import_fonts = require("@webstudio-is/fonts");
|
|
|
25
25
|
const defaultOptions = {
|
|
26
26
|
withFallback: true
|
|
27
27
|
};
|
|
28
|
+
const assertUnreachable = (_arg, errorMessage) => {
|
|
29
|
+
throw new Error(errorMessage);
|
|
30
|
+
};
|
|
28
31
|
const toValue = (value, options = defaultOptions) => {
|
|
29
32
|
if (value === void 0) {
|
|
30
33
|
return "";
|
|
@@ -51,5 +54,18 @@ const toValue = (value, options = defaultOptions) => {
|
|
|
51
54
|
const fallbacksString = fallbacks.length > 0 ? `, ${fallbacks.join(", ")}` : "";
|
|
52
55
|
return `var(--${value.value}${fallbacksString})`;
|
|
53
56
|
}
|
|
54
|
-
|
|
57
|
+
if (value.type === "keyword") {
|
|
58
|
+
return value.value;
|
|
59
|
+
}
|
|
60
|
+
if (value.type === "invalid") {
|
|
61
|
+
return value.value;
|
|
62
|
+
}
|
|
63
|
+
if (value.type === "unset") {
|
|
64
|
+
return value.value;
|
|
65
|
+
}
|
|
66
|
+
if (value.type === "rgb") {
|
|
67
|
+
return `rgba(${value.r}, ${value.g}, ${value.b}, ${value.alpha})`;
|
|
68
|
+
}
|
|
69
|
+
assertUnreachable(value, `Unknown value type`);
|
|
70
|
+
throw new Error("Unknown value type");
|
|
55
71
|
};
|
package/lib/core/css-engine.js
CHANGED
|
@@ -96,7 +96,7 @@ class CssEngine {
|
|
|
96
96
|
for (const plaintextRule of __privateGet(this, _plainRules).values()) {
|
|
97
97
|
css.push(plaintextRule.cssText);
|
|
98
98
|
}
|
|
99
|
-
for (const mediaRule of __privateGet(this, _mediaRules).values()) {
|
|
99
|
+
for (const mediaRule of MediaRule.sort(__privateGet(this, _mediaRules).values())) {
|
|
100
100
|
const { cssText } = mediaRule;
|
|
101
101
|
if (cssText !== "") {
|
|
102
102
|
css.push(cssText);
|
package/lib/core/rules.js
CHANGED
|
@@ -16,7 +16,7 @@ var __privateSet = (obj, member, value, setter) => {
|
|
|
16
16
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
17
17
|
return value;
|
|
18
18
|
};
|
|
19
|
-
var _styleMap, _isDirty, _string, _onChange,
|
|
19
|
+
var _styleMap, _isDirty, _string, _onChange, _mediaType;
|
|
20
20
|
import hyphenate from "hyphenate-style-name";
|
|
21
21
|
import { toValue } from "./to-value";
|
|
22
22
|
class StylePropertyMap {
|
|
@@ -77,12 +77,16 @@ class StyleRule {
|
|
|
77
77
|
_onChange = new WeakMap();
|
|
78
78
|
class MediaRule {
|
|
79
79
|
constructor(options = {}) {
|
|
80
|
-
__privateAdd(this, _options, void 0);
|
|
81
80
|
this.rules = [];
|
|
82
81
|
__privateAdd(this, _mediaType, void 0);
|
|
83
|
-
|
|
82
|
+
this.options = options;
|
|
84
83
|
__privateSet(this, _mediaType, options.mediaType ?? "all");
|
|
85
84
|
}
|
|
85
|
+
static sort(mediaRules) {
|
|
86
|
+
return Array.from(mediaRules).sort((ruleA, ruleB) => {
|
|
87
|
+
return (ruleA.options.minWidth ?? -Number.MAX_SAFE_INTEGER) - (ruleB.options.minWidth ?? -Number.MAX_SAFE_INTEGER);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
86
90
|
insertRule(rule) {
|
|
87
91
|
this.rules.push(rule);
|
|
88
92
|
return rule;
|
|
@@ -96,7 +100,7 @@ class MediaRule {
|
|
|
96
100
|
rules.push(` ${rule.cssText}`);
|
|
97
101
|
}
|
|
98
102
|
let conditionText = "";
|
|
99
|
-
const { minWidth, maxWidth } =
|
|
103
|
+
const { minWidth, maxWidth } = this.options;
|
|
100
104
|
if (minWidth !== void 0) {
|
|
101
105
|
conditionText = `min-width: ${minWidth}px`;
|
|
102
106
|
}
|
|
@@ -113,7 +117,6 @@ ${rules.join(
|
|
|
113
117
|
}`;
|
|
114
118
|
}
|
|
115
119
|
}
|
|
116
|
-
_options = new WeakMap();
|
|
117
120
|
_mediaType = new WeakMap();
|
|
118
121
|
class PlaintextRule {
|
|
119
122
|
constructor(cssText) {
|
|
@@ -123,17 +126,15 @@ class PlaintextRule {
|
|
|
123
126
|
}
|
|
124
127
|
class FontFaceRule {
|
|
125
128
|
constructor(options) {
|
|
126
|
-
|
|
127
|
-
__privateSet(this, _options2, options);
|
|
129
|
+
this.options = options;
|
|
128
130
|
}
|
|
129
131
|
get cssText() {
|
|
130
|
-
const { fontFamily, fontStyle, fontWeight, fontDisplay, src } =
|
|
132
|
+
const { fontFamily, fontStyle, fontWeight, fontDisplay, src } = this.options;
|
|
131
133
|
return `@font-face {
|
|
132
134
|
font-family: ${fontFamily}; font-style: ${fontStyle}; font-weight: ${fontWeight}; font-display: ${fontDisplay}; src: ${src};
|
|
133
135
|
}`;
|
|
134
136
|
}
|
|
135
137
|
}
|
|
136
|
-
_options2 = new WeakMap();
|
|
137
138
|
export {
|
|
138
139
|
FontFaceRule,
|
|
139
140
|
MediaRule,
|
package/lib/core/to-value.js
CHANGED
|
@@ -2,6 +2,9 @@ import { DEFAULT_FONT_FALLBACK, SYSTEM_FONTS } from "@webstudio-is/fonts";
|
|
|
2
2
|
const defaultOptions = {
|
|
3
3
|
withFallback: true
|
|
4
4
|
};
|
|
5
|
+
const assertUnreachable = (_arg, errorMessage) => {
|
|
6
|
+
throw new Error(errorMessage);
|
|
7
|
+
};
|
|
5
8
|
const toValue = (value, options = defaultOptions) => {
|
|
6
9
|
if (value === void 0) {
|
|
7
10
|
return "";
|
|
@@ -28,7 +31,20 @@ const toValue = (value, options = defaultOptions) => {
|
|
|
28
31
|
const fallbacksString = fallbacks.length > 0 ? `, ${fallbacks.join(", ")}` : "";
|
|
29
32
|
return `var(--${value.value}${fallbacksString})`;
|
|
30
33
|
}
|
|
31
|
-
|
|
34
|
+
if (value.type === "keyword") {
|
|
35
|
+
return value.value;
|
|
36
|
+
}
|
|
37
|
+
if (value.type === "invalid") {
|
|
38
|
+
return value.value;
|
|
39
|
+
}
|
|
40
|
+
if (value.type === "unset") {
|
|
41
|
+
return value.value;
|
|
42
|
+
}
|
|
43
|
+
if (value.type === "rgb") {
|
|
44
|
+
return `rgba(${value.r}, ${value.g}, ${value.b}, ${value.alpha})`;
|
|
45
|
+
}
|
|
46
|
+
assertUnreachable(value, `Unknown value type`);
|
|
47
|
+
throw new Error("Unknown value type");
|
|
32
48
|
};
|
|
33
49
|
export {
|
|
34
50
|
toValue
|
package/package.json
CHANGED
|
@@ -5,16 +5,25 @@ const style0 = {
|
|
|
5
5
|
} as const;
|
|
6
6
|
|
|
7
7
|
const mediaRuleOptions0 = { minWidth: 0 } as const;
|
|
8
|
-
const
|
|
8
|
+
const mediaId0 = "0";
|
|
9
|
+
|
|
10
|
+
const style1 = {
|
|
11
|
+
display: { type: "keyword", value: "flex" },
|
|
12
|
+
} as const;
|
|
13
|
+
|
|
14
|
+
const mediaRuleOptions1 = { minWidth: 300 } as const;
|
|
15
|
+
const mediaId1 = "1";
|
|
9
16
|
|
|
10
17
|
describe("CssEngine", () => {
|
|
11
18
|
let engine: CssEngine;
|
|
12
19
|
|
|
13
|
-
|
|
20
|
+
const reset = () => {
|
|
14
21
|
engine = new CssEngine();
|
|
15
|
-
}
|
|
22
|
+
};
|
|
16
23
|
|
|
17
|
-
|
|
24
|
+
beforeEach(reset);
|
|
25
|
+
|
|
26
|
+
test("use default media rule when there is no matching one registered", () => {
|
|
18
27
|
engine.addStyleRule(".c", {
|
|
19
28
|
style: style0,
|
|
20
29
|
breakpoint: "x",
|
|
@@ -35,10 +44,10 @@ describe("CssEngine", () => {
|
|
|
35
44
|
}"
|
|
36
45
|
`);
|
|
37
46
|
|
|
38
|
-
engine.addMediaRule(
|
|
47
|
+
engine.addMediaRule(mediaId0, mediaRuleOptions0);
|
|
39
48
|
engine.addStyleRule(".c1", {
|
|
40
49
|
style: { color: { type: "keyword", value: "blue" } },
|
|
41
|
-
breakpoint:
|
|
50
|
+
breakpoint: mediaId0,
|
|
42
51
|
});
|
|
43
52
|
// Default media query should allways be the first to have the lowest source order specificity
|
|
44
53
|
expect(engine.cssText).toMatchInlineSnapshot(`
|
|
@@ -52,8 +61,74 @@ describe("CssEngine", () => {
|
|
|
52
61
|
`);
|
|
53
62
|
});
|
|
54
63
|
|
|
64
|
+
test("sort media queries based on lower min-width", () => {
|
|
65
|
+
engine.addMediaRule(mediaId1, mediaRuleOptions1);
|
|
66
|
+
engine.addStyleRule(".c2", {
|
|
67
|
+
style: style1,
|
|
68
|
+
breakpoint: mediaId1,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
engine.addMediaRule(mediaId0, mediaRuleOptions0);
|
|
72
|
+
engine.addStyleRule(".c1", {
|
|
73
|
+
style: style0,
|
|
74
|
+
breakpoint: mediaId0,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
engine.addStyleRule(".c3", {
|
|
78
|
+
style: style0,
|
|
79
|
+
breakpoint: "x",
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Default media query should allways be the first to have the lowest source order specificity
|
|
83
|
+
expect(engine.cssText).toMatchInlineSnapshot(`
|
|
84
|
+
"@media all {
|
|
85
|
+
.c3 { display: block }
|
|
86
|
+
}
|
|
87
|
+
@media all and (min-width: 0px) {
|
|
88
|
+
.c1 { display: block }
|
|
89
|
+
}
|
|
90
|
+
@media all and (min-width: 300px) {
|
|
91
|
+
.c2 { display: flex }
|
|
92
|
+
}"
|
|
93
|
+
`);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test("keep the sort order when minWidth is not defined", () => {
|
|
97
|
+
engine.addStyleRule(".c0", {
|
|
98
|
+
style: style0,
|
|
99
|
+
breakpoint: "x",
|
|
100
|
+
});
|
|
101
|
+
engine.addStyleRule(".c1", {
|
|
102
|
+
style: style1,
|
|
103
|
+
breakpoint: "x",
|
|
104
|
+
});
|
|
105
|
+
expect(engine.cssText).toMatchInlineSnapshot(`
|
|
106
|
+
"@media all {
|
|
107
|
+
.c0 { display: block }
|
|
108
|
+
.c1 { display: flex }
|
|
109
|
+
}"
|
|
110
|
+
`);
|
|
111
|
+
|
|
112
|
+
reset();
|
|
113
|
+
|
|
114
|
+
engine.addStyleRule(".c1", {
|
|
115
|
+
style: style1,
|
|
116
|
+
breakpoint: "x",
|
|
117
|
+
});
|
|
118
|
+
engine.addStyleRule(".c0", {
|
|
119
|
+
style: style0,
|
|
120
|
+
breakpoint: "x",
|
|
121
|
+
});
|
|
122
|
+
expect(engine.cssText).toMatchInlineSnapshot(`
|
|
123
|
+
"@media all {
|
|
124
|
+
.c1 { display: flex }
|
|
125
|
+
.c0 { display: block }
|
|
126
|
+
}"
|
|
127
|
+
`);
|
|
128
|
+
});
|
|
129
|
+
|
|
55
130
|
test("rule with multiple properties", () => {
|
|
56
|
-
engine.addMediaRule(
|
|
131
|
+
engine.addMediaRule(mediaId0, mediaRuleOptions0);
|
|
57
132
|
engine.addStyleRule(".c", {
|
|
58
133
|
style: {
|
|
59
134
|
...style0,
|
|
@@ -69,7 +144,7 @@ describe("CssEngine", () => {
|
|
|
69
144
|
});
|
|
70
145
|
|
|
71
146
|
test("hyphenate property", () => {
|
|
72
|
-
engine.addMediaRule(
|
|
147
|
+
engine.addMediaRule(mediaId0, mediaRuleOptions0);
|
|
73
148
|
engine.addStyleRule(".c", {
|
|
74
149
|
style: {
|
|
75
150
|
backgroundColor: { type: "keyword", value: "red" },
|
|
@@ -84,7 +159,7 @@ describe("CssEngine", () => {
|
|
|
84
159
|
});
|
|
85
160
|
|
|
86
161
|
test("add rule", () => {
|
|
87
|
-
engine.addMediaRule(
|
|
162
|
+
engine.addMediaRule(mediaId0, mediaRuleOptions0);
|
|
88
163
|
const rule1 = engine.addStyleRule(".c", {
|
|
89
164
|
style: {
|
|
90
165
|
...style0,
|
|
@@ -116,7 +191,7 @@ describe("CssEngine", () => {
|
|
|
116
191
|
});
|
|
117
192
|
|
|
118
193
|
test("update rule", () => {
|
|
119
|
-
engine.addMediaRule(
|
|
194
|
+
engine.addMediaRule(mediaId0, mediaRuleOptions0);
|
|
120
195
|
const rule = engine.addStyleRule(".c", {
|
|
121
196
|
style: {
|
|
122
197
|
...style0,
|
|
@@ -147,7 +222,7 @@ describe("CssEngine", () => {
|
|
|
147
222
|
});
|
|
148
223
|
|
|
149
224
|
test("don't override media queries", () => {
|
|
150
|
-
engine.addMediaRule(
|
|
225
|
+
engine.addMediaRule(mediaId0, mediaRuleOptions0);
|
|
151
226
|
engine.addStyleRule(".c", {
|
|
152
227
|
style: style0,
|
|
153
228
|
breakpoint: "0",
|
|
@@ -157,7 +232,7 @@ describe("CssEngine", () => {
|
|
|
157
232
|
.c { display: block }
|
|
158
233
|
}"
|
|
159
234
|
`);
|
|
160
|
-
engine.addMediaRule(
|
|
235
|
+
engine.addMediaRule(mediaId0, mediaRuleOptions0);
|
|
161
236
|
expect(engine.cssText).toMatchInlineSnapshot(`
|
|
162
237
|
"@media all and (min-width: 0px) {
|
|
163
238
|
.c { display: block }
|
package/src/core/css-engine.ts
CHANGED
|
@@ -82,7 +82,7 @@ export class CssEngine {
|
|
|
82
82
|
for (const plaintextRule of this.#plainRules.values()) {
|
|
83
83
|
css.push(plaintextRule.cssText);
|
|
84
84
|
}
|
|
85
|
-
for (const mediaRule of this.#mediaRules.values()) {
|
|
85
|
+
for (const mediaRule of MediaRule.sort(this.#mediaRules.values())) {
|
|
86
86
|
const { cssText } = mediaRule;
|
|
87
87
|
if (cssText !== "") {
|
|
88
88
|
css.push(cssText);
|
package/src/core/rules.ts
CHANGED
|
@@ -65,11 +65,22 @@ export type MediaRuleOptions = {
|
|
|
65
65
|
};
|
|
66
66
|
|
|
67
67
|
export class MediaRule {
|
|
68
|
-
|
|
68
|
+
// Sort media rules by minWidth.
|
|
69
|
+
// Needed to ensure that more specific media rules are inserted after less specific ones.
|
|
70
|
+
// So that they get a higher specificity.
|
|
71
|
+
static sort(mediaRules: Iterable<MediaRule>) {
|
|
72
|
+
return Array.from(mediaRules).sort((ruleA, ruleB) => {
|
|
73
|
+
return (
|
|
74
|
+
(ruleA.options.minWidth ?? -Number.MAX_SAFE_INTEGER) -
|
|
75
|
+
(ruleB.options.minWidth ?? -Number.MAX_SAFE_INTEGER)
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
options: MediaRuleOptions;
|
|
69
80
|
rules: Array<StyleRule | PlaintextRule> = [];
|
|
70
81
|
#mediaType;
|
|
71
82
|
constructor(options: MediaRuleOptions = {}) {
|
|
72
|
-
this
|
|
83
|
+
this.options = options;
|
|
73
84
|
this.#mediaType = options.mediaType ?? "all";
|
|
74
85
|
}
|
|
75
86
|
insertRule(rule: StyleRule | PlaintextRule) {
|
|
@@ -85,7 +96,7 @@ export class MediaRule {
|
|
|
85
96
|
rules.push(` ${rule.cssText}`);
|
|
86
97
|
}
|
|
87
98
|
let conditionText = "";
|
|
88
|
-
const { minWidth, maxWidth } = this
|
|
99
|
+
const { minWidth, maxWidth } = this.options;
|
|
89
100
|
if (minWidth !== undefined) {
|
|
90
101
|
conditionText = `min-width: ${minWidth}px`;
|
|
91
102
|
}
|
|
@@ -118,13 +129,13 @@ export type FontFaceOptions = {
|
|
|
118
129
|
};
|
|
119
130
|
|
|
120
131
|
export class FontFaceRule {
|
|
121
|
-
|
|
132
|
+
options: FontFaceOptions;
|
|
122
133
|
constructor(options: FontFaceOptions) {
|
|
123
|
-
this
|
|
134
|
+
this.options = options;
|
|
124
135
|
}
|
|
125
136
|
get cssText() {
|
|
126
137
|
const { fontFamily, fontStyle, fontWeight, fontDisplay, src } =
|
|
127
|
-
this
|
|
138
|
+
this.options;
|
|
128
139
|
return `@font-face {\n font-family: ${fontFamily}; font-style: ${fontStyle}; font-weight: ${fontWeight}; font-display: ${fontDisplay}; src: ${src};\n}`;
|
|
129
140
|
}
|
|
130
141
|
}
|
package/src/core/to-value.ts
CHANGED
|
@@ -9,6 +9,11 @@ const defaultOptions = {
|
|
|
9
9
|
withFallback: true,
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
// exhaustive check, should never happen in runtime as ts would give error
|
|
13
|
+
const assertUnreachable = (_arg: never, errorMessage: string) => {
|
|
14
|
+
throw new Error(errorMessage);
|
|
15
|
+
};
|
|
16
|
+
|
|
12
17
|
export const toValue = (
|
|
13
18
|
value?: StyleValue,
|
|
14
19
|
options: ToCssOptions = defaultOptions
|
|
@@ -39,5 +44,26 @@ export const toValue = (
|
|
|
39
44
|
fallbacks.length > 0 ? `, ${fallbacks.join(", ")}` : "";
|
|
40
45
|
return `var(--${value.value}${fallbacksString})`;
|
|
41
46
|
}
|
|
42
|
-
|
|
47
|
+
|
|
48
|
+
if (value.type === "keyword") {
|
|
49
|
+
return value.value;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (value.type === "invalid") {
|
|
53
|
+
return value.value;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (value.type === "unset") {
|
|
57
|
+
return value.value;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (value.type === "rgb") {
|
|
61
|
+
return `rgba(${value.r}, ${value.g}, ${value.b}, ${value.alpha})`;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Will give ts error in case of missing type
|
|
65
|
+
assertUnreachable(value, `Unknown value type`);
|
|
66
|
+
|
|
67
|
+
// Will never happen
|
|
68
|
+
throw new Error("Unknown value type");
|
|
43
69
|
};
|