css-engine-test-pb 0.0.5 → 0.0.7
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/dist/compiler.d.ts +7 -1
- package/dist/compiler.js +105 -3
- package/dist/engine.d.ts +1 -1
- package/dist/engine.js +4 -4
- package/dist/makeResetStyles.js +1 -1
- package/dist/types.d.ts +9 -0
- package/package.json +1 -1
package/dist/compiler.d.ts
CHANGED
|
@@ -4,8 +4,14 @@ interface CompiledRule {
|
|
|
4
4
|
cssText: string;
|
|
5
5
|
bucket: StyleBucket;
|
|
6
6
|
}
|
|
7
|
+
export type CompileMode = 'atomic' | 'monolithic';
|
|
7
8
|
export declare class StyleCompiler {
|
|
8
|
-
compile(styleDefinition: StyleRule): CompiledRule[];
|
|
9
|
+
compile(styleDefinition: StyleRule, mode?: CompileMode): CompiledRule[];
|
|
10
|
+
private compileAtomic;
|
|
11
|
+
private compileMonolithic;
|
|
12
|
+
private buildCSSBlock;
|
|
13
|
+
private buildMonolithicPseudos;
|
|
14
|
+
private buildMonolithicMedia;
|
|
9
15
|
private processProperties;
|
|
10
16
|
private processPseudos;
|
|
11
17
|
private processMediaQueries;
|
package/dist/compiler.js
CHANGED
|
@@ -1,13 +1,105 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { StyleBucket } from './types';
|
|
2
|
+
import { createClassName, hashString } from './utils/hash';
|
|
2
3
|
import { camelToKebab, isPseudoSelector, isMediaQuery, determineBucket } from './utils';
|
|
3
4
|
export class StyleCompiler {
|
|
4
|
-
compile(styleDefinition) {
|
|
5
|
+
compile(styleDefinition, mode = 'atomic') {
|
|
6
|
+
if (mode === 'monolithic') {
|
|
7
|
+
return this.compileMonolithic(styleDefinition);
|
|
8
|
+
}
|
|
9
|
+
return this.compileAtomic(styleDefinition);
|
|
10
|
+
}
|
|
11
|
+
compileAtomic(styleDefinition) {
|
|
5
12
|
const rules = [];
|
|
6
13
|
this.processProperties(styleDefinition, rules);
|
|
7
14
|
this.processPseudos(styleDefinition, rules);
|
|
8
15
|
this.processMediaQueries(styleDefinition, rules);
|
|
9
16
|
return rules;
|
|
10
17
|
}
|
|
18
|
+
compileMonolithic(styleDefinition) {
|
|
19
|
+
const hash = hashString(JSON.stringify(styleDefinition));
|
|
20
|
+
const className = 'r' + hash;
|
|
21
|
+
let cssText = '';
|
|
22
|
+
const mainStyles = this.buildCSSBlock(styleDefinition);
|
|
23
|
+
if (mainStyles) {
|
|
24
|
+
cssText += `.${className} { ${mainStyles} }\n`;
|
|
25
|
+
}
|
|
26
|
+
cssText += this.buildMonolithicPseudos(styleDefinition, className);
|
|
27
|
+
cssText += this.buildMonolithicMedia(styleDefinition, className);
|
|
28
|
+
return [{
|
|
29
|
+
className,
|
|
30
|
+
cssText: cssText.trim(),
|
|
31
|
+
bucket: StyleBucket.RESET
|
|
32
|
+
}];
|
|
33
|
+
}
|
|
34
|
+
buildCSSBlock(styles) {
|
|
35
|
+
let css = '';
|
|
36
|
+
for (const [property, value] of Object.entries(styles)) {
|
|
37
|
+
if (isPseudoSelector(property) || isMediaQuery(property)) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (value === undefined || value === null) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const kebabProperty = camelToKebab(property);
|
|
44
|
+
css += `${kebabProperty}: ${value}; `;
|
|
45
|
+
}
|
|
46
|
+
return css.trim();
|
|
47
|
+
}
|
|
48
|
+
buildMonolithicPseudos(styleDefinition, className) {
|
|
49
|
+
let css = '';
|
|
50
|
+
for (const [key, value] of Object.entries(styleDefinition)) {
|
|
51
|
+
if (isPseudoSelector(key) && value) {
|
|
52
|
+
const pseudoStyles = this.buildCSSBlock(value);
|
|
53
|
+
if (pseudoStyles) {
|
|
54
|
+
if (key.includes(',')) {
|
|
55
|
+
const selectors = key
|
|
56
|
+
.split(',')
|
|
57
|
+
.map(s => `.${className}${s.trim()}`)
|
|
58
|
+
.join(', ');
|
|
59
|
+
css += `${selectors} { ${pseudoStyles} }\n`;
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
css += `.${className}${key} { ${pseudoStyles} }\n`;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return css;
|
|
68
|
+
}
|
|
69
|
+
buildMonolithicMedia(styleDefinition, className) {
|
|
70
|
+
let css = '';
|
|
71
|
+
for (const [key, value] of Object.entries(styleDefinition)) {
|
|
72
|
+
if (isMediaQuery(key) && value) {
|
|
73
|
+
const nestedStyles = value;
|
|
74
|
+
let mediaCss = '';
|
|
75
|
+
const mainStyles = this.buildCSSBlock(nestedStyles);
|
|
76
|
+
if (mainStyles) {
|
|
77
|
+
mediaCss += `.${className} { ${mainStyles} }\n`;
|
|
78
|
+
}
|
|
79
|
+
for (const [nestedKey, nestedValue] of Object.entries(nestedStyles)) {
|
|
80
|
+
if (isPseudoSelector(nestedKey) && nestedValue) {
|
|
81
|
+
const pseudoStyles = this.buildCSSBlock(nestedValue);
|
|
82
|
+
if (pseudoStyles) {
|
|
83
|
+
if (nestedKey.includes(',')) {
|
|
84
|
+
const selectors = nestedKey
|
|
85
|
+
.split(',')
|
|
86
|
+
.map(s => `.${className}${s.trim()}`)
|
|
87
|
+
.join(', ');
|
|
88
|
+
mediaCss += `${selectors} { ${pseudoStyles} }\n`;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
mediaCss += `.${className}${nestedKey} { ${pseudoStyles} }\n`;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (mediaCss) {
|
|
97
|
+
css += `${key} {\n${mediaCss}}\n`;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return css;
|
|
102
|
+
}
|
|
11
103
|
processProperties(styles, rules, pseudo, media) {
|
|
12
104
|
Object.entries(styles).forEach(([property, value]) => {
|
|
13
105
|
if (isPseudoSelector(property) || isMediaQuery(property)) {
|
|
@@ -19,7 +111,17 @@ export class StyleCompiler {
|
|
|
19
111
|
const kebabProperty = camelToKebab(property);
|
|
20
112
|
const hashInput = `${kebabProperty}:${value}${pseudo || ''}${media || ''}`;
|
|
21
113
|
const className = createClassName(hashInput);
|
|
22
|
-
|
|
114
|
+
let selector;
|
|
115
|
+
if (pseudo && pseudo.includes(',')) {
|
|
116
|
+
const selectors = pseudo
|
|
117
|
+
.split(',')
|
|
118
|
+
.map(s => `.${className}${s.trim()}`)
|
|
119
|
+
.join(', ');
|
|
120
|
+
selector = selectors;
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
selector = pseudo ? `.${className}${pseudo}` : `.${className}`;
|
|
124
|
+
}
|
|
23
125
|
const cssRule = `${selector} { ${kebabProperty}: ${value}; }`;
|
|
24
126
|
const bucket = determineBucket(pseudo, media);
|
|
25
127
|
let cssText = cssRule;
|
package/dist/engine.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export declare class StyleEngine {
|
|
|
4
4
|
private insertion;
|
|
5
5
|
private cache;
|
|
6
6
|
constructor();
|
|
7
|
-
createStyle(styleDefinition: StyleRule): string;
|
|
7
|
+
createStyle(styleDefinition: StyleRule, mode?: 'atomic' | 'monolithic'): string;
|
|
8
8
|
createStyles(slots: StyleSlots): GeneratedClasses;
|
|
9
9
|
getCSSString(): string;
|
|
10
10
|
clear(): void;
|
package/dist/engine.js
CHANGED
|
@@ -6,12 +6,12 @@ export class StyleEngine {
|
|
|
6
6
|
this.insertion = new InsertionFactory();
|
|
7
7
|
this.cache = new Map();
|
|
8
8
|
}
|
|
9
|
-
createStyle(styleDefinition) {
|
|
10
|
-
const cacheKey = JSON.stringify(styleDefinition)
|
|
9
|
+
createStyle(styleDefinition, mode = 'atomic') {
|
|
10
|
+
const cacheKey = `${mode}:${JSON.stringify(styleDefinition)}`;
|
|
11
11
|
if (this.cache.has(cacheKey)) {
|
|
12
12
|
return this.cache.get(cacheKey);
|
|
13
13
|
}
|
|
14
|
-
const rules = this.compiler.compile(styleDefinition);
|
|
14
|
+
const rules = this.compiler.compile(styleDefinition, mode);
|
|
15
15
|
rules.forEach(rule => {
|
|
16
16
|
this.insertion.insertRule(rule.cssText, rule.bucket);
|
|
17
17
|
});
|
|
@@ -25,7 +25,7 @@ export class StyleEngine {
|
|
|
25
25
|
const resolvedStyle = typeof styleDefinition === 'function'
|
|
26
26
|
? styleDefinition()
|
|
27
27
|
: styleDefinition;
|
|
28
|
-
classes[slotName] = this.createStyle(resolvedStyle);
|
|
28
|
+
classes[slotName] = this.createStyle(resolvedStyle, 'atomic');
|
|
29
29
|
});
|
|
30
30
|
return classes;
|
|
31
31
|
}
|
package/dist/makeResetStyles.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getGlobalEngine } from './engine';
|
|
2
2
|
export function makeResetStyles(styleDefinition) {
|
|
3
3
|
const engine = getGlobalEngine();
|
|
4
|
-
const className = engine.createStyle(styleDefinition);
|
|
4
|
+
const className = engine.createStyle(styleDefinition, 'monolithic');
|
|
5
5
|
return () => className;
|
|
6
6
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -87,6 +87,14 @@ export interface CSSPseudos {
|
|
|
87
87
|
'::before'?: CSSProperties;
|
|
88
88
|
'::after'?: CSSProperties;
|
|
89
89
|
'::placeholder'?: CSSProperties;
|
|
90
|
+
':hover:active'?: CSSProperties;
|
|
91
|
+
':active:focus-visible'?: CSSProperties;
|
|
92
|
+
':hover:focus-visible'?: CSSProperties;
|
|
93
|
+
':hover:active, :hover:focus-visible'?: CSSProperties;
|
|
94
|
+
':hover:active,:hover:focus-visible'?: CSSProperties;
|
|
95
|
+
':hover:active, :active:focus-visible'?: CSSProperties;
|
|
96
|
+
':hover:active,:active:focus-visible'?: CSSProperties;
|
|
97
|
+
[key: `${':' | '::'}${string}`]: CSSProperties | undefined;
|
|
90
98
|
}
|
|
91
99
|
export interface CSSMediaQueries {
|
|
92
100
|
'@media (min-width: 480px)'?: CSSProperties & CSSPseudos;
|
|
@@ -95,6 +103,7 @@ export interface CSSMediaQueries {
|
|
|
95
103
|
'@media (min-width: 1440px)'?: CSSProperties & CSSPseudos;
|
|
96
104
|
'@media (prefers-color-scheme: dark)'?: CSSProperties & CSSPseudos;
|
|
97
105
|
'@media (prefers-reduced-motion: reduce)'?: CSSProperties & CSSPseudos;
|
|
106
|
+
[key: `@media ${string}`]: (CSSProperties & CSSPseudos) | undefined;
|
|
98
107
|
}
|
|
99
108
|
export type StyleRule = CSSProperties & CSSPseudos & CSSMediaQueries;
|
|
100
109
|
export type StyleDefinition = StyleRule | (() => StyleRule);
|