@webstudio-is/css-engine 0.60.0 → 0.62.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.
@@ -22,13 +22,16 @@ __export(compare_media_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(compare_media_exports);
24
24
  const compareMedia = (optionA, optionB) => {
25
- if (optionA?.minWidth === void 0 && optionA?.maxWidth !== void 0 || optionB?.minWidth === void 0 && optionB?.maxWidth !== void 0) {
25
+ if (optionA.minWidth === void 0 && optionA.maxWidth === void 0) {
26
+ return -1;
27
+ }
28
+ if (optionB.minWidth === void 0 && optionB.maxWidth === void 0) {
26
29
  return 1;
27
30
  }
28
- if (optionA?.minWidth !== void 0 && optionB?.minWidth !== void 0) {
31
+ if (optionA.minWidth !== void 0 && optionB.minWidth !== void 0) {
29
32
  return optionA.minWidth - optionB.minWidth;
30
33
  }
31
- if (optionA?.maxWidth !== void 0 && optionB?.maxWidth !== void 0) {
34
+ if (optionA.maxWidth !== void 0 && optionB.maxWidth !== void 0) {
32
35
  return optionB.maxWidth - optionA.maxWidth;
33
36
  }
34
37
  return "minWidth" in optionA ? 1 : -1;
@@ -66,6 +66,11 @@ class CssEngine {
66
66
  mediaRule = new import_rules.MediaRule(options);
67
67
  __privateGet(this, _mediaRules).set(id, mediaRule);
68
68
  __privateSet(this, _isDirty, true);
69
+ return mediaRule;
70
+ }
71
+ if (options) {
72
+ mediaRule.options = options;
73
+ __privateSet(this, _isDirty, true);
69
74
  }
70
75
  return mediaRule;
71
76
  }
@@ -24,7 +24,7 @@ module.exports = __toCommonJS(find_applicable_media_exports);
24
24
  var import_compare_media = require("./compare-media");
25
25
  var import_match_media = require("./match-media");
26
26
  const findApplicableMedia = (media, width) => {
27
- const sortedMedia = media.sort(import_compare_media.compareMedia).reverse();
27
+ const sortedMedia = [...media].sort(import_compare_media.compareMedia).reverse();
28
28
  for (const options of sortedMedia) {
29
29
  if ((0, import_match_media.matchMedia)(options, width)) {
30
30
  return options;
@@ -1,11 +1,14 @@
1
1
  const compareMedia = (optionA, optionB) => {
2
- if (optionA?.minWidth === void 0 && optionA?.maxWidth !== void 0 || optionB?.minWidth === void 0 && optionB?.maxWidth !== void 0) {
2
+ if (optionA.minWidth === void 0 && optionA.maxWidth === void 0) {
3
+ return -1;
4
+ }
5
+ if (optionB.minWidth === void 0 && optionB.maxWidth === void 0) {
3
6
  return 1;
4
7
  }
5
- if (optionA?.minWidth !== void 0 && optionB?.minWidth !== void 0) {
8
+ if (optionA.minWidth !== void 0 && optionB.minWidth !== void 0) {
6
9
  return optionA.minWidth - optionB.minWidth;
7
10
  }
8
- if (optionA?.maxWidth !== void 0 && optionB?.maxWidth !== void 0) {
11
+ if (optionA.maxWidth !== void 0 && optionB.maxWidth !== void 0) {
9
12
  return optionB.maxWidth - optionA.maxWidth;
10
13
  }
11
14
  return "minWidth" in optionA ? 1 : -1;
@@ -48,6 +48,11 @@ class CssEngine {
48
48
  mediaRule = new MediaRule(options);
49
49
  __privateGet(this, _mediaRules).set(id, mediaRule);
50
50
  __privateSet(this, _isDirty, true);
51
+ return mediaRule;
52
+ }
53
+ if (options) {
54
+ mediaRule.options = options;
55
+ __privateSet(this, _isDirty, true);
51
56
  }
52
57
  return mediaRule;
53
58
  }
@@ -1,7 +1,7 @@
1
1
  import { compareMedia } from "./compare-media";
2
2
  import { matchMedia } from "./match-media";
3
3
  const findApplicableMedia = (media, width) => {
4
- const sortedMedia = media.sort(compareMedia).reverse();
4
+ const sortedMedia = [...media].sort(compareMedia).reverse();
5
5
  for (const options of sortedMedia) {
6
6
  if (matchMedia(options, width)) {
7
7
  return options;
@@ -7,7 +7,7 @@ declare class StylePropertyMap {
7
7
  setTransformer(transformValue: TransformValue): void;
8
8
  set(property: StyleProperty, value?: StyleValue): void;
9
9
  has(property: StyleProperty): boolean;
10
- keys(): IterableIterator<"color" | "left" | "right" | "top" | "bottom" | "contain" | "clip" | "content" | `--${string}` | "accentColor" | "alignContent" | "alignItems" | "alignSelf" | "alignTracks" | "animationComposition" | "animationDelay" | "animationDirection" | "animationDuration" | "animationFillMode" | "animationIterationCount" | "animationName" | "animationPlayState" | "animationTimingFunction" | "animationTimeline" | "appearance" | "aspectRatio" | "backdropFilter" | "backfaceVisibility" | "backgroundAttachment" | "backgroundBlendMode" | "backgroundClip" | "backgroundColor" | "backgroundImage" | "backgroundOrigin" | "backgroundPosition" | "backgroundPositionX" | "backgroundPositionY" | "backgroundRepeat" | "backgroundSize" | "blockOverflow" | "blockSize" | "borderBlockColor" | "borderBlockStyle" | "borderBlockWidth" | "borderBlockEndColor" | "borderBlockEndStyle" | "borderBlockEndWidth" | "borderBlockStartColor" | "borderBlockStartStyle" | "borderBlockStartWidth" | "borderBottomColor" | "borderBottomLeftRadius" | "borderBottomRightRadius" | "borderBottomStyle" | "borderBottomWidth" | "borderCollapse" | "borderEndEndRadius" | "borderEndStartRadius" | "borderImageOutset" | "borderImageRepeat" | "borderImageSlice" | "borderImageSource" | "borderImageWidth" | "borderInlineColor" | "borderInlineStyle" | "borderInlineWidth" | "borderInlineEndColor" | "borderInlineEndStyle" | "borderInlineEndWidth" | "borderInlineStartColor" | "borderInlineStartStyle" | "borderInlineStartWidth" | "borderLeftColor" | "borderLeftStyle" | "borderLeftWidth" | "borderRightColor" | "borderRightStyle" | "borderRightWidth" | "borderSpacing" | "borderStartEndRadius" | "borderStartStartRadius" | "borderTopColor" | "borderTopLeftRadius" | "borderTopRightRadius" | "borderTopStyle" | "borderTopWidth" | "boxDecorationBreak" | "boxShadow" | "boxSizing" | "breakAfter" | "breakBefore" | "breakInside" | "captionSide" | "caretColor" | "caretShape" | "clear" | "clipPath" | "printColorAdjust" | "colorScheme" | "columnCount" | "columnFill" | "columnGap" | "columnRuleColor" | "columnRuleStyle" | "columnRuleWidth" | "columnSpan" | "columnWidth" | "containIntrinsicBlockSize" | "containIntrinsicHeight" | "containIntrinsicInlineSize" | "containIntrinsicWidth" | "contentVisibility" | "counterIncrement" | "counterReset" | "counterSet" | "cursor" | "direction" | "display" | "emptyCells" | "filter" | "flexBasis" | "flexDirection" | "flexGrow" | "flexShrink" | "flexWrap" | "float" | "fontFamily" | "fontFeatureSettings" | "fontKerning" | "fontLanguageOverride" | "fontOpticalSizing" | "fontVariationSettings" | "fontSize" | "fontSizeAdjust" | "fontStretch" | "fontStyle" | "fontSynthesis" | "fontVariant" | "fontVariantAlternates" | "fontVariantCaps" | "fontVariantEastAsian" | "fontVariantLigatures" | "fontVariantNumeric" | "fontVariantPosition" | "fontWeight" | "forcedColorAdjust" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridColumnEnd" | "gridColumnStart" | "gridRowEnd" | "gridRowStart" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "hangingPunctuation" | "height" | "hyphenateCharacter" | "hyphens" | "imageOrientation" | "imageRendering" | "imageResolution" | "initialLetter" | "initialLetterAlign" | "inlineSize" | "inputSecurity" | "insetBlockEnd" | "insetBlockStart" | "insetInlineEnd" | "insetInlineStart" | "isolation" | "justifyContent" | "justifyItems" | "justifySelf" | "justifyTracks" | "letterSpacing" | "lineBreak" | "lineClamp" | "lineHeight" | "lineHeightStep" | "listStyleImage" | "listStylePosition" | "listStyleType" | "marginBlockEnd" | "marginBlockStart" | "marginBottom" | "marginInlineEnd" | "marginInlineStart" | "marginLeft" | "marginRight" | "marginTop" | "marginTrim" | "maskBorderMode" | "maskBorderOutset" | "maskBorderRepeat" | "maskBorderSlice" | "maskBorderSource" | "maskBorderWidth" | "maskClip" | "maskComposite" | "maskImage" | "maskMode" | "maskOrigin" | "maskPosition" | "maskRepeat" | "maskSize" | "maskType" | "masonryAutoFlow" | "mathDepth" | "mathShift" | "mathStyle" | "maxBlockSize" | "maxHeight" | "maxInlineSize" | "maxLines" | "maxWidth" | "minBlockSize" | "minHeight" | "minInlineSize" | "minWidth" | "mixBlendMode" | "objectFit" | "objectPosition" | "offsetAnchor" | "offsetDistance" | "offsetPath" | "offsetPosition" | "offsetRotate" | "opacity" | "order" | "orphans" | "outlineColor" | "outlineOffset" | "outlineStyle" | "outlineWidth" | "overflow" | "overflowAnchor" | "overflowBlock" | "overflowClipMargin" | "overflowInline" | "overflowWrap" | "overflowX" | "overflowY" | "overscrollBehavior" | "overscrollBehaviorBlock" | "overscrollBehaviorInline" | "overscrollBehaviorX" | "overscrollBehaviorY" | "paddingBlockEnd" | "paddingBlockStart" | "paddingBottom" | "paddingInlineEnd" | "paddingInlineStart" | "paddingLeft" | "paddingRight" | "paddingTop" | "pageBreakAfter" | "pageBreakBefore" | "pageBreakInside" | "paintOrder" | "perspective" | "perspectiveOrigin" | "pointerEvents" | "position" | "quotes" | "resize" | "rotate" | "rowGap" | "rubyAlign" | "rubyMerge" | "rubyPosition" | "scale" | "scrollbarColor" | "scrollbarGutter" | "scrollbarWidth" | "scrollBehavior" | "scrollMarginBlockStart" | "scrollMarginBlockEnd" | "scrollMarginBottom" | "scrollMarginInlineStart" | "scrollMarginInlineEnd" | "scrollMarginLeft" | "scrollMarginRight" | "scrollMarginTop" | "scrollPaddingBlockStart" | "scrollPaddingBlockEnd" | "scrollPaddingBottom" | "scrollPaddingInlineStart" | "scrollPaddingInlineEnd" | "scrollPaddingLeft" | "scrollPaddingRight" | "scrollPaddingTop" | "scrollSnapAlign" | "scrollSnapStop" | "scrollSnapType" | "scrollTimelineAxis" | "scrollTimelineName" | "shapeImageThreshold" | "shapeMargin" | "shapeOutside" | "tabSize" | "tableLayout" | "textAlign" | "textAlignLast" | "textCombineUpright" | "textDecorationColor" | "textDecorationLine" | "textDecorationSkip" | "textDecorationSkipInk" | "textDecorationStyle" | "textDecorationThickness" | "textEmphasisColor" | "textEmphasisPosition" | "textEmphasisStyle" | "textIndent" | "textJustify" | "textOrientation" | "textOverflow" | "textRendering" | "textShadow" | "textSizeAdjust" | "textTransform" | "textUnderlineOffset" | "textUnderlinePosition" | "touchAction" | "transform" | "transformBox" | "transformOrigin" | "transformStyle" | "transitionDelay" | "transitionDuration" | "transitionProperty" | "transitionTimingFunction" | "translate" | "unicodeBidi" | "userSelect" | "verticalAlign" | "visibility" | "whiteSpace" | "widows" | "width" | "willChange" | "wordBreak" | "wordSpacing" | "wordWrap" | "writingMode" | "zIndex">;
10
+ keys(): IterableIterator<"clip" | "top" | "right" | `--${string}` | "accentColor" | "alignContent" | "alignItems" | "alignSelf" | "alignTracks" | "animationComposition" | "animationDelay" | "animationDirection" | "animationDuration" | "animationFillMode" | "animationIterationCount" | "animationName" | "animationPlayState" | "animationTimingFunction" | "animationTimeline" | "appearance" | "aspectRatio" | "backdropFilter" | "backfaceVisibility" | "backgroundAttachment" | "backgroundBlendMode" | "backgroundClip" | "backgroundColor" | "backgroundImage" | "backgroundOrigin" | "backgroundPosition" | "backgroundPositionX" | "backgroundPositionY" | "backgroundRepeat" | "backgroundSize" | "blockOverflow" | "blockSize" | "borderBlockColor" | "borderBlockStyle" | "borderBlockWidth" | "borderBlockEndColor" | "borderBlockEndStyle" | "borderBlockEndWidth" | "borderBlockStartColor" | "borderBlockStartStyle" | "borderBlockStartWidth" | "borderBottomColor" | "borderBottomLeftRadius" | "borderBottomRightRadius" | "borderBottomStyle" | "borderBottomWidth" | "borderCollapse" | "borderEndEndRadius" | "borderEndStartRadius" | "borderImageOutset" | "borderImageRepeat" | "borderImageSlice" | "borderImageSource" | "borderImageWidth" | "borderInlineColor" | "borderInlineStyle" | "borderInlineWidth" | "borderInlineEndColor" | "borderInlineEndStyle" | "borderInlineEndWidth" | "borderInlineStartColor" | "borderInlineStartStyle" | "borderInlineStartWidth" | "borderLeftColor" | "borderLeftStyle" | "borderLeftWidth" | "borderRightColor" | "borderRightStyle" | "borderRightWidth" | "borderSpacing" | "borderStartEndRadius" | "borderStartStartRadius" | "borderTopColor" | "borderTopLeftRadius" | "borderTopRightRadius" | "borderTopStyle" | "borderTopWidth" | "bottom" | "boxDecorationBreak" | "boxShadow" | "boxSizing" | "breakAfter" | "breakBefore" | "breakInside" | "captionSide" | "caretColor" | "caretShape" | "clear" | "clipPath" | "color" | "printColorAdjust" | "colorScheme" | "columnCount" | "columnFill" | "columnGap" | "columnRuleColor" | "columnRuleStyle" | "columnRuleWidth" | "columnSpan" | "columnWidth" | "contain" | "containIntrinsicBlockSize" | "containIntrinsicHeight" | "containIntrinsicInlineSize" | "containIntrinsicWidth" | "content" | "contentVisibility" | "counterIncrement" | "counterReset" | "counterSet" | "cursor" | "direction" | "display" | "emptyCells" | "filter" | "flexBasis" | "flexDirection" | "flexGrow" | "flexShrink" | "flexWrap" | "float" | "fontFamily" | "fontFeatureSettings" | "fontKerning" | "fontLanguageOverride" | "fontOpticalSizing" | "fontVariationSettings" | "fontSize" | "fontSizeAdjust" | "fontStretch" | "fontStyle" | "fontSynthesis" | "fontVariant" | "fontVariantAlternates" | "fontVariantCaps" | "fontVariantEastAsian" | "fontVariantLigatures" | "fontVariantNumeric" | "fontVariantPosition" | "fontWeight" | "forcedColorAdjust" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridColumnEnd" | "gridColumnStart" | "gridRowEnd" | "gridRowStart" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "hangingPunctuation" | "height" | "hyphenateCharacter" | "hyphens" | "imageOrientation" | "imageRendering" | "imageResolution" | "initialLetter" | "initialLetterAlign" | "inlineSize" | "inputSecurity" | "insetBlockEnd" | "insetBlockStart" | "insetInlineEnd" | "insetInlineStart" | "isolation" | "justifyContent" | "justifyItems" | "justifySelf" | "justifyTracks" | "left" | "letterSpacing" | "lineBreak" | "lineClamp" | "lineHeight" | "lineHeightStep" | "listStyleImage" | "listStylePosition" | "listStyleType" | "marginBlockEnd" | "marginBlockStart" | "marginBottom" | "marginInlineEnd" | "marginInlineStart" | "marginLeft" | "marginRight" | "marginTop" | "marginTrim" | "maskBorderMode" | "maskBorderOutset" | "maskBorderRepeat" | "maskBorderSlice" | "maskBorderSource" | "maskBorderWidth" | "maskClip" | "maskComposite" | "maskImage" | "maskMode" | "maskOrigin" | "maskPosition" | "maskRepeat" | "maskSize" | "maskType" | "masonryAutoFlow" | "mathDepth" | "mathShift" | "mathStyle" | "maxBlockSize" | "maxHeight" | "maxInlineSize" | "maxLines" | "maxWidth" | "minBlockSize" | "minHeight" | "minInlineSize" | "minWidth" | "mixBlendMode" | "objectFit" | "objectPosition" | "offsetAnchor" | "offsetDistance" | "offsetPath" | "offsetPosition" | "offsetRotate" | "opacity" | "order" | "orphans" | "outlineColor" | "outlineOffset" | "outlineStyle" | "outlineWidth" | "overflow" | "overflowAnchor" | "overflowBlock" | "overflowClipMargin" | "overflowInline" | "overflowWrap" | "overflowX" | "overflowY" | "overscrollBehavior" | "overscrollBehaviorBlock" | "overscrollBehaviorInline" | "overscrollBehaviorX" | "overscrollBehaviorY" | "paddingBlockEnd" | "paddingBlockStart" | "paddingBottom" | "paddingInlineEnd" | "paddingInlineStart" | "paddingLeft" | "paddingRight" | "paddingTop" | "pageBreakAfter" | "pageBreakBefore" | "pageBreakInside" | "paintOrder" | "perspective" | "perspectiveOrigin" | "pointerEvents" | "position" | "quotes" | "resize" | "rotate" | "rowGap" | "rubyAlign" | "rubyMerge" | "rubyPosition" | "scale" | "scrollbarColor" | "scrollbarGutter" | "scrollbarWidth" | "scrollBehavior" | "scrollMarginBlockStart" | "scrollMarginBlockEnd" | "scrollMarginBottom" | "scrollMarginInlineStart" | "scrollMarginInlineEnd" | "scrollMarginLeft" | "scrollMarginRight" | "scrollMarginTop" | "scrollPaddingBlockStart" | "scrollPaddingBlockEnd" | "scrollPaddingBottom" | "scrollPaddingInlineStart" | "scrollPaddingInlineEnd" | "scrollPaddingLeft" | "scrollPaddingRight" | "scrollPaddingTop" | "scrollSnapAlign" | "scrollSnapStop" | "scrollSnapType" | "scrollTimelineAxis" | "scrollTimelineName" | "shapeImageThreshold" | "shapeMargin" | "shapeOutside" | "tabSize" | "tableLayout" | "textAlign" | "textAlignLast" | "textCombineUpright" | "textDecorationColor" | "textDecorationLine" | "textDecorationSkip" | "textDecorationSkipInk" | "textDecorationStyle" | "textDecorationThickness" | "textEmphasisColor" | "textEmphasisPosition" | "textEmphasisStyle" | "textIndent" | "textJustify" | "textOrientation" | "textOverflow" | "textRendering" | "textShadow" | "textSizeAdjust" | "textTransform" | "textUnderlineOffset" | "textUnderlinePosition" | "touchAction" | "transform" | "transformBox" | "transformOrigin" | "transformStyle" | "transitionDelay" | "transitionDuration" | "transitionProperty" | "transitionTimingFunction" | "translate" | "unicodeBidi" | "userSelect" | "verticalAlign" | "visibility" | "whiteSpace" | "widows" | "width" | "willChange" | "wordBreak" | "wordSpacing" | "wordWrap" | "writingMode" | "zIndex">;
11
11
  delete(property: StyleProperty): void;
12
12
  clear(): void;
13
13
  toString(): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webstudio-is/css-engine",
3
- "version": "0.60.0",
3
+ "version": "0.62.0",
4
4
  "description": "CSS Renderer for Webstudio",
5
5
  "author": "Webstudio <github@webstudio.is>",
6
6
  "homepage": "https://webstudio.is",
@@ -9,8 +9,8 @@
9
9
  "hyphenate-style-name": "^1.0.4",
10
10
  "react": "^18.2.0",
11
11
  "react-dom": "^18.2.0",
12
- "@webstudio-is/css-data": "^0.60.0",
13
- "@webstudio-is/fonts": "^0.60.0"
12
+ "@webstudio-is/css-data": "^0.62.0",
13
+ "@webstudio-is/fonts": "^0.62.0"
14
14
  },
15
15
  "devDependencies": {
16
16
  "@jest/globals": "^29.3.1",
@@ -20,10 +20,10 @@
20
20
  "@types/react-dom": "^18.0.11",
21
21
  "jest": "^29.3.1",
22
22
  "typescript": "5.0.3",
23
- "@webstudio-is/jest-config": "^1.0.5",
23
+ "@webstudio-is/jest-config": "^1.0.6",
24
24
  "@webstudio-is/scripts": "^0.0.0",
25
25
  "@webstudio-is/storybook-config": "^0.0.0",
26
- "@webstudio-is/tsconfig": "^1.0.5"
26
+ "@webstudio-is/tsconfig": "^1.0.6"
27
27
  },
28
28
  "exports": {
29
29
  "source": "./src/index.ts",
@@ -2,33 +2,55 @@ import { describe, test, expect } from "@jest/globals";
2
2
  import { compareMedia } from "./compare-media";
3
3
 
4
4
  describe("Compare media", () => {
5
- test("mobile first", () => {
5
+ test("min-width", () => {
6
6
  const initial = [
7
+ {},
8
+ { minWidth: 1280 },
9
+ { minWidth: 0 },
10
+ { minWidth: 1024 },
11
+ { minWidth: 768 },
12
+ ];
13
+ const expected = [
14
+ {},
7
15
  { minWidth: 0 },
8
16
  { minWidth: 768 },
9
17
  { minWidth: 1024 },
10
18
  { minWidth: 1280 },
11
19
  ];
12
- expect(initial.sort(compareMedia)).toStrictEqual(initial);
20
+ const sorted = initial.sort(compareMedia);
21
+ expect(sorted).toStrictEqual(expected);
13
22
  });
14
23
 
15
- test("random minWidth", () => {
16
- const initial = [{ minWidth: 0 }, { minWidth: 3 }, { minWidth: 2 }];
17
- const sorted = [{ minWidth: 0 }, { minWidth: 2 }, { minWidth: 3 }];
18
- expect(initial.sort(compareMedia)).toStrictEqual(sorted);
24
+ test("max-width", () => {
25
+ const initial = [
26
+ {},
27
+ { maxWidth: 1280 },
28
+ { maxWidth: 0 },
29
+ { maxWidth: 1024 },
30
+ { maxWidth: 768 },
31
+ ];
32
+ const expected = [
33
+ {},
34
+ { maxWidth: 1280 },
35
+ { maxWidth: 1024 },
36
+ { maxWidth: 768 },
37
+ { maxWidth: 0 },
38
+ ];
39
+ const sorted = initial.sort(compareMedia);
40
+ expect(sorted).toStrictEqual(expected);
19
41
  });
20
42
 
21
- test("webflow", () => {
43
+ test("mixed max and min", () => {
22
44
  const initial = [
23
45
  {},
24
46
  { maxWidth: 991 },
25
- { maxWidth: 767 },
26
47
  { maxWidth: 479 },
27
- { minWidth: 1280 },
48
+ { maxWidth: 767 },
28
49
  { minWidth: 1440 },
50
+ { minWidth: 1280 },
29
51
  { minWidth: 1920 },
30
52
  ];
31
- const sorted = [
53
+ const expected = [
32
54
  {},
33
55
  { maxWidth: 991 },
34
56
  { maxWidth: 767 },
@@ -37,6 +59,7 @@ describe("Compare media", () => {
37
59
  { minWidth: 1440 },
38
60
  { minWidth: 1920 },
39
61
  ];
40
- expect(initial.sort(compareMedia)).toStrictEqual(sorted);
62
+ const sorted = initial.sort(compareMedia);
63
+ expect(sorted).toStrictEqual(expected);
41
64
  });
42
65
  });
@@ -9,18 +9,19 @@ export const compareMedia = (
9
9
  optionB: MediaRuleOptions
10
10
  ) => {
11
11
  // Ensures a media with no min/max is always first
12
- if (
13
- (optionA?.minWidth === undefined && optionA?.maxWidth !== undefined) ||
14
- (optionB?.minWidth === undefined && optionB?.maxWidth !== undefined)
15
- ) {
12
+ if (optionA.minWidth === undefined && optionA.maxWidth === undefined) {
13
+ return -1;
14
+ }
15
+ if (optionB.minWidth === undefined && optionB.maxWidth === undefined) {
16
16
  return 1;
17
17
  }
18
+
18
19
  // Both are defined by minWidth, put the bigger one first
19
- if (optionA?.minWidth !== undefined && optionB?.minWidth !== undefined) {
20
+ if (optionA.minWidth !== undefined && optionB.minWidth !== undefined) {
20
21
  return optionA.minWidth - optionB.minWidth;
21
22
  }
22
23
  // Both are defined by maxWidth, put the smaller one first
23
- if (optionA?.maxWidth !== undefined && optionB?.maxWidth !== undefined) {
24
+ if (optionA.maxWidth !== undefined && optionB.maxWidth !== undefined) {
24
25
  return optionB.maxWidth - optionA.maxWidth;
25
26
  }
26
27
 
@@ -266,6 +266,27 @@ describe("CssEngine", () => {
266
266
  `);
267
267
  });
268
268
 
269
+ test("update media rule options", () => {
270
+ engine.addMediaRule(mediaId0, mediaRuleOptions0);
271
+ engine.addStyleRule(".c", {
272
+ style: {
273
+ color: { type: "keyword", value: "red" },
274
+ },
275
+ breakpoint: "0",
276
+ });
277
+ expect(engine.cssText).toMatchInlineSnapshot(`
278
+ "@media all and (min-width: 0px) {
279
+ .c { color: red }
280
+ }"
281
+ `);
282
+ engine.addMediaRule(mediaId0, { minWidth: 10 });
283
+ expect(engine.cssText).toMatchInlineSnapshot(`
284
+ "@media all and (min-width: 10px) {
285
+ .c { color: red }
286
+ }"
287
+ `);
288
+ });
289
+
269
290
  test("don't override media queries", () => {
270
291
  engine.addMediaRule(mediaId0, mediaRuleOptions0);
271
292
  engine.addStyleRule(".c", {
@@ -39,7 +39,14 @@ export class CssEngine {
39
39
  mediaRule = new MediaRule(options);
40
40
  this.#mediaRules.set(id, mediaRule);
41
41
  this.#isDirty = true;
42
+ return mediaRule;
42
43
  }
44
+
45
+ if (options) {
46
+ mediaRule.options = options;
47
+ this.#isDirty = true;
48
+ }
49
+
43
50
  return mediaRule;
44
51
  }
45
52
  addStyleRule(
@@ -7,7 +7,7 @@ export const findApplicableMedia = <Media extends MediaRuleOptions>(
7
7
  media: Array<Media>,
8
8
  width: number
9
9
  ) => {
10
- const sortedMedia = media
10
+ const sortedMedia = [...media]
11
11
  .sort(compareMedia)
12
12
  // Reverse order is needed because the last rule in CSSOM has higher source order specificity.
13
13
  .reverse();