@webstudio-is/css-engine 0.189.0 → 0.191.4

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 (32) hide show
  1. package/package.json +5 -7
  2. package/lib/index.js +0 -951
  3. package/lib/types/__generated__/types.d.ts +0 -2
  4. package/lib/types/core/atomic.d.ts +0 -14
  5. package/lib/types/core/atomic.test.d.ts +0 -1
  6. package/lib/types/core/compare-media.d.ts +0 -6
  7. package/lib/types/core/compare-media.test.d.ts +0 -1
  8. package/lib/types/core/create-style-sheet.d.ts +0 -4
  9. package/lib/types/core/css-engine.stories.d.ts +0 -5
  10. package/lib/types/core/equal-media.d.ts +0 -2
  11. package/lib/types/core/equal-media.test.d.ts +0 -1
  12. package/lib/types/core/find-applicable-media.d.ts +0 -2
  13. package/lib/types/core/find-applicable-media.test.d.ts +0 -1
  14. package/lib/types/core/index.d.ts +0 -13
  15. package/lib/types/core/match-media.d.ts +0 -2
  16. package/lib/types/core/match-media.test.d.ts +0 -1
  17. package/lib/types/core/merger.d.ts +0 -274
  18. package/lib/types/core/merger.test.d.ts +0 -1
  19. package/lib/types/core/prefixer.d.ts +0 -2
  20. package/lib/types/core/prefixer.test.d.ts +0 -1
  21. package/lib/types/core/rules.d.ts +0 -104
  22. package/lib/types/core/style-element.d.ts +0 -10
  23. package/lib/types/core/style-sheet-regular.d.ts +0 -3
  24. package/lib/types/core/style-sheet-regular.test.d.ts +0 -1
  25. package/lib/types/core/style-sheet.d.ts +0 -24
  26. package/lib/types/core/to-property.d.ts +0 -4
  27. package/lib/types/core/to-property.test.d.ts +0 -1
  28. package/lib/types/core/to-value.d.ts +0 -3
  29. package/lib/types/core/to-value.test.d.ts +0 -1
  30. package/lib/types/css.d.ts +0 -1
  31. package/lib/types/index.d.ts +0 -4
  32. package/lib/types/schema.d.ts +0 -3925
package/lib/index.js DELETED
@@ -1,951 +0,0 @@
1
- // src/core/prefixer.ts
2
- var prefixStyles = (styleMap) => {
3
- const newStyleMap = /* @__PURE__ */ new Map();
4
- for (const [property, value] of styleMap) {
5
- if (property === "background-clip") {
6
- newStyleMap.set("-webkit-background-clip", value);
7
- }
8
- if (property === "user-select") {
9
- newStyleMap.set("-webkit-user-select", value);
10
- }
11
- if (property === "text-size-adjust") {
12
- newStyleMap.set("-webkit-text-size-adjust", value);
13
- }
14
- if (property === "backdrop-filter") {
15
- newStyleMap.set("-webkit-backdrop-filter", value);
16
- }
17
- newStyleMap.set(property, value);
18
- }
19
- return newStyleMap;
20
- };
21
-
22
- // src/schema.ts
23
- import { z } from "zod";
24
- var Unit = z.string();
25
- var UnitValue = z.object({
26
- type: z.literal("unit"),
27
- unit: Unit,
28
- value: z.number(),
29
- hidden: z.boolean().optional()
30
- });
31
- var KeywordValue = z.object({
32
- type: z.literal("keyword"),
33
- // @todo use exact type
34
- value: z.string(),
35
- hidden: z.boolean().optional()
36
- });
37
- var UnparsedValue = z.object({
38
- type: z.literal("unparsed"),
39
- value: z.string(),
40
- // For the builder we want to be able to hide background-image
41
- hidden: z.boolean().optional()
42
- });
43
- var FontFamilyValue = z.object({
44
- type: z.literal("fontFamily"),
45
- value: z.array(z.string()),
46
- hidden: z.boolean().optional()
47
- });
48
- var RgbValue = z.object({
49
- type: z.literal("rgb"),
50
- r: z.number(),
51
- g: z.number(),
52
- b: z.number(),
53
- alpha: z.number(),
54
- hidden: z.boolean().optional()
55
- });
56
- var FunctionValue = z.object({
57
- type: z.literal("function"),
58
- name: z.string(),
59
- args: z.lazy(() => StyleValue),
60
- hidden: z.boolean().optional()
61
- });
62
- var ImageValue = z.object({
63
- type: z.literal("image"),
64
- value: z.union([
65
- z.object({ type: z.literal("asset"), value: z.string() }),
66
- // url is not stored in db and only used by css-engine transformValue
67
- // to prepare image value for rendering
68
- z.object({ type: z.literal("url"), url: z.string() })
69
- ]),
70
- // For the builder we want to be able to hide images
71
- hidden: z.boolean().optional()
72
- });
73
- var GuaranteedInvalidValue = z.object({
74
- type: z.literal("guaranteedInvalid"),
75
- hidden: z.boolean().optional()
76
- });
77
- var InvalidValue = z.object({
78
- type: z.literal("invalid"),
79
- value: z.string(),
80
- hidden: z.boolean().optional()
81
- });
82
- var UnsetValue = z.object({
83
- type: z.literal("unset"),
84
- value: z.literal(""),
85
- hidden: z.boolean().optional()
86
- });
87
- var VarFallback = z.union([
88
- UnparsedValue,
89
- KeywordValue,
90
- UnitValue,
91
- RgbValue
92
- ]);
93
- var toVarFallback = (styleValue, transformValue) => {
94
- if (styleValue.type === "unparsed" || styleValue.type === "keyword" || styleValue.type === "unit" || styleValue.type === "rgb") {
95
- return styleValue;
96
- }
97
- styleValue;
98
- return { type: "unparsed", value: toValue(styleValue, transformValue) };
99
- };
100
- var VarValue = z.object({
101
- type: z.literal("var"),
102
- value: z.string(),
103
- fallback: VarFallback.optional(),
104
- hidden: z.boolean().optional()
105
- });
106
- var TupleValueItem = z.union([
107
- UnitValue,
108
- KeywordValue,
109
- UnparsedValue,
110
- ImageValue,
111
- RgbValue,
112
- FunctionValue,
113
- VarValue
114
- ]);
115
- var TupleValue = z.object({
116
- type: z.literal("tuple"),
117
- value: z.array(TupleValueItem),
118
- hidden: z.boolean().optional()
119
- });
120
- var LayerValueItem = z.union([
121
- UnitValue,
122
- KeywordValue,
123
- UnparsedValue,
124
- ImageValue,
125
- TupleValue,
126
- RgbValue,
127
- InvalidValue,
128
- FunctionValue,
129
- VarValue
130
- ]);
131
- var LayersValue = z.object({
132
- type: z.literal("layers"),
133
- value: z.array(LayerValueItem),
134
- hidden: z.boolean().optional()
135
- });
136
- var StyleValue = z.union([
137
- ImageValue,
138
- LayersValue,
139
- UnitValue,
140
- KeywordValue,
141
- FontFamilyValue,
142
- RgbValue,
143
- UnparsedValue,
144
- TupleValue,
145
- FunctionValue,
146
- GuaranteedInvalidValue,
147
- InvalidValue,
148
- UnsetValue,
149
- VarValue
150
- ]);
151
- var Style = z.record(z.string(), StyleValue);
152
-
153
- // src/css.ts
154
- var cssWideKeywords = /* @__PURE__ */ new Set([
155
- "initial",
156
- "inherit",
157
- "unset",
158
- "revert",
159
- "revert-layer"
160
- ]);
161
-
162
- // src/core/to-value.ts
163
- import { captureError } from "@webstudio-is/error-utils";
164
- import { DEFAULT_FONT_FALLBACK, SYSTEM_FONTS } from "@webstudio-is/fonts";
165
- var fallbackTransform = (styleValue) => {
166
- if (styleValue.type !== "fontFamily") {
167
- return;
168
- }
169
- let { value } = styleValue;
170
- if (value.length === 0) {
171
- value = [DEFAULT_FONT_FALLBACK];
172
- }
173
- if (value.length === 1) {
174
- const stack = SYSTEM_FONTS.get(value[0])?.stack;
175
- value = stack ?? [value[0], DEFAULT_FONT_FALLBACK];
176
- }
177
- return {
178
- type: "fontFamily",
179
- value: Array.from(new Set(value))
180
- };
181
- };
182
- var sanitizeCssUrl = (str) => JSON.stringify(str);
183
- var toValue = (styleValue, transformValue) => {
184
- if (styleValue === void 0) {
185
- return "";
186
- }
187
- const transformedValue = transformValue?.(styleValue) ?? fallbackTransform(styleValue);
188
- const value = transformedValue ?? styleValue;
189
- if (value.type === "unit") {
190
- return value.value + (value.unit === "number" ? "" : value.unit);
191
- }
192
- if (value.type === "fontFamily") {
193
- const families = [];
194
- for (const family of value.value) {
195
- families.push(family.includes(" ") ? `"${family}"` : family);
196
- }
197
- return families.join(", ");
198
- }
199
- if (value.type === "var") {
200
- if (value.hidden) {
201
- return "";
202
- }
203
- let fallbacksString = "";
204
- if (value.fallback) {
205
- fallbacksString = `, ${toValue(value.fallback, transformValue)}`;
206
- }
207
- return `var(--${value.value}${fallbacksString})`;
208
- }
209
- if (value.type === "keyword") {
210
- if (value.hidden === true) {
211
- return "";
212
- }
213
- return value.value;
214
- }
215
- if (value.type === "invalid") {
216
- return value.value;
217
- }
218
- if (value.type === "unset") {
219
- return value.value;
220
- }
221
- if (value.type === "rgb") {
222
- return `rgba(${value.r}, ${value.g}, ${value.b}, ${value.alpha})`;
223
- }
224
- if (value.type === "image") {
225
- if (value.hidden || value.value.type !== "url") {
226
- return "none";
227
- }
228
- return `url(${sanitizeCssUrl(value.value.url)})`;
229
- }
230
- if (value.type === "unparsed") {
231
- if (value.hidden === true) {
232
- return "none";
233
- }
234
- return value.value;
235
- }
236
- if (value.type === "layers") {
237
- const valueString = value.value.filter((layer) => layer.hidden !== true).map((layer) => toValue(layer, transformValue)).join(", ");
238
- return valueString === "" ? "none" : valueString;
239
- }
240
- if (value.type === "tuple") {
241
- if (value.hidden === true) {
242
- return "none";
243
- }
244
- return value.value.filter((value2) => value2.hidden !== true).map((value2) => toValue(value2, transformValue)).join(" ");
245
- }
246
- if (value.type === "function") {
247
- if (value.hidden === true) {
248
- return "";
249
- }
250
- return `${value.name}(${toValue(value.args, transformValue)})`;
251
- }
252
- if (value.type === "guaranteedInvalid") {
253
- return "";
254
- }
255
- return captureError(new Error("Unknown value type"), value);
256
- };
257
-
258
- // src/core/merger.ts
259
- var isLonghandValue = (value) => {
260
- if (value === void 0) {
261
- return false;
262
- }
263
- if (value.type === "keyword" && cssWideKeywords.has(value.value)) {
264
- return false;
265
- }
266
- if (value.type === "var") {
267
- const fallback = value.fallback;
268
- if (fallback?.type === "keyword" && cssWideKeywords.has(fallback.value)) {
269
- return false;
270
- }
271
- }
272
- return true;
273
- };
274
- var mergeBorder = (styleMap, base) => {
275
- const width = styleMap.get(`${base}-width`);
276
- const style = styleMap.get(`${base}-style`);
277
- const color = styleMap.get(`${base}-color`);
278
- if (isLonghandValue(width) && isLonghandValue(style) && isLonghandValue(color)) {
279
- styleMap.delete(`${base}-width`);
280
- styleMap.delete(`${base}-style`);
281
- styleMap.delete(`${base}-color`);
282
- styleMap.set(base, { type: "tuple", value: [width, style, color] });
283
- }
284
- };
285
- var mergeBox = (styleMap, base) => {
286
- const topValue = styleMap.get(`${base}-top`);
287
- const top = toValue(topValue);
288
- const right = toValue(styleMap.get(`${base}-right`));
289
- const bottom = toValue(styleMap.get(`${base}-bottom`));
290
- const left = toValue(styleMap.get(`${base}-left`));
291
- if (isLonghandValue(topValue) && top === right && top === bottom && top === left) {
292
- styleMap.delete(`${base}-top`);
293
- styleMap.delete(`${base}-right`);
294
- styleMap.delete(`${base}-bottom`);
295
- styleMap.delete(`${base}-left`);
296
- styleMap.set(base, topValue);
297
- }
298
- };
299
- var mergeWhiteSpaceAndTextWrap = (styleMap) => {
300
- const collapseValue = styleMap.get("white-space-collapse");
301
- const collapse = toValue(collapseValue);
302
- const modeValue = styleMap.get("text-wrap-mode");
303
- const mode = toValue(modeValue);
304
- const styleValue = styleMap.get("text-wrap-style");
305
- const style = toValue(styleValue);
306
- styleMap.delete("text-wrap-mode");
307
- styleMap.delete("text-wrap-style");
308
- if (collapse === "collapse" || collapse === "initial" || mode === "wrap" || mode === "initial") {
309
- styleMap.set("white-space", { type: "keyword", value: "normal" });
310
- }
311
- if (mode === "nowrap") {
312
- styleMap.set("white-space", { type: "keyword", value: "nowrap" });
313
- }
314
- if (collapse === "preserve") {
315
- if (mode === "nowrap") {
316
- styleMap.set("white-space", { type: "keyword", value: "pre" });
317
- } else {
318
- styleMap.set("white-space", { type: "keyword", value: "pre-wrap" });
319
- }
320
- }
321
- if (collapse === "preserve-breaks") {
322
- styleMap.set("white-space", { type: "keyword", value: "pre-line" });
323
- }
324
- if (collapse === "break-spaces") {
325
- styleMap.set("white-space", { type: "keyword", value: "break-spaces" });
326
- }
327
- if (style === "auto") {
328
- styleMap.set("text-wrap", modeValue ?? { type: "keyword", value: "wrap" });
329
- }
330
- if (style === "balance" || style === "stable" || style === "pretty") {
331
- styleMap.set("text-wrap", { type: "keyword", value: style });
332
- }
333
- const textWrap = (styleValue?.type !== "keyword" ? styleValue : void 0) ?? (modeValue?.type !== "keyword" ? modeValue : void 0);
334
- if (textWrap) {
335
- styleMap.set("text-wrap", textWrap);
336
- }
337
- if (collapseValue) {
338
- styleMap.delete("white-space-collapse");
339
- styleMap.set("white-space-collapse", collapseValue);
340
- }
341
- };
342
- var mergeBackgroundPosition = (styleMap) => {
343
- const x = styleMap.get("background-position-x");
344
- const y = styleMap.get("background-position-y");
345
- if (x?.type === "layers" && y?.type === "layers" && x.value.length === y.value.length) {
346
- const position = x.value.map((xValue, index) => {
347
- const yValue = y.value[index];
348
- return {
349
- type: "tuple",
350
- value: [xValue, yValue]
351
- };
352
- });
353
- styleMap.delete("background-position-x");
354
- styleMap.delete("background-position-y");
355
- styleMap.set("background-position", {
356
- type: "layers",
357
- value: position
358
- });
359
- }
360
- };
361
- var mergeStyles = (styleMap) => {
362
- const newStyle = new Map(styleMap);
363
- mergeBorder(newStyle, "border-top");
364
- mergeBorder(newStyle, "border-right");
365
- mergeBorder(newStyle, "border-bottom");
366
- mergeBorder(newStyle, "border-left");
367
- mergeBorder(newStyle, "border");
368
- mergeBorder(newStyle, "outline");
369
- mergeBox(newStyle, "border");
370
- mergeBox(newStyle, "margin");
371
- mergeBox(newStyle, "padding");
372
- mergeWhiteSpaceAndTextWrap(newStyle);
373
- mergeBackgroundPosition(newStyle);
374
- return newStyle;
375
- };
376
-
377
- // src/core/to-property.ts
378
- var hyphenateProperty = (property) => property.replace(/[A-Z]/g, (match) => "-" + match.toLowerCase());
379
-
380
- // src/core/rules.ts
381
- var mapGroupBy = (array, getKey) => {
382
- const groups = /* @__PURE__ */ new Map();
383
- for (const item of array) {
384
- const key = getKey(item);
385
- let group = groups.get(key);
386
- if (group === void 0) {
387
- group = [];
388
- groups.set(key, group);
389
- }
390
- group.push(item);
391
- }
392
- return groups;
393
- };
394
- var mergeDeclarations = (declarations) => {
395
- const newDeclarations = [];
396
- const groups = mapGroupBy(
397
- declarations,
398
- (declaration) => declaration.breakpoint + declaration.selector
399
- );
400
- for (const groupDeclarations of groups.values()) {
401
- const { breakpoint, selector } = groupDeclarations[0];
402
- const merged = mergeStyles(
403
- new Map(
404
- groupDeclarations.map((item) => [item.property, item.value])
405
- )
406
- );
407
- for (const [property, value] of merged) {
408
- newDeclarations.push({
409
- breakpoint,
410
- selector,
411
- property,
412
- value
413
- });
414
- }
415
- }
416
- return newDeclarations;
417
- };
418
- var generateStyleMap = ({
419
- style,
420
- indent = 0,
421
- transformValue
422
- }) => {
423
- const spaces = " ".repeat(indent);
424
- let lines = "";
425
- for (const [property, value] of style) {
426
- const propertyString = hyphenateProperty(property);
427
- const valueString = toValue(value, transformValue);
428
- const line = `${spaces}${propertyString}: ${valueString}`;
429
- lines += lines === "" ? line : `;
430
- ${line}`;
431
- }
432
- return lines;
433
- };
434
- var normalizeDeclaration = (declaration) => ({
435
- ...declaration,
436
- property: hyphenateProperty(declaration.property)
437
- });
438
- var getDeclarationKey = (declaraionKey) => {
439
- const { breakpoint, selector, property } = declaraionKey;
440
- return `${breakpoint}:${selector}:${property}`;
441
- };
442
- var MixinRule = class {
443
- // use map to avoid duplicated properties
444
- #declarations = /* @__PURE__ */ new Map();
445
- #dirtyBreakpoints = /* @__PURE__ */ new Set();
446
- /*
447
- * check if breakpoint was updated
448
- */
449
- isDirtyBreakpoint(breakpoint) {
450
- return this.#dirtyBreakpoints.has(breakpoint);
451
- }
452
- /**
453
- * reset breakpoints invalidation
454
- */
455
- clearBreakpoints() {
456
- this.#dirtyBreakpoints.clear();
457
- }
458
- setDeclaration(declaration) {
459
- declaration = normalizeDeclaration(declaration);
460
- this.#declarations.set(getDeclarationKey(declaration), declaration);
461
- this.#dirtyBreakpoints.add(declaration.breakpoint);
462
- }
463
- deleteDeclaration(declaration) {
464
- declaration = normalizeDeclaration(declaration);
465
- this.#declarations.delete(getDeclarationKey(declaration));
466
- this.#dirtyBreakpoints.add(declaration.breakpoint);
467
- }
468
- getDeclarations() {
469
- return this.#declarations.values();
470
- }
471
- };
472
- var NestingRule = class {
473
- #selector;
474
- #descendantSuffix;
475
- #mixinRules = /* @__PURE__ */ new Map();
476
- #mixins = /* @__PURE__ */ new Set();
477
- // use map to avoid duplicated properties
478
- #declarations = /* @__PURE__ */ new Map();
479
- // cached generated rule by breakpoint
480
- #cache = /* @__PURE__ */ new Map();
481
- constructor(mixinRules, selector, descendantSuffix) {
482
- this.#selector = selector;
483
- this.#descendantSuffix = descendantSuffix;
484
- this.#mixinRules = mixinRules;
485
- }
486
- getSelector() {
487
- return this.#selector;
488
- }
489
- setSelector(selector) {
490
- this.#selector = selector;
491
- this.#cache.clear();
492
- }
493
- getDescendantSuffix() {
494
- return this.#descendantSuffix;
495
- }
496
- addMixin(mixin) {
497
- this.#mixins.add(mixin);
498
- this.#cache.clear();
499
- }
500
- applyMixins(mixins) {
501
- this.#mixins = new Set(mixins);
502
- this.#cache.clear();
503
- }
504
- setDeclaration(declaration) {
505
- declaration = normalizeDeclaration(declaration);
506
- this.#declarations.set(getDeclarationKey(declaration), declaration);
507
- this.#cache.delete(declaration.breakpoint);
508
- }
509
- deleteDeclaration(declaration) {
510
- declaration = normalizeDeclaration(declaration);
511
- this.#declarations.delete(getDeclarationKey(declaration));
512
- this.#cache.delete(declaration.breakpoint);
513
- }
514
- #getDeclarations() {
515
- const declarations = /* @__PURE__ */ new Map();
516
- for (const mixin of this.#mixins) {
517
- const rule = this.#mixinRules.get(mixin);
518
- if (rule === void 0) {
519
- continue;
520
- }
521
- for (const declaration of rule.getDeclarations()) {
522
- declarations.set(getDeclarationKey(declaration), declaration);
523
- }
524
- }
525
- for (const declaration of this.#declarations.values()) {
526
- declarations.set(getDeclarationKey(declaration), declaration);
527
- }
528
- return declarations.values();
529
- }
530
- getMergedDeclarations() {
531
- return mergeDeclarations(this.#getDeclarations());
532
- }
533
- toString({
534
- breakpoint,
535
- indent = 0,
536
- transformValue
537
- }) {
538
- for (const mixin of this.#mixins) {
539
- const rule = this.#mixinRules.get(mixin);
540
- if (rule?.isDirtyBreakpoint(breakpoint)) {
541
- this.#cache.delete(breakpoint);
542
- }
543
- }
544
- const cached = this.#cache.get(breakpoint);
545
- if (cached && cached.indent === indent && cached.transformValue === transformValue) {
546
- return cached.generated;
547
- }
548
- const styleBySelector = /* @__PURE__ */ new Map();
549
- for (const declaration of this.getMergedDeclarations()) {
550
- if (declaration.breakpoint !== breakpoint) {
551
- continue;
552
- }
553
- const { selector: nestedSelector } = declaration;
554
- const selector = this.#selector + this.#descendantSuffix + nestedSelector;
555
- let style = styleBySelector.get(selector);
556
- if (style === void 0) {
557
- style = /* @__PURE__ */ new Map();
558
- styleBySelector.set(selector, style);
559
- }
560
- style.set(declaration.property, declaration.value);
561
- }
562
- const spaces = " ".repeat(indent);
563
- const generated = Array.from(styleBySelector).sort(
564
- ([leftSelector], [rightSelector]) => leftSelector.localeCompare(rightSelector)
565
- ).map(([selector, style]) => {
566
- const content = generateStyleMap({
567
- style: prefixStyles(style),
568
- indent: indent + 2,
569
- transformValue
570
- });
571
- return `${spaces}${selector} {
572
- ${content}
573
- ${spaces}}
574
- `;
575
- }).join("").trimEnd();
576
- this.#cache.set(breakpoint, { generated, indent, transformValue });
577
- return generated;
578
- }
579
- };
580
- var MediaRule = class {
581
- #name;
582
- options;
583
- rules;
584
- #mediaType;
585
- constructor(name, options = {}) {
586
- this.#name = name;
587
- this.options = options;
588
- this.rules = /* @__PURE__ */ new Map();
589
- this.#mediaType = options.mediaType ?? "all";
590
- }
591
- insertRule(rule) {
592
- this.rules.set(rule.cssText, rule);
593
- return rule;
594
- }
595
- get cssText() {
596
- return this.toString();
597
- }
598
- toString() {
599
- return this.generateRule({ nestingRules: [] });
600
- }
601
- generateRule({
602
- nestingRules,
603
- transformValue
604
- }) {
605
- if (this.rules.size === 0 && nestingRules.length === 0) {
606
- return "";
607
- }
608
- const rules = [];
609
- for (const rule of this.rules.values()) {
610
- rules.push(rule.toString());
611
- }
612
- for (const rule of nestingRules) {
613
- const generatedRule = rule.toString({
614
- breakpoint: this.#name,
615
- indent: 2,
616
- transformValue
617
- });
618
- if (generatedRule !== "") {
619
- rules.push(generatedRule);
620
- }
621
- }
622
- if (rules.length === 0) {
623
- return "";
624
- }
625
- let conditionText = "";
626
- const { minWidth, maxWidth } = this.options;
627
- if (minWidth !== void 0) {
628
- conditionText = ` and (min-width: ${minWidth}px)`;
629
- }
630
- if (maxWidth !== void 0) {
631
- conditionText += ` and (max-width: ${maxWidth}px)`;
632
- }
633
- return `@media ${this.#mediaType}${conditionText} {
634
- ${rules.join(
635
- "\n"
636
- )}
637
- }`;
638
- }
639
- };
640
- var PlaintextRule = class {
641
- cssText;
642
- constructor(cssText) {
643
- this.cssText = cssText;
644
- }
645
- toString() {
646
- return this.cssText;
647
- }
648
- };
649
- var FontFaceRule = class {
650
- #cached;
651
- #options;
652
- constructor(options) {
653
- this.#options = options;
654
- }
655
- get cssText() {
656
- return this.toString();
657
- }
658
- toString() {
659
- if (this.#cached) {
660
- return this.#cached;
661
- }
662
- const decls = [];
663
- const { fontFamily, fontStyle, fontWeight, fontDisplay, src } = this.#options;
664
- const value = toValue(
665
- { type: "fontFamily", value: [fontFamily] },
666
- // Avoids adding a fallback automatically which needs to happen for font family in general but not for font face.
667
- (value2) => value2
668
- );
669
- decls.push(`font-family: ${value}`);
670
- decls.push(`font-style: ${fontStyle}`);
671
- decls.push(`font-weight: ${fontWeight}`);
672
- decls.push(`font-display: ${fontDisplay}`);
673
- decls.push(`src: ${src}`);
674
- this.#cached = `@font-face {
675
- ${decls.join("; ")};
676
- }`;
677
- return this.#cached;
678
- }
679
- };
680
-
681
- // src/core/compare-media.ts
682
- var compareMedia = (optionA, optionB) => {
683
- if (optionA.minWidth === void 0 && optionA.maxWidth === void 0) {
684
- return -1;
685
- }
686
- if (optionB.minWidth === void 0 && optionB.maxWidth === void 0) {
687
- return 1;
688
- }
689
- if (optionA.minWidth !== void 0 && optionB.minWidth !== void 0) {
690
- return optionA.minWidth - optionB.minWidth;
691
- }
692
- if (optionA.maxWidth !== void 0 && optionB.maxWidth !== void 0) {
693
- return optionB.maxWidth - optionA.maxWidth;
694
- }
695
- return "minWidth" in optionA ? 1 : -1;
696
- };
697
-
698
- // src/core/style-element.ts
699
- var StyleElement = class {
700
- #element;
701
- #name;
702
- constructor(name = "") {
703
- this.#name = name;
704
- }
705
- get isMounted() {
706
- return this.#element?.parentElement != null;
707
- }
708
- mount() {
709
- if (this.isMounted === false) {
710
- this.#element = document.createElement("style");
711
- this.#element.setAttribute("data-webstudio", this.#name);
712
- document.head.appendChild(this.#element);
713
- }
714
- }
715
- unmount() {
716
- if (this.isMounted) {
717
- this.#element?.parentElement?.removeChild(this.#element);
718
- this.#element = void 0;
719
- }
720
- }
721
- render(cssText) {
722
- if (this.#element) {
723
- this.#element.textContent = cssText;
724
- }
725
- }
726
- setAttribute(name, value) {
727
- if (this.#element) {
728
- this.#element.setAttribute(name, value);
729
- }
730
- }
731
- getAttribute(name) {
732
- if (this.#element) {
733
- return this.#element.getAttribute(name);
734
- }
735
- }
736
- };
737
-
738
- // src/core/style-sheet.ts
739
- var StyleSheet = class {
740
- #cssText = "";
741
- #mediaRules = /* @__PURE__ */ new Map();
742
- #plainRules = /* @__PURE__ */ new Map();
743
- #mixinRules = /* @__PURE__ */ new Map();
744
- nestingRules = /* @__PURE__ */ new Map();
745
- #fontFaceRules = [];
746
- #transformValue;
747
- #element;
748
- constructor(element) {
749
- this.#element = element;
750
- }
751
- setTransformer(transformValue) {
752
- this.#transformValue = transformValue;
753
- }
754
- addMediaRule(id, options) {
755
- let mediaRule = this.#mediaRules.get(id);
756
- if (mediaRule === void 0) {
757
- mediaRule = new MediaRule(id, options);
758
- this.#mediaRules.set(id, mediaRule);
759
- return mediaRule;
760
- }
761
- if (options) {
762
- mediaRule.options = options;
763
- }
764
- if (mediaRule === void 0) {
765
- throw new Error("No media rule found");
766
- }
767
- return mediaRule;
768
- }
769
- addPlaintextRule(cssText) {
770
- const rule = this.#plainRules.get(cssText);
771
- if (rule !== void 0) {
772
- return rule;
773
- }
774
- return this.#plainRules.set(cssText, new PlaintextRule(cssText));
775
- }
776
- addMixinRule(name) {
777
- let rule = this.#mixinRules.get(name);
778
- if (rule === void 0) {
779
- rule = new MixinRule();
780
- this.#mixinRules.set(name, rule);
781
- }
782
- return rule;
783
- }
784
- addNestingRule(selector, descendantSuffix = "") {
785
- const key = selector + descendantSuffix;
786
- let rule = this.nestingRules.get(key);
787
- if (rule === void 0) {
788
- rule = new NestingRule(this.#mixinRules, selector, descendantSuffix);
789
- this.nestingRules.set(key, rule);
790
- }
791
- return rule;
792
- }
793
- addFontFaceRule(options) {
794
- return this.#fontFaceRules.push(new FontFaceRule(options));
795
- }
796
- generateWith({
797
- nestingRules,
798
- transformValue
799
- }) {
800
- const css = [];
801
- css.push(...this.#fontFaceRules.map((rule) => rule.cssText));
802
- for (const plaintextRule of this.#plainRules.values()) {
803
- css.push(plaintextRule.cssText);
804
- }
805
- const sortedMediaRules = Array.from(this.#mediaRules.values()).sort(
806
- (ruleA, ruleB) => compareMedia(ruleA.options, ruleB.options)
807
- );
808
- for (const mediaRule of sortedMediaRules) {
809
- const cssText = mediaRule.generateRule({
810
- nestingRules,
811
- transformValue
812
- });
813
- if (cssText !== "") {
814
- css.push(cssText);
815
- }
816
- }
817
- for (const rule of this.#mixinRules.values()) {
818
- rule.clearBreakpoints();
819
- }
820
- this.#cssText = css.join("\n");
821
- return this.#cssText;
822
- }
823
- get cssText() {
824
- return this.generateWith({
825
- nestingRules: Array.from(this.nestingRules.values()),
826
- transformValue: this.#transformValue
827
- });
828
- }
829
- clear() {
830
- this.#mediaRules.clear();
831
- this.#mixinRules.clear();
832
- this.nestingRules.clear();
833
- this.#plainRules.clear();
834
- this.#fontFaceRules = [];
835
- }
836
- render() {
837
- this.#element.mount();
838
- this.#element.render(this.cssText);
839
- }
840
- unmount() {
841
- this.#element.unmount();
842
- }
843
- setAttribute(name, value) {
844
- this.#element.setAttribute(name, value);
845
- }
846
- getAttribute(name) {
847
- return this.#element.getAttribute(name);
848
- }
849
- };
850
-
851
- // src/core/style-sheet-regular.ts
852
- var StyleSheetRegular = class extends StyleSheet {
853
- };
854
-
855
- // src/core/create-style-sheet.ts
856
- var createRegularStyleSheet = (options) => {
857
- const element = new StyleElement(options?.name);
858
- return new StyleSheetRegular(element);
859
- };
860
-
861
- // src/core/match-media.ts
862
- var matchMedia = (options, width) => {
863
- const minWidth = options.minWidth ?? Number.MIN_SAFE_INTEGER;
864
- const maxWidth = options.maxWidth ?? Number.MAX_SAFE_INTEGER;
865
- return width >= minWidth && width <= maxWidth;
866
- };
867
-
868
- // src/core/equal-media.ts
869
- var equalMedia = (left, right) => {
870
- return left.minWidth === right.minWidth && left.maxWidth === right.maxWidth;
871
- };
872
-
873
- // src/core/find-applicable-media.ts
874
- var findApplicableMedia = (media, width) => {
875
- const sortedMedia = [...media].sort(compareMedia).reverse();
876
- for (const options of sortedMedia) {
877
- if (matchMedia(options, width)) {
878
- return options;
879
- }
880
- }
881
- };
882
-
883
- // src/core/atomic.ts
884
- import hash from "@emotion/hash";
885
- var generateAtomic = (sheet, options) => {
886
- const { getKey, transformValue } = options;
887
- const atomicRules = /* @__PURE__ */ new Map();
888
- const classes = options.classes ?? /* @__PURE__ */ new Map();
889
- for (const rule of sheet.nestingRules.values()) {
890
- const descendantSuffix = rule.getDescendantSuffix();
891
- const groupKey = getKey(rule);
892
- if (groupKey === void 0) {
893
- atomicRules.set(rule.getSelector(), rule);
894
- continue;
895
- }
896
- let classList = classes.get(groupKey);
897
- if (classList === void 0) {
898
- classList = [];
899
- classes.set(groupKey, classList);
900
- }
901
- for (const declaration of rule.getMergedDeclarations()) {
902
- const atomicHash = hash(
903
- descendantSuffix + declaration.breakpoint + declaration.selector + declaration.property + toValue(declaration.value, transformValue)
904
- );
905
- const className = `c${atomicHash}`;
906
- let atomicRule = atomicRules.get(atomicHash);
907
- if (atomicRule === void 0) {
908
- atomicRule = new NestingRule(
909
- /* @__PURE__ */ new Map(),
910
- `.${className}`,
911
- descendantSuffix
912
- );
913
- atomicRule.setDeclaration(declaration);
914
- atomicRules.set(atomicHash, atomicRule);
915
- }
916
- classList.push(className);
917
- }
918
- }
919
- const cssText = sheet.generateWith({
920
- nestingRules: Array.from(atomicRules.values()),
921
- transformValue
922
- });
923
- return { cssText, classes };
924
- };
925
- export {
926
- FunctionValue,
927
- GuaranteedInvalidValue,
928
- ImageValue,
929
- InvalidValue,
930
- KeywordValue,
931
- LayersValue,
932
- StyleValue,
933
- TupleValue,
934
- TupleValueItem,
935
- UnitValue,
936
- UnparsedValue,
937
- VarFallback,
938
- compareMedia,
939
- createRegularStyleSheet,
940
- cssWideKeywords,
941
- equalMedia,
942
- findApplicableMedia,
943
- generateAtomic,
944
- generateStyleMap,
945
- hyphenateProperty,
946
- matchMedia,
947
- mergeStyles,
948
- prefixStyles,
949
- toValue,
950
- toVarFallback
951
- };