@tenphi/tasty 2.6.4 → 2.7.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/dist/{collector-C-keQH9m.js → collector-BWvvN7_y.js} +3 -3
- package/dist/{collector-C-keQH9m.js.map → collector-BWvvN7_y.js.map} +1 -1
- package/dist/{config-BBiyxMCe.js → config-DF2QZQEW.js} +421 -269
- package/dist/config-DF2QZQEW.js.map +1 -0
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +6 -6
- package/dist/{core-BO4319td.js → core-BbdGIKAK.js} +5 -5
- package/dist/core-BbdGIKAK.js.map +1 -0
- package/dist/{css-writer-BWvwQzz0.js → css-writer-Bh05D6KI.js} +3 -3
- package/dist/css-writer-Bh05D6KI.js.map +1 -0
- package/dist/{format-rules-BSjeH4Z7.js → format-rules-DCI2lomx.js} +2 -2
- package/dist/{format-rules-BSjeH4Z7.js.map → format-rules-DCI2lomx.js.map} +1 -1
- package/dist/{hydrate-CcvrP4qJ.js → hydrate-DsFfFPVK.js} +2 -2
- package/dist/{hydrate-CcvrP4qJ.js.map → hydrate-DsFfFPVK.js.map} +1 -1
- package/dist/{index-B_k47mc_.d.ts → index-D-OA_O6i.d.ts} +95 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/dist/{keyframes-BUQhdOSJ.js → keyframes-Dg95rDpN.js} +10 -3
- package/dist/keyframes-Dg95rDpN.js.map +1 -0
- package/dist/{merge-styles-Cd2vBl9b.js → merge-styles-Bnn6j_SA.js} +2 -2
- package/dist/{merge-styles-Cd2vBl9b.js.map → merge-styles-Bnn6j_SA.js.map} +1 -1
- package/dist/{resolve-recipes-C1nrvnYh.js → resolve-recipes-CBQaQ3tD.js} +3 -3
- package/dist/{resolve-recipes-C1nrvnYh.js.map → resolve-recipes-CBQaQ3tD.js.map} +1 -1
- package/dist/ssr/astro-client.js +1 -1
- package/dist/ssr/astro.js +3 -3
- package/dist/ssr/index.js +3 -3
- package/dist/ssr/next.js +4 -4
- package/dist/static/index.js +1 -1
- package/dist/zero/babel.js +4 -4
- package/dist/zero/index.js +1 -1
- package/docs/dsl.md +109 -0
- package/docs/pipeline.md +49 -4
- package/package.json +15 -6
- package/tasty.config.ts +1 -0
- package/dist/config-BBiyxMCe.js.map +0 -1
- package/dist/core-BO4319td.js.map +0 -1
- package/dist/css-writer-BWvwQzz0.js.map +0 -1
- package/dist/keyframes-BUQhdOSJ.js.map +0 -1
|
@@ -55,6 +55,223 @@ function canonicalFuncName(lowered) {
|
|
|
55
55
|
return CANONICAL_FUNC_CASE.get(lowered) ?? lowered;
|
|
56
56
|
}
|
|
57
57
|
//#endregion
|
|
58
|
+
//#region src/properties/index.ts
|
|
59
|
+
const PROPERTIES_KEY = "@properties";
|
|
60
|
+
/**
|
|
61
|
+
* Valid CSS custom property name pattern (after the -- prefix).
|
|
62
|
+
* Must start with a letter or underscore, followed by letters, digits, hyphens, or underscores.
|
|
63
|
+
*/
|
|
64
|
+
const VALID_PROPERTY_NAME_PATTERN = /^[a-z_][a-z0-9-_]*$/i;
|
|
65
|
+
/**
|
|
66
|
+
* Validate a CSS custom property name (the part after --).
|
|
67
|
+
* Returns true if the name is valid for use as a CSS custom property.
|
|
68
|
+
*/
|
|
69
|
+
function isValidPropertyName(name) {
|
|
70
|
+
return VALID_PROPERTY_NAME_PATTERN.test(name);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Check if styles object has local @properties definition.
|
|
74
|
+
* Fast path: single property lookup.
|
|
75
|
+
*/
|
|
76
|
+
function hasLocalProperties(styles) {
|
|
77
|
+
return PROPERTIES_KEY in styles;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Extract local @properties from styles object.
|
|
81
|
+
* Returns null if no local properties (fast path).
|
|
82
|
+
*/
|
|
83
|
+
function extractLocalProperties(styles) {
|
|
84
|
+
const properties = styles[PROPERTIES_KEY];
|
|
85
|
+
if (!properties || typeof properties !== "object") return null;
|
|
86
|
+
return properties;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Parse a property token name and return the CSS property name and whether it's a color.
|
|
90
|
+
* Supports tasty token syntax and validates the property name.
|
|
91
|
+
*
|
|
92
|
+
* Token formats:
|
|
93
|
+
* - `$name` → { cssName: '--name', isColor: false }
|
|
94
|
+
* - `#name` → { cssName: '--name-color', isColor: true }
|
|
95
|
+
* - `--name` → { cssName: '--name', isColor: false } (legacy, auto-detect color by suffix)
|
|
96
|
+
* - `name` → { cssName: '--name', isColor: false } (legacy)
|
|
97
|
+
*
|
|
98
|
+
* @param token - The property token to parse
|
|
99
|
+
* @returns Parsed result with cssName, isColor, isValid, and optional error
|
|
100
|
+
*/
|
|
101
|
+
function parsePropertyToken(token) {
|
|
102
|
+
if (!token || typeof token !== "string") return {
|
|
103
|
+
cssName: "",
|
|
104
|
+
isColor: false,
|
|
105
|
+
isValid: false,
|
|
106
|
+
error: "Property token must be a non-empty string"
|
|
107
|
+
};
|
|
108
|
+
let name;
|
|
109
|
+
let isColor;
|
|
110
|
+
if (token.startsWith("$")) {
|
|
111
|
+
name = token.slice(1);
|
|
112
|
+
isColor = false;
|
|
113
|
+
} else if (token.startsWith("#")) {
|
|
114
|
+
name = token.slice(1);
|
|
115
|
+
isColor = true;
|
|
116
|
+
} else if (token.startsWith("--")) {
|
|
117
|
+
name = token.slice(2);
|
|
118
|
+
isColor = token.endsWith("-color");
|
|
119
|
+
} else {
|
|
120
|
+
name = token;
|
|
121
|
+
isColor = token.endsWith("-color");
|
|
122
|
+
}
|
|
123
|
+
if (!name) return {
|
|
124
|
+
cssName: "",
|
|
125
|
+
isColor,
|
|
126
|
+
isValid: false,
|
|
127
|
+
error: "Property name cannot be empty"
|
|
128
|
+
};
|
|
129
|
+
if (!isValidPropertyName(name)) return {
|
|
130
|
+
cssName: "",
|
|
131
|
+
isColor,
|
|
132
|
+
isValid: false,
|
|
133
|
+
error: `Invalid property name "${name}". Must start with a letter or underscore, followed by letters, digits, hyphens, or underscores.`
|
|
134
|
+
};
|
|
135
|
+
let cssName;
|
|
136
|
+
if (token.startsWith("#")) cssName = `--${name}-color`;
|
|
137
|
+
else cssName = `--${name}`;
|
|
138
|
+
return {
|
|
139
|
+
cssName,
|
|
140
|
+
isColor,
|
|
141
|
+
isValid: true
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Normalize a property definition to a consistent string representation.
|
|
146
|
+
* Used for comparing definitions to detect type conflicts.
|
|
147
|
+
*
|
|
148
|
+
* Only `syntax` and `inherits` are compared — `initialValue` is intentionally
|
|
149
|
+
* excluded because different components may set different defaults for the
|
|
150
|
+
* same typed property (e.g. auto-inferred `0px` vs explicit `6px`).
|
|
151
|
+
*
|
|
152
|
+
* Keys are sorted alphabetically to ensure consistent comparison:
|
|
153
|
+
* { inherits: true, syntax: '<color>' } === { syntax: '<color>', inherits: true }
|
|
154
|
+
*/
|
|
155
|
+
function normalizePropertyDefinition(def) {
|
|
156
|
+
const normalized = {};
|
|
157
|
+
if (def.inherits !== void 0) normalized.inherits = def.inherits;
|
|
158
|
+
if (def.syntax !== void 0) normalized.syntax = def.syntax;
|
|
159
|
+
return JSON.stringify(normalized);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Get the effective property definition for a token.
|
|
163
|
+
* For color tokens (#name), auto-sets syntax to '<color>' and defaults initialValue to 'transparent'.
|
|
164
|
+
*
|
|
165
|
+
* @param token - Property token ($name, #name, --name, or plain name)
|
|
166
|
+
* @param userDefinition - User-provided definition options
|
|
167
|
+
* @returns Effective definition with cssName, definition, isValid, and optional error
|
|
168
|
+
*/
|
|
169
|
+
function getEffectiveDefinition(token, userDefinition) {
|
|
170
|
+
const parsed = parsePropertyToken(token);
|
|
171
|
+
if (!parsed.isValid) return {
|
|
172
|
+
cssName: "",
|
|
173
|
+
definition: userDefinition,
|
|
174
|
+
isColor: false,
|
|
175
|
+
isValid: false,
|
|
176
|
+
error: parsed.error
|
|
177
|
+
};
|
|
178
|
+
if (parsed.isColor) return {
|
|
179
|
+
cssName: parsed.cssName,
|
|
180
|
+
definition: {
|
|
181
|
+
syntax: "<color>",
|
|
182
|
+
inherits: userDefinition.inherits,
|
|
183
|
+
initialValue: userDefinition.initialValue ?? "transparent"
|
|
184
|
+
},
|
|
185
|
+
isColor: true,
|
|
186
|
+
isValid: true
|
|
187
|
+
};
|
|
188
|
+
return {
|
|
189
|
+
cssName: parsed.cssName,
|
|
190
|
+
definition: userDefinition,
|
|
191
|
+
isColor: false,
|
|
192
|
+
isValid: true
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
const UNIT_TO_SYNTAX = {};
|
|
196
|
+
const LENGTH_UNITS = [
|
|
197
|
+
"px",
|
|
198
|
+
"em",
|
|
199
|
+
"rem",
|
|
200
|
+
"vw",
|
|
201
|
+
"vh",
|
|
202
|
+
"vmin",
|
|
203
|
+
"vmax",
|
|
204
|
+
"ch",
|
|
205
|
+
"ex",
|
|
206
|
+
"cap",
|
|
207
|
+
"ic",
|
|
208
|
+
"lh",
|
|
209
|
+
"rlh",
|
|
210
|
+
"svw",
|
|
211
|
+
"svh",
|
|
212
|
+
"lvw",
|
|
213
|
+
"lvh",
|
|
214
|
+
"dvw",
|
|
215
|
+
"dvh",
|
|
216
|
+
"cqw",
|
|
217
|
+
"cqh",
|
|
218
|
+
"cqi",
|
|
219
|
+
"cqb",
|
|
220
|
+
"cqmin",
|
|
221
|
+
"cqmax"
|
|
222
|
+
];
|
|
223
|
+
const ANGLE_UNITS = [
|
|
224
|
+
"deg",
|
|
225
|
+
"rad",
|
|
226
|
+
"grad",
|
|
227
|
+
"turn"
|
|
228
|
+
];
|
|
229
|
+
const TIME_UNITS = ["ms", "s"];
|
|
230
|
+
for (const u of LENGTH_UNITS) UNIT_TO_SYNTAX[u] = {
|
|
231
|
+
syntax: "<length-percentage>",
|
|
232
|
+
initialValue: "0px"
|
|
233
|
+
};
|
|
234
|
+
UNIT_TO_SYNTAX["%"] = {
|
|
235
|
+
syntax: "<length-percentage>",
|
|
236
|
+
initialValue: "0px"
|
|
237
|
+
};
|
|
238
|
+
for (const u of ANGLE_UNITS) UNIT_TO_SYNTAX[u] = {
|
|
239
|
+
syntax: "<angle>",
|
|
240
|
+
initialValue: "0deg"
|
|
241
|
+
};
|
|
242
|
+
for (const u of TIME_UNITS) UNIT_TO_SYNTAX[u] = {
|
|
243
|
+
syntax: "<time>",
|
|
244
|
+
initialValue: "0s"
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* Infer CSS @property syntax from a concrete value.
|
|
248
|
+
* Detects numeric types: \<number\>, \<length-percentage\>, \<angle\>, \<time\>.
|
|
249
|
+
* Length and percentage values both map to \<length-percentage\> for maximum flexibility.
|
|
250
|
+
* Color properties are handled separately via the #name token convention
|
|
251
|
+
* (--name-color gets \<color\> syntax automatically in getEffectiveDefinition).
|
|
252
|
+
*
|
|
253
|
+
* @param value - The CSS value to infer from (e.g. '10px', '1', '45deg')
|
|
254
|
+
* @returns Inferred syntax and initial value, or null if not inferable
|
|
255
|
+
*/
|
|
256
|
+
function inferSyntaxFromValue(value) {
|
|
257
|
+
if (!value || typeof value !== "string") return null;
|
|
258
|
+
const trimmed = value.trim();
|
|
259
|
+
if (!trimmed) return null;
|
|
260
|
+
if (RE_NUMBER.test(trimmed)) {
|
|
261
|
+
if (parseFloat(trimmed) === 0) return null;
|
|
262
|
+
return {
|
|
263
|
+
syntax: "<number>",
|
|
264
|
+
initialValue: "0"
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
const unitMatch = trimmed.match(RE_RAW_UNIT);
|
|
268
|
+
if (unitMatch) {
|
|
269
|
+
const mapping = UNIT_TO_SYNTAX[unitMatch[2]];
|
|
270
|
+
if (mapping) return mapping;
|
|
271
|
+
}
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
//#endregion
|
|
58
275
|
//#region src/parser/lru.ts
|
|
59
276
|
var Lru = class {
|
|
60
277
|
limit;
|
|
@@ -1131,223 +1348,6 @@ function getComponentPropertySyntax() {
|
|
|
1131
1348
|
}
|
|
1132
1349
|
}
|
|
1133
1350
|
//#endregion
|
|
1134
|
-
//#region src/properties/index.ts
|
|
1135
|
-
const PROPERTIES_KEY = "@properties";
|
|
1136
|
-
/**
|
|
1137
|
-
* Valid CSS custom property name pattern (after the -- prefix).
|
|
1138
|
-
* Must start with a letter or underscore, followed by letters, digits, hyphens, or underscores.
|
|
1139
|
-
*/
|
|
1140
|
-
const VALID_PROPERTY_NAME_PATTERN = /^[a-z_][a-z0-9-_]*$/i;
|
|
1141
|
-
/**
|
|
1142
|
-
* Validate a CSS custom property name (the part after --).
|
|
1143
|
-
* Returns true if the name is valid for use as a CSS custom property.
|
|
1144
|
-
*/
|
|
1145
|
-
function isValidPropertyName(name) {
|
|
1146
|
-
return VALID_PROPERTY_NAME_PATTERN.test(name);
|
|
1147
|
-
}
|
|
1148
|
-
/**
|
|
1149
|
-
* Check if styles object has local @properties definition.
|
|
1150
|
-
* Fast path: single property lookup.
|
|
1151
|
-
*/
|
|
1152
|
-
function hasLocalProperties(styles) {
|
|
1153
|
-
return PROPERTIES_KEY in styles;
|
|
1154
|
-
}
|
|
1155
|
-
/**
|
|
1156
|
-
* Extract local @properties from styles object.
|
|
1157
|
-
* Returns null if no local properties (fast path).
|
|
1158
|
-
*/
|
|
1159
|
-
function extractLocalProperties(styles) {
|
|
1160
|
-
const properties = styles[PROPERTIES_KEY];
|
|
1161
|
-
if (!properties || typeof properties !== "object") return null;
|
|
1162
|
-
return properties;
|
|
1163
|
-
}
|
|
1164
|
-
/**
|
|
1165
|
-
* Parse a property token name and return the CSS property name and whether it's a color.
|
|
1166
|
-
* Supports tasty token syntax and validates the property name.
|
|
1167
|
-
*
|
|
1168
|
-
* Token formats:
|
|
1169
|
-
* - `$name` → { cssName: '--name', isColor: false }
|
|
1170
|
-
* - `#name` → { cssName: '--name-color', isColor: true }
|
|
1171
|
-
* - `--name` → { cssName: '--name', isColor: false } (legacy, auto-detect color by suffix)
|
|
1172
|
-
* - `name` → { cssName: '--name', isColor: false } (legacy)
|
|
1173
|
-
*
|
|
1174
|
-
* @param token - The property token to parse
|
|
1175
|
-
* @returns Parsed result with cssName, isColor, isValid, and optional error
|
|
1176
|
-
*/
|
|
1177
|
-
function parsePropertyToken(token) {
|
|
1178
|
-
if (!token || typeof token !== "string") return {
|
|
1179
|
-
cssName: "",
|
|
1180
|
-
isColor: false,
|
|
1181
|
-
isValid: false,
|
|
1182
|
-
error: "Property token must be a non-empty string"
|
|
1183
|
-
};
|
|
1184
|
-
let name;
|
|
1185
|
-
let isColor;
|
|
1186
|
-
if (token.startsWith("$")) {
|
|
1187
|
-
name = token.slice(1);
|
|
1188
|
-
isColor = false;
|
|
1189
|
-
} else if (token.startsWith("#")) {
|
|
1190
|
-
name = token.slice(1);
|
|
1191
|
-
isColor = true;
|
|
1192
|
-
} else if (token.startsWith("--")) {
|
|
1193
|
-
name = token.slice(2);
|
|
1194
|
-
isColor = token.endsWith("-color");
|
|
1195
|
-
} else {
|
|
1196
|
-
name = token;
|
|
1197
|
-
isColor = token.endsWith("-color");
|
|
1198
|
-
}
|
|
1199
|
-
if (!name) return {
|
|
1200
|
-
cssName: "",
|
|
1201
|
-
isColor,
|
|
1202
|
-
isValid: false,
|
|
1203
|
-
error: "Property name cannot be empty"
|
|
1204
|
-
};
|
|
1205
|
-
if (!isValidPropertyName(name)) return {
|
|
1206
|
-
cssName: "",
|
|
1207
|
-
isColor,
|
|
1208
|
-
isValid: false,
|
|
1209
|
-
error: `Invalid property name "${name}". Must start with a letter or underscore, followed by letters, digits, hyphens, or underscores.`
|
|
1210
|
-
};
|
|
1211
|
-
let cssName;
|
|
1212
|
-
if (token.startsWith("#")) cssName = `--${name}-color`;
|
|
1213
|
-
else cssName = `--${name}`;
|
|
1214
|
-
return {
|
|
1215
|
-
cssName,
|
|
1216
|
-
isColor,
|
|
1217
|
-
isValid: true
|
|
1218
|
-
};
|
|
1219
|
-
}
|
|
1220
|
-
/**
|
|
1221
|
-
* Normalize a property definition to a consistent string representation.
|
|
1222
|
-
* Used for comparing definitions to detect type conflicts.
|
|
1223
|
-
*
|
|
1224
|
-
* Only `syntax` and `inherits` are compared — `initialValue` is intentionally
|
|
1225
|
-
* excluded because different components may set different defaults for the
|
|
1226
|
-
* same typed property (e.g. auto-inferred `0px` vs explicit `6px`).
|
|
1227
|
-
*
|
|
1228
|
-
* Keys are sorted alphabetically to ensure consistent comparison:
|
|
1229
|
-
* { inherits: true, syntax: '<color>' } === { syntax: '<color>', inherits: true }
|
|
1230
|
-
*/
|
|
1231
|
-
function normalizePropertyDefinition(def) {
|
|
1232
|
-
const normalized = {};
|
|
1233
|
-
if (def.inherits !== void 0) normalized.inherits = def.inherits;
|
|
1234
|
-
if (def.syntax !== void 0) normalized.syntax = def.syntax;
|
|
1235
|
-
return JSON.stringify(normalized);
|
|
1236
|
-
}
|
|
1237
|
-
/**
|
|
1238
|
-
* Get the effective property definition for a token.
|
|
1239
|
-
* For color tokens (#name), auto-sets syntax to '<color>' and defaults initialValue to 'transparent'.
|
|
1240
|
-
*
|
|
1241
|
-
* @param token - Property token ($name, #name, --name, or plain name)
|
|
1242
|
-
* @param userDefinition - User-provided definition options
|
|
1243
|
-
* @returns Effective definition with cssName, definition, isValid, and optional error
|
|
1244
|
-
*/
|
|
1245
|
-
function getEffectiveDefinition(token, userDefinition) {
|
|
1246
|
-
const parsed = parsePropertyToken(token);
|
|
1247
|
-
if (!parsed.isValid) return {
|
|
1248
|
-
cssName: "",
|
|
1249
|
-
definition: userDefinition,
|
|
1250
|
-
isColor: false,
|
|
1251
|
-
isValid: false,
|
|
1252
|
-
error: parsed.error
|
|
1253
|
-
};
|
|
1254
|
-
if (parsed.isColor) return {
|
|
1255
|
-
cssName: parsed.cssName,
|
|
1256
|
-
definition: {
|
|
1257
|
-
syntax: "<color>",
|
|
1258
|
-
inherits: userDefinition.inherits,
|
|
1259
|
-
initialValue: userDefinition.initialValue ?? "transparent"
|
|
1260
|
-
},
|
|
1261
|
-
isColor: true,
|
|
1262
|
-
isValid: true
|
|
1263
|
-
};
|
|
1264
|
-
return {
|
|
1265
|
-
cssName: parsed.cssName,
|
|
1266
|
-
definition: userDefinition,
|
|
1267
|
-
isColor: false,
|
|
1268
|
-
isValid: true
|
|
1269
|
-
};
|
|
1270
|
-
}
|
|
1271
|
-
const UNIT_TO_SYNTAX = {};
|
|
1272
|
-
const LENGTH_UNITS = [
|
|
1273
|
-
"px",
|
|
1274
|
-
"em",
|
|
1275
|
-
"rem",
|
|
1276
|
-
"vw",
|
|
1277
|
-
"vh",
|
|
1278
|
-
"vmin",
|
|
1279
|
-
"vmax",
|
|
1280
|
-
"ch",
|
|
1281
|
-
"ex",
|
|
1282
|
-
"cap",
|
|
1283
|
-
"ic",
|
|
1284
|
-
"lh",
|
|
1285
|
-
"rlh",
|
|
1286
|
-
"svw",
|
|
1287
|
-
"svh",
|
|
1288
|
-
"lvw",
|
|
1289
|
-
"lvh",
|
|
1290
|
-
"dvw",
|
|
1291
|
-
"dvh",
|
|
1292
|
-
"cqw",
|
|
1293
|
-
"cqh",
|
|
1294
|
-
"cqi",
|
|
1295
|
-
"cqb",
|
|
1296
|
-
"cqmin",
|
|
1297
|
-
"cqmax"
|
|
1298
|
-
];
|
|
1299
|
-
const ANGLE_UNITS = [
|
|
1300
|
-
"deg",
|
|
1301
|
-
"rad",
|
|
1302
|
-
"grad",
|
|
1303
|
-
"turn"
|
|
1304
|
-
];
|
|
1305
|
-
const TIME_UNITS = ["ms", "s"];
|
|
1306
|
-
for (const u of LENGTH_UNITS) UNIT_TO_SYNTAX[u] = {
|
|
1307
|
-
syntax: "<length-percentage>",
|
|
1308
|
-
initialValue: "0px"
|
|
1309
|
-
};
|
|
1310
|
-
UNIT_TO_SYNTAX["%"] = {
|
|
1311
|
-
syntax: "<length-percentage>",
|
|
1312
|
-
initialValue: "0px"
|
|
1313
|
-
};
|
|
1314
|
-
for (const u of ANGLE_UNITS) UNIT_TO_SYNTAX[u] = {
|
|
1315
|
-
syntax: "<angle>",
|
|
1316
|
-
initialValue: "0deg"
|
|
1317
|
-
};
|
|
1318
|
-
for (const u of TIME_UNITS) UNIT_TO_SYNTAX[u] = {
|
|
1319
|
-
syntax: "<time>",
|
|
1320
|
-
initialValue: "0s"
|
|
1321
|
-
};
|
|
1322
|
-
/**
|
|
1323
|
-
* Infer CSS @property syntax from a concrete value.
|
|
1324
|
-
* Detects numeric types: \<number\>, \<length-percentage\>, \<angle\>, \<time\>.
|
|
1325
|
-
* Length and percentage values both map to \<length-percentage\> for maximum flexibility.
|
|
1326
|
-
* Color properties are handled separately via the #name token convention
|
|
1327
|
-
* (--name-color gets \<color\> syntax automatically in getEffectiveDefinition).
|
|
1328
|
-
*
|
|
1329
|
-
* @param value - The CSS value to infer from (e.g. '10px', '1', '45deg')
|
|
1330
|
-
* @returns Inferred syntax and initial value, or null if not inferable
|
|
1331
|
-
*/
|
|
1332
|
-
function inferSyntaxFromValue(value) {
|
|
1333
|
-
if (!value || typeof value !== "string") return null;
|
|
1334
|
-
const trimmed = value.trim();
|
|
1335
|
-
if (!trimmed) return null;
|
|
1336
|
-
if (RE_NUMBER.test(trimmed)) {
|
|
1337
|
-
if (parseFloat(trimmed) === 0) return null;
|
|
1338
|
-
return {
|
|
1339
|
-
syntax: "<number>",
|
|
1340
|
-
initialValue: "0"
|
|
1341
|
-
};
|
|
1342
|
-
}
|
|
1343
|
-
const unitMatch = trimmed.match(RE_RAW_UNIT);
|
|
1344
|
-
if (unitMatch) {
|
|
1345
|
-
const mapping = UNIT_TO_SYNTAX[unitMatch[2]];
|
|
1346
|
-
if (mapping) return mapping;
|
|
1347
|
-
}
|
|
1348
|
-
return null;
|
|
1349
|
-
}
|
|
1350
|
-
//#endregion
|
|
1351
1351
|
//#region src/utils/hash.ts
|
|
1352
1352
|
/**
|
|
1353
1353
|
* Fast string hash (djb2) for deduplication keys.
|
|
@@ -3783,7 +3783,7 @@ function resetHandlers() {
|
|
|
3783
3783
|
for (const key of Object.keys(STYLE_HANDLER_MAP$1)) delete STYLE_HANDLER_MAP$1[key];
|
|
3784
3784
|
for (const key of Object.keys(initialHandlerMapSnapshot)) STYLE_HANDLER_MAP$1[key] = [...initialHandlerMapSnapshot[key]];
|
|
3785
3785
|
}
|
|
3786
|
-
function defineCustomStyle
|
|
3786
|
+
function defineCustomStyle(names, handler) {
|
|
3787
3787
|
let handlerWithLookup;
|
|
3788
3788
|
if (typeof names === "function") {
|
|
3789
3789
|
handlerWithLookup = names;
|
|
@@ -3798,16 +3798,16 @@ function defineCustomStyle$1(names, handler) {
|
|
|
3798
3798
|
STYLE_HANDLER_MAP$1[name].push(handlerWithLookup);
|
|
3799
3799
|
});
|
|
3800
3800
|
}
|
|
3801
|
-
function defineStyleAlias
|
|
3801
|
+
function defineStyleAlias(styleName, cssStyleName, converter) {
|
|
3802
3802
|
const styleHandler = createStyle(styleName, cssStyleName, converter);
|
|
3803
3803
|
if (!STYLE_HANDLER_MAP$1[styleName]) STYLE_HANDLER_MAP$1[styleName] = [];
|
|
3804
3804
|
STYLE_HANDLER_MAP$1[styleName].push(styleHandler);
|
|
3805
3805
|
}
|
|
3806
3806
|
function predefine() {
|
|
3807
|
-
defineStyleAlias
|
|
3808
|
-
defineStyleAlias
|
|
3809
|
-
defineStyleAlias
|
|
3810
|
-
defineStyleAlias
|
|
3807
|
+
defineStyleAlias("gridAreas", "grid-template-areas");
|
|
3808
|
+
defineStyleAlias("gridColumns", "grid-template-columns", columnsConverter);
|
|
3809
|
+
defineStyleAlias("gridRows", "grid-template-rows", rowsConverter);
|
|
3810
|
+
defineStyleAlias("gridTemplate", "grid-template", (val) => {
|
|
3811
3811
|
if (typeof val !== "string") return;
|
|
3812
3812
|
return val.split("/").map((s, i) => (i ? columnsConverter : rowsConverter)(s)).join("/");
|
|
3813
3813
|
});
|
|
@@ -3833,12 +3833,12 @@ function predefine() {
|
|
|
3833
3833
|
scrollbarStyle,
|
|
3834
3834
|
fadeStyle,
|
|
3835
3835
|
insetStyle
|
|
3836
|
-
].forEach((handler) => defineCustomStyle
|
|
3836
|
+
].forEach((handler) => defineCustomStyle(handler));
|
|
3837
3837
|
captureInitialHandlerState();
|
|
3838
3838
|
return {
|
|
3839
3839
|
STYLE_HANDLER_MAP: STYLE_HANDLER_MAP$1,
|
|
3840
|
-
defineCustomStyle
|
|
3841
|
-
defineStyleAlias
|
|
3840
|
+
defineCustomStyle,
|
|
3841
|
+
defineStyleAlias
|
|
3842
3842
|
};
|
|
3843
3843
|
}
|
|
3844
3844
|
/**
|
|
@@ -3969,7 +3969,7 @@ const styleHandlers = {
|
|
|
3969
3969
|
};
|
|
3970
3970
|
//#endregion
|
|
3971
3971
|
//#region src/styles/index.ts
|
|
3972
|
-
const { STYLE_HANDLER_MAP
|
|
3972
|
+
const { STYLE_HANDLER_MAP } = predefine();
|
|
3973
3973
|
//#endregion
|
|
3974
3974
|
//#region src/injector/sheet-manager.ts
|
|
3975
3975
|
const supportsConstructableSheets = typeof CSSStyleSheet !== "undefined" && (() => {
|
|
@@ -7442,6 +7442,18 @@ function wrapInIsOrNot(args, negated) {
|
|
|
7442
7442
|
return `${negated ? ":not" : ":is"}(${args.sort().join(", ")})`;
|
|
7443
7443
|
}
|
|
7444
7444
|
/**
|
|
7445
|
+
* Wrap a non-empty selector fragment in `:where(...)` to zero its
|
|
7446
|
+
* specificity. Tasty anchors specificity solely on the doubled class
|
|
7447
|
+
* (`.tXX.tXX`) and `data-element` attributes; every stateful selector
|
|
7448
|
+
* (modifiers, pseudos, :is()/:not() groups, root/parent context) is wrapped
|
|
7449
|
+
* so it contributes nothing to specificity and the cascade is decided by
|
|
7450
|
+
* source order alone. Empty input passes through unchanged.
|
|
7451
|
+
*/
|
|
7452
|
+
function wrapWhere(inner) {
|
|
7453
|
+
if (!inner) return "";
|
|
7454
|
+
return `:where(${inner})`;
|
|
7455
|
+
}
|
|
7456
|
+
/**
|
|
7445
7457
|
* Convert a selector group to a CSS selector fragment.
|
|
7446
7458
|
*
|
|
7447
7459
|
* Single-branch groups are unwrapped (no :is() wrapper).
|
|
@@ -7545,7 +7557,7 @@ function rootGroupsToCSS(groups) {
|
|
|
7545
7557
|
if (optimized.length === 0) return void 0;
|
|
7546
7558
|
let prefix = ":root";
|
|
7547
7559
|
for (const group of optimized) prefix += selectorGroupToCSS(group);
|
|
7548
|
-
return prefix;
|
|
7560
|
+
return wrapWhere(prefix);
|
|
7549
7561
|
}
|
|
7550
7562
|
/**
|
|
7551
7563
|
* Convert parent groups to CSS selector fragments (for final output).
|
|
@@ -7557,7 +7569,8 @@ function parentGroupsToCSS(groups) {
|
|
|
7557
7569
|
for (const group of groups) {
|
|
7558
7570
|
const combinator = group.direct ? " > *" : " *";
|
|
7559
7571
|
const args = group.branches.map((branch) => branchToCSS(branch) + combinator);
|
|
7560
|
-
|
|
7572
|
+
const inner = group.negated ? `:not(${args.sort().join(", ")})` : args.sort().join(", ");
|
|
7573
|
+
result += wrapWhere(inner);
|
|
7561
7574
|
}
|
|
7562
7575
|
return result;
|
|
7563
7576
|
}
|
|
@@ -7889,6 +7902,14 @@ function andToCSS(children) {
|
|
|
7889
7902
|
};
|
|
7890
7903
|
}
|
|
7891
7904
|
/**
|
|
7905
|
+
* Check if a condition involves an `@supports` query (recursively).
|
|
7906
|
+
*/
|
|
7907
|
+
function branchHasSupports(node) {
|
|
7908
|
+
if (node.kind === "state") return node.type === "supports";
|
|
7909
|
+
if (isCompoundCondition(node)) return node.children.some(branchHasSupports);
|
|
7910
|
+
return false;
|
|
7911
|
+
}
|
|
7912
|
+
/**
|
|
7892
7913
|
* Make OR branches within AND children mutually exclusive.
|
|
7893
7914
|
*
|
|
7894
7915
|
* For an AND child that is OR(A, B), transforms it to OR(A, B & !A)
|
|
@@ -7905,9 +7926,10 @@ function makeOrBranchesExclusive(children) {
|
|
|
7905
7926
|
if (!isCompoundCondition(child) || child.operator !== "OR") return child;
|
|
7906
7927
|
if (child.children.length <= 1) return child;
|
|
7907
7928
|
if (!branchesProduceDifferentContexts(child.children)) return child;
|
|
7929
|
+
const sortedBranches = [...child.children].sort((a, b) => (branchHasSupports(a) ? 0 : 1) - (branchHasSupports(b) ? 0 : 1));
|
|
7908
7930
|
const exclusiveBranches = [];
|
|
7909
7931
|
const priorBranches = [];
|
|
7910
|
-
for (const branch of
|
|
7932
|
+
for (const branch of sortedBranches) {
|
|
7911
7933
|
if (priorBranches.length === 0) exclusiveBranches.push(branch);
|
|
7912
7934
|
else {
|
|
7913
7935
|
let exclusive = branch;
|
|
@@ -8218,6 +8240,21 @@ function buildAtRulesFromVariant(variant) {
|
|
|
8218
8240
|
return atRules;
|
|
8219
8241
|
}
|
|
8220
8242
|
//#endregion
|
|
8243
|
+
//#region src/pipeline/warnings.ts
|
|
8244
|
+
const defaultWarningHandler = (warning) => {
|
|
8245
|
+
console.warn(`[Tasty] ${warning.message}`);
|
|
8246
|
+
};
|
|
8247
|
+
let warningHandler = defaultWarningHandler;
|
|
8248
|
+
/**
|
|
8249
|
+
* Emit a structured pipeline warning via the configured handler.
|
|
8250
|
+
*/
|
|
8251
|
+
function emitWarning(code, message) {
|
|
8252
|
+
warningHandler({
|
|
8253
|
+
code,
|
|
8254
|
+
message
|
|
8255
|
+
});
|
|
8256
|
+
}
|
|
8257
|
+
//#endregion
|
|
8221
8258
|
//#region src/pipeline/exclusive.ts
|
|
8222
8259
|
/**
|
|
8223
8260
|
* Build exclusive conditions for a list of parsed style entries.
|
|
@@ -8246,7 +8283,12 @@ function buildAtRulesFromVariant(variant) {
|
|
|
8246
8283
|
function buildExclusiveConditions(entries) {
|
|
8247
8284
|
const result = [];
|
|
8248
8285
|
const priorConditions = [];
|
|
8286
|
+
const floors = [];
|
|
8249
8287
|
for (const entry of entries) {
|
|
8288
|
+
if (entry.floor) {
|
|
8289
|
+
floors.push(entry);
|
|
8290
|
+
continue;
|
|
8291
|
+
}
|
|
8250
8292
|
let exclusive = entry.condition;
|
|
8251
8293
|
for (const prior of priorConditions) {
|
|
8252
8294
|
if (prior.kind === "true") continue;
|
|
@@ -8261,6 +8303,10 @@ function buildExclusiveConditions(entries) {
|
|
|
8261
8303
|
});
|
|
8262
8304
|
if (entry.condition.kind !== "true") priorConditions.push(entry.condition);
|
|
8263
8305
|
}
|
|
8306
|
+
for (const floor of floors) result.push({
|
|
8307
|
+
...floor,
|
|
8308
|
+
exclusiveCondition: floor.condition
|
|
8309
|
+
});
|
|
8264
8310
|
return result;
|
|
8265
8311
|
}
|
|
8266
8312
|
/**
|
|
@@ -8273,19 +8319,85 @@ function buildExclusiveConditions(entries) {
|
|
|
8273
8319
|
*/
|
|
8274
8320
|
function parseStyleEntries(styleKey, valueMap, parseCondition) {
|
|
8275
8321
|
const entries = [];
|
|
8276
|
-
|
|
8322
|
+
let floorEntry = null;
|
|
8323
|
+
Object.keys(valueMap).forEach((stateKey) => {
|
|
8277
8324
|
const value = valueMap[stateKey];
|
|
8325
|
+
if (stateKey === "_") {
|
|
8326
|
+
floorEntry = {
|
|
8327
|
+
styleKey,
|
|
8328
|
+
stateKey,
|
|
8329
|
+
value,
|
|
8330
|
+
condition: trueCondition(),
|
|
8331
|
+
priority: 0,
|
|
8332
|
+
floor: true
|
|
8333
|
+
};
|
|
8334
|
+
return;
|
|
8335
|
+
}
|
|
8336
|
+
if (isMisusedFallbackKey(stateKey)) {
|
|
8337
|
+
emitWarning("INVALID_FALLBACK_KEY", `Style key "${stateKey}" (in "${styleKey}") combines the fallback "_" with other state logic. "_" can only be used on its own as a map-wide fallback floor. The key has been ignored.`);
|
|
8338
|
+
return;
|
|
8339
|
+
}
|
|
8278
8340
|
const condition = stateKey === "" ? trueCondition() : parseCondition(stateKey);
|
|
8279
8341
|
entries.push({
|
|
8280
8342
|
styleKey,
|
|
8281
8343
|
stateKey,
|
|
8282
8344
|
value,
|
|
8283
8345
|
condition,
|
|
8284
|
-
priority:
|
|
8346
|
+
priority: 0
|
|
8285
8347
|
});
|
|
8286
8348
|
});
|
|
8287
|
-
|
|
8288
|
-
|
|
8349
|
+
if (floorEntry !== null) {
|
|
8350
|
+
const hasOtherStates = entries.some((e) => e.condition.kind !== "true");
|
|
8351
|
+
const hasDefault = entries.some((e) => e.condition.kind === "true");
|
|
8352
|
+
if (!hasOtherStates && hasDefault) {
|
|
8353
|
+
emitWarning("REDUNDANT_DEFAULT_STATE", `Style "${styleKey}" defines both a "_" fallback and a "" default with no other states. The "" default is redundant (always superseded by "_"); the "_" value is used and the "" default is ignored.`);
|
|
8354
|
+
entries.length = 0;
|
|
8355
|
+
}
|
|
8356
|
+
}
|
|
8357
|
+
const normalized = normalizeDefaultStates(entries, styleKey);
|
|
8358
|
+
const ordered = floorEntry !== null ? [floorEntry, ...normalized] : normalized;
|
|
8359
|
+
ordered.forEach((entry, index) => {
|
|
8360
|
+
entry.priority = index;
|
|
8361
|
+
});
|
|
8362
|
+
ordered.reverse();
|
|
8363
|
+
return ordered;
|
|
8364
|
+
}
|
|
8365
|
+
/**
|
|
8366
|
+
* Detect a misused standalone `_` fallback key: a key that is not exactly
|
|
8367
|
+
* `_` but contains `_` as a standalone atom among state-logic operators
|
|
8368
|
+
* (`&`, `|`, `^`, `,`) or grouping parens. A `_` embedded in a longer token
|
|
8369
|
+
* (e.g. a modifier named `_private`) is not a misuse.
|
|
8370
|
+
*/
|
|
8371
|
+
function isMisusedFallbackKey(stateKey) {
|
|
8372
|
+
if (stateKey === "_" || !stateKey.includes("_")) return false;
|
|
8373
|
+
return /(?:^|[\s&|^,(])_(?:[\s&|^,)]|$)/.test(stateKey);
|
|
8374
|
+
}
|
|
8375
|
+
/**
|
|
8376
|
+
* Resolve the bare `''` default state (`condition.kind === 'true'`) in a
|
|
8377
|
+
* style value map.
|
|
8378
|
+
*
|
|
8379
|
+
* The bare default only behaves correctly as the **first** (lowest-priority)
|
|
8380
|
+
* key. When it appears later, `buildExclusiveConditions` processes it first
|
|
8381
|
+
* (after the reverse), never adds it to the prior list, and never negates it
|
|
8382
|
+
* — so it silently overrides every state authored before it.
|
|
8383
|
+
*
|
|
8384
|
+
* This function, given entries in authored order, moves a misplaced bare
|
|
8385
|
+
* default to the front (lowest priority), preserving the relative order of
|
|
8386
|
+
* all other entries, and emits a `MISPLACED_DEFAULT_STATE` warning.
|
|
8387
|
+
*
|
|
8388
|
+
* The `_` fallback floor is pulled out before this runs (see
|
|
8389
|
+
* `parseStyleEntries`), so only the bare `''` default is considered here.
|
|
8390
|
+
*/
|
|
8391
|
+
function normalizeDefaultStates(entries, styleKey) {
|
|
8392
|
+
const defaultPos = entries.findIndex((e) => e.condition.kind === "true");
|
|
8393
|
+
if (defaultPos <= 0) return entries;
|
|
8394
|
+
const defaultEntry = entries[defaultPos];
|
|
8395
|
+
emitWarning("MISPLACED_DEFAULT_STATE", `Style "${styleKey}" defines the default state "${defaultEntry.stateKey}" after other states. A bare default ("") must be the first key, otherwise it overrides the states above it. It has been moved to the first position. Define default states first.`);
|
|
8396
|
+
return [
|
|
8397
|
+
defaultEntry,
|
|
8398
|
+
...entries.slice(0, defaultPos),
|
|
8399
|
+
...entries.slice(defaultPos + 1)
|
|
8400
|
+
];
|
|
8289
8401
|
}
|
|
8290
8402
|
/**
|
|
8291
8403
|
* Merge parsed entries that share the same value.
|
|
@@ -8408,8 +8520,9 @@ function extractCompoundStates(valueMap) {
|
|
|
8408
8520
|
const keys = Object.keys(valueMap);
|
|
8409
8521
|
if (keys.length < 3 || !keys.some((k) => k.includes("&"))) return valueMap;
|
|
8410
8522
|
const entries = keys.map((key) => {
|
|
8523
|
+
const atoms = splitTopLevelAnd(key);
|
|
8411
8524
|
return {
|
|
8412
|
-
atoms:
|
|
8525
|
+
atoms: atoms === null || atoms.includes("_") ? [key] : atoms,
|
|
8413
8526
|
value: valueMap[key]
|
|
8414
8527
|
};
|
|
8415
8528
|
});
|
|
@@ -8600,7 +8713,35 @@ function hasAtRuleContext(node) {
|
|
|
8600
8713
|
return false;
|
|
8601
8714
|
}
|
|
8602
8715
|
/**
|
|
8603
|
-
*
|
|
8716
|
+
* Check if a condition involves an `@supports` query.
|
|
8717
|
+
*
|
|
8718
|
+
* `@supports` is feature detection: anything ANDed with it (e.g. a
|
|
8719
|
+
* `@container scroll-state(...)` query that only exists when
|
|
8720
|
+
* `container-type: scroll-state` is supported) becomes *unknown* — not
|
|
8721
|
+
* simply false — when the feature is absent. So a negated supports branch
|
|
8722
|
+
* must be emitted first (as the bare "feature unsupported" fallback) and
|
|
8723
|
+
* every other negated branch must nest inside the supported scope.
|
|
8724
|
+
*/
|
|
8725
|
+
function hasSupportsContext(node) {
|
|
8726
|
+
if (node.kind === "state") return node.type === "supports";
|
|
8727
|
+
if (node.kind === "compound") return node.children.some(hasSupportsContext);
|
|
8728
|
+
return false;
|
|
8729
|
+
}
|
|
8730
|
+
/**
|
|
8731
|
+
* Rank an OR branch for exclusive expansion ordering. Lower rank is
|
|
8732
|
+
* processed first (becomes the more "outer" / less-constrained branch):
|
|
8733
|
+
* 0 — branch involves `@supports` (feature-detection guard)
|
|
8734
|
+
* 1 — branch involves another at-rule (media / container / starting)
|
|
8735
|
+
* 2 — branch is pure selector context (modifiers / pseudos)
|
|
8736
|
+
*/
|
|
8737
|
+
function orBranchRank(node) {
|
|
8738
|
+
if (hasSupportsContext(node)) return 0;
|
|
8739
|
+
if (hasAtRuleContext(node)) return 1;
|
|
8740
|
+
return 2;
|
|
8741
|
+
}
|
|
8742
|
+
/**
|
|
8743
|
+
* Sort OR branches to prioritize at-rule conditions first, with
|
|
8744
|
+
* `@supports` branches ahead of all other at-rules.
|
|
8604
8745
|
*
|
|
8605
8746
|
* This is critical for correct CSS generation. For `!A | !B` where A is at-rule
|
|
8606
8747
|
* and B is modifier, we want:
|
|
@@ -8610,15 +8751,18 @@ function hasAtRuleContext(node) {
|
|
|
8610
8751
|
* If we process in wrong order (!B first), we'd get:
|
|
8611
8752
|
* - Branch 0: !B (modifier negation WITHOUT at-rule context - WRONG!)
|
|
8612
8753
|
* - Branch 1: B & !A (at-rule negation with modifier - incomplete coverage)
|
|
8754
|
+
*
|
|
8755
|
+
* The extra `@supports`-first tier matters when a feature query guards a
|
|
8756
|
+
* dependent query. For `!(S & C) = !S | !C` (S = `@supports(...)`, C =
|
|
8757
|
+
* `@container scroll-state(...)`), `simplify` sorts the branches
|
|
8758
|
+
* alphabetically into `[!C, !S]`. Expanding in that order would emit `!C`
|
|
8759
|
+
* as a bare `@container (not scroll-state(...))` — meaningless where the
|
|
8760
|
+
* feature is unsupported, so the default would never apply there. Putting
|
|
8761
|
+
* `!S` first yields `!S | (S & !C)`: a bare supports fallback plus the
|
|
8762
|
+
* dependent negation nested in the supported scope.
|
|
8613
8763
|
*/
|
|
8614
8764
|
function sortOrBranchesForExpansion(branches) {
|
|
8615
|
-
return [...branches].sort((a, b) =>
|
|
8616
|
-
const aHasAtRule = hasAtRuleContext(a);
|
|
8617
|
-
const bHasAtRule = hasAtRuleContext(b);
|
|
8618
|
-
if (aHasAtRule && !bHasAtRule) return -1;
|
|
8619
|
-
if (!aHasAtRule && bHasAtRule) return 1;
|
|
8620
|
-
return 0;
|
|
8621
|
-
});
|
|
8765
|
+
return [...branches].sort((a, b) => orBranchRank(a) - orBranchRank(b));
|
|
8622
8766
|
}
|
|
8623
8767
|
/**
|
|
8624
8768
|
* Expand ORs in a single entry's exclusive condition
|
|
@@ -8683,21 +8827,6 @@ function transformSelectorContent(content) {
|
|
|
8683
8827
|
return content.replace(ELEMENT_NAME_RE, (_, prefix, name) => `${prefix}[data-element="${name}"]`);
|
|
8684
8828
|
}
|
|
8685
8829
|
//#endregion
|
|
8686
|
-
//#region src/pipeline/warnings.ts
|
|
8687
|
-
const defaultWarningHandler = (warning) => {
|
|
8688
|
-
console.warn(`[Tasty] ${warning.message}`);
|
|
8689
|
-
};
|
|
8690
|
-
let warningHandler = defaultWarningHandler;
|
|
8691
|
-
/**
|
|
8692
|
-
* Emit a structured pipeline warning via the configured handler.
|
|
8693
|
-
*/
|
|
8694
|
-
function emitWarning(code, message) {
|
|
8695
|
-
warningHandler({
|
|
8696
|
-
code,
|
|
8697
|
-
message
|
|
8698
|
-
});
|
|
8699
|
-
}
|
|
8700
|
-
//#endregion
|
|
8701
8830
|
//#region src/pipeline/parseStateKey.ts
|
|
8702
8831
|
/**
|
|
8703
8832
|
* State Key Parser
|
|
@@ -9212,7 +9341,17 @@ function runPipeline(styles, parserContext) {
|
|
|
9212
9341
|
const starting = [];
|
|
9213
9342
|
for (const rule of dedupedRules) if (rule.startingStyle) starting.push(rule);
|
|
9214
9343
|
else normal.push(rule);
|
|
9215
|
-
return normal.concat(starting);
|
|
9344
|
+
return stableSortByOrder(normal).concat(stableSortByOrder(starting));
|
|
9345
|
+
}
|
|
9346
|
+
/**
|
|
9347
|
+
* Stable sort CSS rules by their `order` hint ascending. Rules without an
|
|
9348
|
+
* `order` are treated as 0. `Array.prototype.sort` is stable (ES2019+,
|
|
9349
|
+
* Node >= 20), so equal-order rules keep their emission order — the `_`
|
|
9350
|
+
* fallback floor (low order) stays before the overrides that layer over it.
|
|
9351
|
+
*/
|
|
9352
|
+
function stableSortByOrder(rules) {
|
|
9353
|
+
if (rules.length <= 1) return rules;
|
|
9354
|
+
return [...rules].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
|
9216
9355
|
}
|
|
9217
9356
|
/**
|
|
9218
9357
|
* Process styles at a given nesting level.
|
|
@@ -9320,7 +9459,8 @@ function invokeHandler(handler, stateSnapshots, selectorSuffix) {
|
|
|
9320
9459
|
for (const suffix of suffixes) computedRules.push({
|
|
9321
9460
|
condition: snapshot.condition,
|
|
9322
9461
|
declarations,
|
|
9323
|
-
selectorSuffix: suffix
|
|
9462
|
+
selectorSuffix: suffix,
|
|
9463
|
+
order: snapshot.order
|
|
9324
9464
|
});
|
|
9325
9465
|
}
|
|
9326
9466
|
}
|
|
@@ -9738,10 +9878,15 @@ function computeStateCombinations(exclusiveByStyle, lookupStyles) {
|
|
|
9738
9878
|
const simplified = simplifyCondition(and(...combo.map((e) => e.exclusiveCondition)));
|
|
9739
9879
|
if (simplified.kind === "false") continue;
|
|
9740
9880
|
const values = {};
|
|
9741
|
-
|
|
9881
|
+
let order = 0;
|
|
9882
|
+
for (const entry of combo) {
|
|
9883
|
+
values[entry.styleKey] = entry.value;
|
|
9884
|
+
if (entry.priority > order) order = entry.priority;
|
|
9885
|
+
}
|
|
9742
9886
|
snapshots.push({
|
|
9743
9887
|
condition: simplified,
|
|
9744
|
-
values
|
|
9888
|
+
values,
|
|
9889
|
+
order
|
|
9745
9890
|
});
|
|
9746
9891
|
}
|
|
9747
9892
|
return snapshots;
|
|
@@ -9789,10 +9934,13 @@ function mergeByValue(rules) {
|
|
|
9789
9934
|
for (const [, groupRules] of groups) if (groupRules.length === 1) merged.push(groupRules[0]);
|
|
9790
9935
|
else {
|
|
9791
9936
|
const mergedCondition = simplifyCondition(or(...groupRules.map((r) => r.condition)));
|
|
9937
|
+
let order = groupRules[0].order;
|
|
9938
|
+
for (const r of groupRules) if (r.order < order) order = r.order;
|
|
9792
9939
|
merged.push({
|
|
9793
9940
|
condition: mergedCondition,
|
|
9794
9941
|
declarations: groupRules[0].declarations,
|
|
9795
|
-
selectorSuffix: groupRules[0].selectorSuffix
|
|
9942
|
+
selectorSuffix: groupRules[0].selectorSuffix,
|
|
9943
|
+
order
|
|
9796
9944
|
});
|
|
9797
9945
|
}
|
|
9798
9946
|
return merged;
|
|
@@ -9802,12 +9950,15 @@ function mergeByValue(rules) {
|
|
|
9802
9950
|
*/
|
|
9803
9951
|
function buildSelectorFromVariant(variant, selectorSuffix) {
|
|
9804
9952
|
let selector = "";
|
|
9805
|
-
|
|
9806
|
-
for (const group of variant.selectorGroups)
|
|
9953
|
+
let rootSegment = branchToCSS([...variant.modifierConditions, ...variant.pseudoConditions]);
|
|
9954
|
+
for (const group of variant.selectorGroups) rootSegment += selectorGroupToCSS(group);
|
|
9955
|
+
selector += wrapWhere(rootSegment);
|
|
9807
9956
|
if (variant.parentGroups.length > 0) selector += parentGroupsToCSS(variant.parentGroups);
|
|
9808
9957
|
selector += selectorSuffix;
|
|
9809
9958
|
const ownOptimized = optimizeGroups(variant.ownGroups);
|
|
9810
|
-
|
|
9959
|
+
let ownSegment = "";
|
|
9960
|
+
for (const group of ownOptimized) ownSegment += selectorGroupToCSS(group);
|
|
9961
|
+
selector += wrapWhere(ownSegment);
|
|
9811
9962
|
return selector;
|
|
9812
9963
|
}
|
|
9813
9964
|
/**
|
|
@@ -9842,7 +9993,8 @@ function materializeComputedRule(rule) {
|
|
|
9842
9993
|
const selectorFragments = mergeVariantsIntoSelectorGroups(group.variants).map((v) => buildSelectorFromVariant(v, rule.selectorSuffix));
|
|
9843
9994
|
const cssRule = {
|
|
9844
9995
|
selector: selectorFragments.length === 1 ? selectorFragments[0] : selectorFragments,
|
|
9845
|
-
declarations
|
|
9996
|
+
declarations,
|
|
9997
|
+
order: rule.order
|
|
9846
9998
|
};
|
|
9847
9999
|
if (group.atRules.length > 0) cssRule.atRules = group.atRules;
|
|
9848
10000
|
if (group.rootPrefix) cssRule.rootPrefix = group.rootPrefix;
|
|
@@ -10554,6 +10706,6 @@ function resetConfig() {
|
|
|
10554
10706
|
delete storage[GLOBAL_INJECTOR_KEY];
|
|
10555
10707
|
}
|
|
10556
10708
|
//#endregion
|
|
10557
|
-
export { parseColor as $, StyleInjector as A,
|
|
10709
|
+
export { parseColor as $, StyleInjector as A, hasLocalProperties as At, styleHandlers as B, parseStateKey as C, getRgbValuesFromRgbaString as Ct, extractPredefinedStateRefs as D, Lru as Dt, extractLocalPredefinedStates as E, strToRgb as Et, fontFaceContentHash as F, CUSTOM_UNITS as G, warn as H, formatFontFaceRule as I, filterMods as J, DIRECTIONS as K, hasLocalFontFace as L, formatCounterStyleRule as M, hasLocalCounterStyle as N, getGlobalPredefinedStates as O, extractLocalProperties as Ot, extractLocalFontFace as P, normalizeColorTokenValue as Q, SheetManager as R, renderStyles as S, getNamedColorHex as St, createStateParserContext as T, hslToRgbValues as Tt, createStyle as U, deprecationWarning as V, PropertyTypeResolver as W, getGlobalParser as X, getGlobalFuncs as Y, getGlobalPredefinedTokens as Z, markStylesGenerated as _, colorInitialValueToComponents as _t, getGlobalCounterStyle as a, okhslPlugin as at, hasPipelineCacheEntry as b, getColorSpaceSuffix as bt, getGlobalKeyframes as c, DEFAULT_NAME_PREFIX as ct, getNamePrefix as d, makeCounterStyleName as dt, parseStyle as et, hasGlobalKeyframes as f, makeKeyframeName as ft, isTestEnvironment as g, hashString as gt, isConfigLocked as h, isDevEnv as ht, getGlobalConfigTokens as i, okhslFunc as it, extractLocalCounterStyle as j, parsePropertyToken as jt, setGlobalPredefinedStates as k, getEffectiveDefinition as kt, getGlobalRecipes as l, DEFAULT_ZERO_NAME_PREFIX as lt, hasStylesGenerated as m, validateNamePrefix as mt, getConfig as n, setGlobalPredefinedTokens as nt, getGlobalFontFace as o, StyleParser as ot, hasGlobalRecipes as p, tastyClassRegex as pt, customFunc as q, getEffectiveProperties as r, stringifyStyles as rt, getGlobalInjector as s, Bucket as st, configure as t, resetGlobalPredefinedTokens as tt, getGlobalStyles as u, makeClassName as ut, resetConfig as v, getColorSpaceComponents as vt, camelToKebab as w, hexToRgb as wt, isSelector as x, getComponentPropertySyntax as xt, generateTypographyTokens as y, getColorSpaceFunc as yt, STYLE_HANDLER_MAP as z };
|
|
10558
10710
|
|
|
10559
|
-
//# sourceMappingURL=config-
|
|
10711
|
+
//# sourceMappingURL=config-DF2QZQEW.js.map
|