@webstudio-is/css-engine 0.238.0 → 0.252.1
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/index.js +44 -8
- package/lib/types/core/compare-media.d.ts +5 -2
- package/lib/types/core/create-style-sheet.d.ts +2 -0
- package/lib/types/core/equal-media.d.ts +4 -0
- package/lib/types/core/find-applicable-media.d.ts +5 -0
- package/lib/types/core/index.d.ts +1 -0
- package/lib/types/core/match-media.d.ts +5 -0
- package/lib/types/core/rules.d.ts +7 -0
- package/lib/types/core/rules.test.d.ts +1 -0
- package/lib/types/core/style-element.d.ts +12 -0
- package/lib/types/core/style-sheet.d.ts +3 -3
- package/package.json +3 -3
package/lib/index.js
CHANGED
|
@@ -720,12 +720,16 @@ var MediaRule = class {
|
|
|
720
720
|
return "";
|
|
721
721
|
}
|
|
722
722
|
let conditionText = "";
|
|
723
|
-
const { minWidth, maxWidth } = this.options;
|
|
724
|
-
if (
|
|
725
|
-
conditionText = ` and (
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
|
|
723
|
+
const { minWidth, maxWidth, condition } = this.options;
|
|
724
|
+
if (condition !== void 0) {
|
|
725
|
+
conditionText = ` and (${condition})`;
|
|
726
|
+
} else {
|
|
727
|
+
if (minWidth !== void 0) {
|
|
728
|
+
conditionText = ` and (min-width: ${minWidth}px)`;
|
|
729
|
+
}
|
|
730
|
+
if (maxWidth !== void 0) {
|
|
731
|
+
conditionText += ` and (max-width: ${maxWidth}px)`;
|
|
732
|
+
}
|
|
729
733
|
}
|
|
730
734
|
return `@media ${this.#mediaType}${conditionText} {
|
|
731
735
|
${rules.join(
|
|
@@ -777,6 +781,21 @@ var FontFaceRule = class {
|
|
|
777
781
|
|
|
778
782
|
// src/core/compare-media.ts
|
|
779
783
|
var compareMedia = (optionA, optionB) => {
|
|
784
|
+
if (optionA.condition !== void 0 && optionB.condition !== void 0) {
|
|
785
|
+
return optionA.condition.localeCompare(optionB.condition);
|
|
786
|
+
}
|
|
787
|
+
if (optionA.condition !== void 0) {
|
|
788
|
+
if (optionB.minWidth === void 0 && optionB.maxWidth === void 0) {
|
|
789
|
+
return 1;
|
|
790
|
+
}
|
|
791
|
+
return -1;
|
|
792
|
+
}
|
|
793
|
+
if (optionB.condition !== void 0) {
|
|
794
|
+
if (optionA.minWidth === void 0 && optionA.maxWidth === void 0) {
|
|
795
|
+
return -1;
|
|
796
|
+
}
|
|
797
|
+
return 1;
|
|
798
|
+
}
|
|
780
799
|
if (optionA.minWidth === void 0 && optionA.maxWidth === void 0) {
|
|
781
800
|
return -1;
|
|
782
801
|
}
|
|
@@ -831,6 +850,22 @@ var StyleElement = class {
|
|
|
831
850
|
}
|
|
832
851
|
}
|
|
833
852
|
};
|
|
853
|
+
var FakeStyleElement = class {
|
|
854
|
+
get isMounted() {
|
|
855
|
+
return false;
|
|
856
|
+
}
|
|
857
|
+
mount() {
|
|
858
|
+
}
|
|
859
|
+
unmount() {
|
|
860
|
+
}
|
|
861
|
+
render(_cssText) {
|
|
862
|
+
}
|
|
863
|
+
setAttribute(_name, _value) {
|
|
864
|
+
}
|
|
865
|
+
getAttribute(_name) {
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
};
|
|
834
869
|
|
|
835
870
|
// src/core/style-sheet.ts
|
|
836
871
|
var StyleSheet = class {
|
|
@@ -951,7 +986,7 @@ var StyleSheetRegular = class extends StyleSheet {
|
|
|
951
986
|
|
|
952
987
|
// src/core/create-style-sheet.ts
|
|
953
988
|
var createRegularStyleSheet = (options) => {
|
|
954
|
-
const element = new StyleElement(options?.name);
|
|
989
|
+
const element = options?.element ?? new StyleElement(options?.name);
|
|
955
990
|
return new StyleSheetRegular(element);
|
|
956
991
|
};
|
|
957
992
|
|
|
@@ -964,7 +999,7 @@ var matchMedia = (options, width) => {
|
|
|
964
999
|
|
|
965
1000
|
// src/core/equal-media.ts
|
|
966
1001
|
var equalMedia = (left, right) => {
|
|
967
|
-
return left.minWidth === right.minWidth && left.maxWidth === right.maxWidth;
|
|
1002
|
+
return left.minWidth === right.minWidth && left.maxWidth === right.maxWidth && left.condition === right.condition;
|
|
968
1003
|
};
|
|
969
1004
|
|
|
970
1005
|
// src/core/find-applicable-media.ts
|
|
@@ -1021,6 +1056,7 @@ var generateAtomic = (sheet, options) => {
|
|
|
1021
1056
|
};
|
|
1022
1057
|
export {
|
|
1023
1058
|
ColorValue,
|
|
1059
|
+
FakeStyleElement,
|
|
1024
1060
|
FunctionValue,
|
|
1025
1061
|
GuaranteedInvalidValue,
|
|
1026
1062
|
ImageValue,
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { MediaRuleOptions } from "./rules";
|
|
2
2
|
/**
|
|
3
|
-
* Sort
|
|
4
|
-
*
|
|
3
|
+
* Sort media queries for CSS cascade order.
|
|
4
|
+
* Width-based: minWidth descending, then maxWidth ascending
|
|
5
|
+
* Custom conditions: sorted alphabetically, placed between base and width-based
|
|
6
|
+
*
|
|
7
|
+
* Note: minWidth/maxWidth and condition are mutually exclusive in MediaRuleOptions.
|
|
5
8
|
*/
|
|
6
9
|
export declare const compareMedia: (optionA: MediaRuleOptions, optionB: MediaRuleOptions) => number;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { StyleSheetRegular } from "./style-sheet-regular";
|
|
2
|
+
import { StyleElement, FakeStyleElement } from "./style-element";
|
|
2
3
|
export declare const createRegularStyleSheet: (options?: {
|
|
3
4
|
name?: string;
|
|
5
|
+
element?: StyleElement | FakeStyleElement;
|
|
4
6
|
}) => StyleSheetRegular;
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
import type { MediaRuleOptions } from "./rules";
|
|
2
|
+
/**
|
|
3
|
+
* Compare two media query options for equality.
|
|
4
|
+
* Note: minWidth/maxWidth and condition are mutually exclusive.
|
|
5
|
+
*/
|
|
2
6
|
export declare const equalMedia: (left: MediaRuleOptions, right: MediaRuleOptions) => boolean;
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
import type { MediaRuleOptions } from "./rules";
|
|
2
|
+
/**
|
|
3
|
+
* Find the applicable media rule that matches the given width.
|
|
4
|
+
* Only matches width-based breakpoints (minWidth/maxWidth).
|
|
5
|
+
* Custom condition breakpoints are not matched by this function.
|
|
6
|
+
*/
|
|
2
7
|
export declare const findApplicableMedia: <Media extends MediaRuleOptions>(media: Array<Media>, width: number) => Media | undefined;
|
|
@@ -4,6 +4,7 @@ export { mergeStyles } from "./merger";
|
|
|
4
4
|
export { generateStyleMap } from "./rules";
|
|
5
5
|
export type { StyleSheetRegular } from "./style-sheet-regular";
|
|
6
6
|
export * from "./create-style-sheet";
|
|
7
|
+
export { FakeStyleElement } from "./style-element";
|
|
7
8
|
export * from "./to-value";
|
|
8
9
|
export { hyphenateProperty } from "./to-property";
|
|
9
10
|
export * from "./match-media";
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
import type { MediaRuleOptions } from "./rules";
|
|
2
|
+
/**
|
|
3
|
+
* Check if a media query matches a given width.
|
|
4
|
+
* Only applies to width-based breakpoints (minWidth/maxWidth).
|
|
5
|
+
* Custom condition breakpoints are not matched by this function.
|
|
6
|
+
*/
|
|
2
7
|
export declare const matchMedia: (options: MediaRuleOptions, width: number) => boolean;
|
|
@@ -68,9 +68,16 @@ export declare class NestingRule {
|
|
|
68
68
|
transformValue?: TransformValue;
|
|
69
69
|
}): string;
|
|
70
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Options for media queries.
|
|
73
|
+
* Note: minWidth/maxWidth and condition are mutually exclusive.
|
|
74
|
+
* If condition is set, minWidth and maxWidth must be undefined.
|
|
75
|
+
* If minWidth or maxWidth is set, condition must be undefined.
|
|
76
|
+
*/
|
|
71
77
|
export type MediaRuleOptions = {
|
|
72
78
|
minWidth?: number;
|
|
73
79
|
maxWidth?: number;
|
|
80
|
+
condition?: string;
|
|
74
81
|
mediaType?: "all" | "screen" | "print";
|
|
75
82
|
};
|
|
76
83
|
export declare class MediaRule {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -8,3 +8,15 @@ export declare class StyleElement {
|
|
|
8
8
|
setAttribute(name: string, value: string): void;
|
|
9
9
|
getAttribute(name: string): string | null | undefined;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* A fake style element that does nothing.
|
|
13
|
+
* Useful for testing stylesheets without DOM.
|
|
14
|
+
*/
|
|
15
|
+
export declare class FakeStyleElement {
|
|
16
|
+
get isMounted(): boolean;
|
|
17
|
+
mount(): void;
|
|
18
|
+
unmount(): void;
|
|
19
|
+
render(_cssText: string): void;
|
|
20
|
+
setAttribute(_name: string, _value: string): void;
|
|
21
|
+
getAttribute(_name: string): void;
|
|
22
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { MediaRule, MixinRule, NestingRule, PlaintextRule, type FontFaceOptions, type MediaRuleOptions } from "./rules";
|
|
2
|
-
import { StyleElement } from "./style-element";
|
|
2
|
+
import { StyleElement, FakeStyleElement } from "./style-element";
|
|
3
3
|
import type { TransformValue } from "./to-value";
|
|
4
4
|
export declare class StyleSheet {
|
|
5
5
|
#private;
|
|
6
6
|
nestingRules: Map<string, NestingRule>;
|
|
7
|
-
constructor(element: StyleElement);
|
|
7
|
+
constructor(element: StyleElement | FakeStyleElement);
|
|
8
8
|
setTransformer(transformValue: TransformValue): void;
|
|
9
9
|
addMediaRule(id: string, options?: MediaRuleOptions): MediaRule;
|
|
10
10
|
addPlaintextRule(cssText: string): PlaintextRule | Map<string, PlaintextRule>;
|
|
@@ -20,5 +20,5 @@ export declare class StyleSheet {
|
|
|
20
20
|
render(): void;
|
|
21
21
|
unmount(): void;
|
|
22
22
|
setAttribute(name: string, value: string): void;
|
|
23
|
-
getAttribute(name: string): string |
|
|
23
|
+
getAttribute(name: string): string | void | null;
|
|
24
24
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webstudio-is/css-engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.252.1",
|
|
4
4
|
"description": "CSS Renderer for Webstudio",
|
|
5
5
|
"author": "Webstudio <github@webstudio.is>",
|
|
6
6
|
"homepage": "https://webstudio.is",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@emotion/hash": "^0.9.2",
|
|
10
10
|
"zod": "^3.24.2",
|
|
11
|
-
"@webstudio-is/fonts": "0.
|
|
11
|
+
"@webstudio-is/fonts": "0.252.1"
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
14
14
|
"@types/react": "^18.2.70",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"private": false,
|
|
39
39
|
"sideEffects": false,
|
|
40
40
|
"scripts": {
|
|
41
|
-
"typecheck": "
|
|
41
|
+
"typecheck": "tsgo --noEmit",
|
|
42
42
|
"build": "rm -rf lib && esbuild src/index.ts --outdir=lib --bundle --format=esm --packages=external && esbuild src/runtime.ts --outdir=lib --bundle --format=esm --packages=external",
|
|
43
43
|
"dts": "tsc --project tsconfig.dts.json",
|
|
44
44
|
"test": "vitest run"
|