@barocss/kit 0.10.3 → 0.11.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/dist/index.cjs +1476 -868
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -19
- package/dist/index.d.ts +13 -19
- package/dist/index.js +1476 -869
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -270,249 +270,571 @@ function clearContextCaches(ctx) {
|
|
|
270
270
|
state.failures.clear();
|
|
271
271
|
}
|
|
272
272
|
//#endregion
|
|
273
|
-
//#region src/core/
|
|
274
|
-
var utilityRegistry = [];
|
|
275
|
-
function registerUtility(util, ctx) {
|
|
276
|
-
const state = ctx && getContextState(ctx);
|
|
277
|
-
if (ctx && !state) throw new Error("Utility registration requires a context from createContext");
|
|
278
|
-
(state?.utilities || utilityRegistry).push(util);
|
|
279
|
-
if (ctx) clearContextCaches(ctx);
|
|
280
|
-
else {
|
|
281
|
-
parseResultCache.clear();
|
|
282
|
-
utilityCache.clear();
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
function getUtility(ctx) {
|
|
286
|
-
return ctx && getContextState(ctx)?.utilities || utilityRegistry;
|
|
287
|
-
}
|
|
288
|
-
var modifierRegistry = [];
|
|
273
|
+
//#region src/core/utils.ts
|
|
289
274
|
/**
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
* @example
|
|
293
|
-
* ```
|
|
294
|
-
* staticModifier('disabled', ['&:disabled'], { source: 'pseudo' });
|
|
295
|
-
* ```
|
|
296
|
-
*
|
|
297
|
-
* @param name The name of the modifier
|
|
298
|
-
* @param selectors The selectors of the modifier
|
|
299
|
-
* @param options The options of the modifier
|
|
300
|
-
*
|
|
301
|
-
* @returns {void}
|
|
275
|
+
* Parses a fraction string (e.g., '1/2') and returns a percentage string (e.g., '50%'), or null if not a valid fraction.
|
|
302
276
|
*/
|
|
303
|
-
function
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
modifySelector: ({ ..._rest }) => {
|
|
308
|
-
return selectors.map((sel) => ({
|
|
309
|
-
selector: sel,
|
|
310
|
-
source: options.source
|
|
311
|
-
}));
|
|
312
|
-
},
|
|
313
|
-
...options
|
|
314
|
-
}, ctx);
|
|
315
|
-
}
|
|
316
|
-
function functionalModifier(match, modifySelector, wrap, options = {}, ctx) {
|
|
317
|
-
registerModifier({
|
|
318
|
-
match,
|
|
319
|
-
modifySelector,
|
|
320
|
-
wrap,
|
|
321
|
-
...options
|
|
322
|
-
}, ctx);
|
|
323
|
-
}
|
|
324
|
-
function registerModifier(modifier, ctx) {
|
|
325
|
-
const state = ctx && getContextState(ctx);
|
|
326
|
-
if (ctx && !state) throw new Error("Modifier registration requires a context from createContext");
|
|
327
|
-
(state?.modifiers || modifierRegistry).push(modifier);
|
|
328
|
-
if (ctx) clearContextCaches(ctx);
|
|
329
|
-
}
|
|
330
|
-
function getModifier(ctx) {
|
|
331
|
-
return ctx && getContextState(ctx)?.modifiers || modifierRegistry;
|
|
332
|
-
}
|
|
333
|
-
var ESCAPE_REGEX = /[^A-Za-z0-9_-]/gu;
|
|
334
|
-
var UNSAFE_RAW = /^[\s\p{C}\p{Z}]$/u;
|
|
335
|
-
function escapeClassName(className) {
|
|
336
|
-
if (className === "-") return "\\-";
|
|
337
|
-
const lead = /^-?[0-9]/.exec(className);
|
|
338
|
-
if (lead) {
|
|
339
|
-
const i = lead[0].length - 1;
|
|
340
|
-
return className.slice(0, i) + "\\" + className.charCodeAt(i).toString(16) + " " + escapeRest(className.slice(i + 1));
|
|
277
|
+
function parseFraction(input) {
|
|
278
|
+
if (input.includes("/")) {
|
|
279
|
+
const [num, denom] = input.split("/").map(Number);
|
|
280
|
+
if (!isNaN(num) && !isNaN(denom) && denom !== 0) return `${num / denom * 100}%`;
|
|
341
281
|
}
|
|
342
|
-
return
|
|
343
|
-
}
|
|
344
|
-
function escapeRest(className) {
|
|
345
|
-
return className.replace(ESCAPE_REGEX, (c) => {
|
|
346
|
-
if (c === " ") return "\\x20 ";
|
|
347
|
-
if (c === ".") return "\\.";
|
|
348
|
-
if (c === "/") return "\\/";
|
|
349
|
-
if (c === ":") return "\\:";
|
|
350
|
-
if (c === "[") return "\\[";
|
|
351
|
-
if (c === "]") return "\\]";
|
|
352
|
-
if (c === "(") return "\\(";
|
|
353
|
-
if (c === ")") return "\\)";
|
|
354
|
-
if (c === "%") return "\\%";
|
|
355
|
-
if (c === "#") return "\\#";
|
|
356
|
-
if (c === ",") return "\\,";
|
|
357
|
-
if (c === "=") return "\\=";
|
|
358
|
-
if (c === "&") return "\\&";
|
|
359
|
-
if (c === "~") return "\\~";
|
|
360
|
-
if (c === "*") return "\\*";
|
|
361
|
-
if (c === "$") return "\\$";
|
|
362
|
-
if (c === "^") return "\\^";
|
|
363
|
-
if (c === "+") return "\\+";
|
|
364
|
-
if (c === "?") return "\\?";
|
|
365
|
-
if (c === "!") return "\\!";
|
|
366
|
-
if (c === "@") return "\\@";
|
|
367
|
-
if (c === "'") return "\\'";
|
|
368
|
-
if (c === "\"") return "\\\"";
|
|
369
|
-
if (c === "`") return "\\`";
|
|
370
|
-
if (c === ";") return "\\;";
|
|
371
|
-
if (c === "<") return "\\<";
|
|
372
|
-
if (c === ">") return "\\>";
|
|
373
|
-
if (c === "{") return "\\{";
|
|
374
|
-
if (c === "}") return "\\}";
|
|
375
|
-
if (c === "|") return "\\|";
|
|
376
|
-
if (c === "\\") return "\\\\";
|
|
377
|
-
if (UNSAFE_RAW.test(c)) return "\\" + c.codePointAt(0).toString(16) + " ";
|
|
378
|
-
return "\\" + c;
|
|
379
|
-
});
|
|
282
|
+
return null;
|
|
380
283
|
}
|
|
381
284
|
/**
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
* @example
|
|
385
|
-
* ```
|
|
386
|
-
* staticUtility('block', [['display', 'block']]);
|
|
387
|
-
* staticUtility('hidden', [['display', 'none']]);
|
|
388
|
-
* staticUtility('space-x-px', [
|
|
389
|
-
* [
|
|
390
|
-
* '& > :not([hidden]) ~ :not([hidden])', // selector
|
|
391
|
-
* [
|
|
392
|
-
* ['margin-inline-start', '1px'], // [prop, value]
|
|
393
|
-
* ['margin-inline-end', '1px'], // [prop, value]
|
|
394
|
-
* ],
|
|
395
|
-
* ],
|
|
396
|
-
* ]);
|
|
397
|
-
* ```
|
|
398
|
-
*
|
|
399
|
-
* @param name The name of the utility
|
|
400
|
-
* @param decls The declarations of the utility
|
|
401
|
-
* @param opts The options of the utility
|
|
285
|
+
* Returns the input if it is a valid non-negative integer string, else null.
|
|
402
286
|
*
|
|
403
|
-
* @
|
|
287
|
+
* @example
|
|
288
|
+
* parseNumber("10") // "10"
|
|
289
|
+
* parseNumber("-10") // "-10"
|
|
290
|
+
* parseNumber("10.5") // "10.5"
|
|
404
291
|
*/
|
|
405
|
-
function
|
|
406
|
-
|
|
407
|
-
name,
|
|
408
|
-
match: (className) => {
|
|
409
|
-
return className === name;
|
|
410
|
-
},
|
|
411
|
-
handler: (value) => {
|
|
412
|
-
return decls.flatMap((params) => {
|
|
413
|
-
if (params.type) return [params];
|
|
414
|
-
if (typeof params === "function") return [params(value)];
|
|
415
|
-
const [a, b] = params;
|
|
416
|
-
if (typeof b === "string") return [decl(a, b)];
|
|
417
|
-
else if (Array.isArray(b)) return [rule(a, b.map(([prop, value]) => decl(prop, value)))];
|
|
418
|
-
return [];
|
|
419
|
-
});
|
|
420
|
-
},
|
|
421
|
-
description: opts?.description,
|
|
422
|
-
category: opts?.category,
|
|
423
|
-
priority: opts?.priority
|
|
424
|
-
}, ctx);
|
|
292
|
+
function parseNumber(input) {
|
|
293
|
+
return /^-?\d+(?:\.\d+)?$/.test(input) ? input : null;
|
|
425
294
|
}
|
|
426
295
|
/**
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
* Example:
|
|
430
|
-
* functionalUtility({
|
|
431
|
-
* name: 'z',
|
|
432
|
-
* supportsNegative: true,
|
|
433
|
-
* themeKeys: ['--z-index'],
|
|
434
|
-
* handleBareValue: ({ value }) => isPositiveInteger(value) ? value : null,
|
|
435
|
-
* handle: (value) => [decl('z-index', value)],
|
|
436
|
-
* description: 'z-index utility',
|
|
437
|
-
* category: 'layout',
|
|
438
|
-
* });
|
|
296
|
+
* Returns the input if it is a valid length string, else null.
|
|
439
297
|
*/
|
|
298
|
+
function parseLength(input) {
|
|
299
|
+
return /^\d+(px|em|rem|vh|vw|vmin|vmax|%|in|cm|mm|pt|pc|ex|ch|fr)$/.test(input) ? input : null;
|
|
300
|
+
}
|
|
440
301
|
/**
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
*
|
|
302
|
+
* Unified parser for fraction or number, with options for percent or repeat syntax.
|
|
303
|
+
* - percent: if true, returns percentage for fraction (e.g., '1/2' -> '50%')
|
|
304
|
+
* - repeat: if true, returns repeat() for number (e.g., '3' -> 'repeat(3, minmax(0, 1fr))')
|
|
444
305
|
*/
|
|
445
|
-
function
|
|
446
|
-
if (
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
return
|
|
459
|
-
}
|
|
460
|
-
/** #261: `var(--spacing-<key>)` for a named (non-numeric) `theme.spacing` key, else null. */
|
|
461
|
-
function spacingKeyValue(ctx, key, negative) {
|
|
462
|
-
if (key === "px" || !/^[a-zA-Z][\w-]*$/.test(key) || ctx.theme("spacing", key) == null) return null;
|
|
463
|
-
const ref = `var(--spacing-${key})`;
|
|
464
|
-
return negative ? `calc(${ref} * -1)` : ref;
|
|
306
|
+
function parseFractionOrNumber(value, opts = {}) {
|
|
307
|
+
if (/^\d+$/.test(value)) {
|
|
308
|
+
if (opts.repeat) return `repeat(${value}, minmax(0, 1fr))`;
|
|
309
|
+
return value;
|
|
310
|
+
}
|
|
311
|
+
if (value.includes("/")) {
|
|
312
|
+
const [numerator, denominator] = value.split("/").map(Number);
|
|
313
|
+
if (!isNaN(numerator) && !isNaN(denominator) && denominator !== 0) {
|
|
314
|
+
const result = numerator / denominator;
|
|
315
|
+
if (opts.percent) return `${result * 100}%`;
|
|
316
|
+
return result.toString();
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return null;
|
|
465
320
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
321
|
+
var CSS_COLOR_NAMES = /* @__PURE__ */ new Set([
|
|
322
|
+
"aliceblue",
|
|
323
|
+
"antiquewhite",
|
|
324
|
+
"aqua",
|
|
325
|
+
"aquamarine",
|
|
326
|
+
"azure",
|
|
327
|
+
"beige",
|
|
328
|
+
"bisque",
|
|
329
|
+
"black",
|
|
330
|
+
"blanchedalmond",
|
|
331
|
+
"blue",
|
|
332
|
+
"blueviolet",
|
|
333
|
+
"brown",
|
|
334
|
+
"burlywood",
|
|
335
|
+
"cadetblue",
|
|
336
|
+
"chartreuse",
|
|
337
|
+
"chocolate",
|
|
338
|
+
"coral",
|
|
339
|
+
"cornflowerblue",
|
|
340
|
+
"cornsilk",
|
|
341
|
+
"crimson",
|
|
342
|
+
"cyan",
|
|
343
|
+
"darkblue",
|
|
344
|
+
"darkcyan",
|
|
345
|
+
"darkgoldenrod",
|
|
346
|
+
"darkgray",
|
|
347
|
+
"darkgreen",
|
|
348
|
+
"darkgrey",
|
|
349
|
+
"darkkhaki",
|
|
350
|
+
"darkmagenta",
|
|
351
|
+
"darkolivegreen",
|
|
352
|
+
"darkorange",
|
|
353
|
+
"darkorchid",
|
|
354
|
+
"darkred",
|
|
355
|
+
"darksalmon",
|
|
356
|
+
"darkseagreen",
|
|
357
|
+
"darkslateblue",
|
|
358
|
+
"darkslategray",
|
|
359
|
+
"darkslategrey",
|
|
360
|
+
"darkturquoise",
|
|
361
|
+
"darkviolet",
|
|
362
|
+
"deeppink",
|
|
363
|
+
"deepskyblue",
|
|
364
|
+
"dimgray",
|
|
365
|
+
"dimgrey",
|
|
366
|
+
"dodgerblue",
|
|
367
|
+
"firebrick",
|
|
368
|
+
"floralwhite",
|
|
369
|
+
"forestgreen",
|
|
370
|
+
"fuchsia",
|
|
371
|
+
"gainsboro",
|
|
372
|
+
"ghostwhite",
|
|
373
|
+
"gold",
|
|
374
|
+
"goldenrod",
|
|
375
|
+
"gray",
|
|
376
|
+
"grey",
|
|
377
|
+
"green",
|
|
378
|
+
"greenyellow",
|
|
379
|
+
"honeydew",
|
|
380
|
+
"hotpink",
|
|
381
|
+
"indianred",
|
|
382
|
+
"indigo",
|
|
383
|
+
"ivory",
|
|
384
|
+
"khaki",
|
|
385
|
+
"lavender",
|
|
386
|
+
"lavenderblush",
|
|
387
|
+
"lawngreen",
|
|
388
|
+
"lemonchiffon",
|
|
389
|
+
"lightblue",
|
|
390
|
+
"lightcoral",
|
|
391
|
+
"lightcyan",
|
|
392
|
+
"lightgoldenrodyellow",
|
|
393
|
+
"lightgray",
|
|
394
|
+
"lightgreen",
|
|
395
|
+
"lightgrey",
|
|
396
|
+
"lightpink",
|
|
397
|
+
"lightsalmon",
|
|
398
|
+
"lightseagreen",
|
|
399
|
+
"lightskyblue",
|
|
400
|
+
"lightslategray",
|
|
401
|
+
"lightslategrey",
|
|
402
|
+
"lightsteelblue",
|
|
403
|
+
"lightyellow",
|
|
404
|
+
"lime",
|
|
405
|
+
"limegreen",
|
|
406
|
+
"linen",
|
|
407
|
+
"magenta",
|
|
408
|
+
"maroon",
|
|
409
|
+
"mediumaquamarine",
|
|
410
|
+
"mediumblue",
|
|
411
|
+
"mediumorchid",
|
|
412
|
+
"mediumpurple",
|
|
413
|
+
"mediumseagreen",
|
|
414
|
+
"mediumslateblue",
|
|
415
|
+
"mediumspringgreen",
|
|
416
|
+
"mediumturquoise",
|
|
417
|
+
"mediumvioletred",
|
|
418
|
+
"midnightblue",
|
|
419
|
+
"mintcream",
|
|
420
|
+
"mistyrose",
|
|
421
|
+
"moccasin",
|
|
422
|
+
"navajowhite",
|
|
423
|
+
"navy",
|
|
424
|
+
"oldlace",
|
|
425
|
+
"olive",
|
|
426
|
+
"olivedrab",
|
|
427
|
+
"orange",
|
|
428
|
+
"orangered",
|
|
429
|
+
"orchid",
|
|
430
|
+
"palegoldenrod",
|
|
431
|
+
"palegreen",
|
|
432
|
+
"paleturquoise",
|
|
433
|
+
"palevioletred",
|
|
434
|
+
"papayawhip",
|
|
435
|
+
"peachpuff",
|
|
436
|
+
"peru",
|
|
437
|
+
"pink",
|
|
438
|
+
"plum",
|
|
439
|
+
"powderblue",
|
|
440
|
+
"purple",
|
|
441
|
+
"red",
|
|
442
|
+
"rosybrown",
|
|
443
|
+
"royalblue",
|
|
444
|
+
"saddlebrown",
|
|
445
|
+
"salmon",
|
|
446
|
+
"sandybrown",
|
|
447
|
+
"seagreen",
|
|
448
|
+
"seashell",
|
|
449
|
+
"sienna",
|
|
450
|
+
"silver",
|
|
451
|
+
"skyblue",
|
|
452
|
+
"slateblue",
|
|
453
|
+
"slategray",
|
|
454
|
+
"slategrey",
|
|
455
|
+
"snow",
|
|
456
|
+
"springgreen",
|
|
457
|
+
"steelblue",
|
|
458
|
+
"tan",
|
|
459
|
+
"teal",
|
|
460
|
+
"thistle",
|
|
461
|
+
"tomato",
|
|
462
|
+
"turquoise",
|
|
463
|
+
"violet",
|
|
464
|
+
"wheat",
|
|
465
|
+
"white",
|
|
466
|
+
"whitesmoke",
|
|
467
|
+
"yellow",
|
|
468
|
+
"yellowgreen"
|
|
469
|
+
]);
|
|
470
|
+
/**
|
|
471
|
+
* Returns the input if it is a valid color string, else null.
|
|
472
|
+
*
|
|
473
|
+
* #rgb, #rgba, #rrggbb, #rrggbbaa, rgb(r, g, b), rgb(r, g, b, a), hsl(h, s, l), hsl(h, s, l, a), hwb(h, w, b), hwb(h, w, b, a), lab(l, a, b), lab(l, a, b, a), lch(l, c, h), lch(l, c, h, a), oklab(l, a, b), oklab(l, a, b, a), oklch(l, c, h), oklch(l, c, h, a), color-mix(in oklab, var(--color-blue-500) 60%, transparent)
|
|
474
|
+
*/
|
|
475
|
+
function parseColor(input) {
|
|
476
|
+
if (CSS_COLOR_NAMES.has(input.toLowerCase())) return input;
|
|
477
|
+
if (input.startsWith("color:var(")) return input.slice(6);
|
|
478
|
+
if (input.startsWith("color:")) return parseColor(input.slice(6));
|
|
479
|
+
if (input.startsWith("#") && input.length === 4) return `#${input.slice(1)}`;
|
|
480
|
+
if (input.startsWith("#") && input.length === 5) return `#${input.slice(1)}`;
|
|
481
|
+
if (input.startsWith("#") && input.length === 7) return `#${input.slice(1)}`;
|
|
482
|
+
if (input.startsWith("#") && input.length === 9) return `#${input.slice(1)}`;
|
|
483
|
+
if (input.startsWith("rgb(")) return input.slice(4, -1);
|
|
484
|
+
if (input.startsWith("rgba(")) return input.slice(5, -1);
|
|
485
|
+
if (input.startsWith("hsl(")) return input.slice(4, -1);
|
|
486
|
+
if (input.startsWith("hsla(")) return input.slice(5, -1);
|
|
487
|
+
if (input.startsWith("hwb(")) return input.slice(4, -1);
|
|
488
|
+
if (input.startsWith("lab(")) return input.slice(4, -1);
|
|
489
|
+
if (input.startsWith("lch(")) return input.slice(4, -1);
|
|
490
|
+
if (input.startsWith("oklab(")) return input.slice(5, -1);
|
|
491
|
+
if (input.startsWith("oklch(")) return input.slice(6, -1);
|
|
492
|
+
if (input.startsWith("color-mix(")) return input.slice(9, -1);
|
|
493
|
+
return null;
|
|
494
|
+
}
|
|
495
|
+
var COLOR_KEYWORDS = /* @__PURE__ */ new Set([
|
|
496
|
+
"inherit",
|
|
497
|
+
"currentcolor",
|
|
498
|
+
"transparent"
|
|
499
|
+
]);
|
|
500
|
+
/**
|
|
501
|
+
* Declarations for a theme colour (#228), as Tailwind v4 emits them: `var(--color-<key>)` so runtime theme
|
|
502
|
+
* overrides apply; with an opacity modifier, a literal srgb color-mix fallback plus an oklab color-mix of the var.
|
|
503
|
+
*/
|
|
504
|
+
function themeColorDecls(prop, value, extra) {
|
|
505
|
+
const key = String(extra.realThemeValue);
|
|
506
|
+
const ref = COLOR_KEYWORDS.has(value.toLowerCase()) || value.startsWith("var(") || !/^[\w-]+$/.test(key) ? value : `var(--color-${key})`;
|
|
507
|
+
if (!extra.opacity) return [decl(prop, ref)];
|
|
508
|
+
const alpha = normalizeAlpha(String(extra.opacity));
|
|
509
|
+
if (!alpha) return [];
|
|
510
|
+
const supports = (amount) => atRule("supports", "(color:color-mix(in lab, red, red))", [decl(prop, `color-mix(in oklab, ${ref} ${amount}, transparent)`)]);
|
|
511
|
+
if (alpha.isVar) return [decl(prop, value), supports(alpha.amount)];
|
|
512
|
+
return [decl(prop, `color-mix(in srgb, ${value} ${alpha.amount}, transparent)`), supports(alpha.amount)];
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Opacity modifier → color-mix amount, as Tailwind v4 does: `50` → `50%`, `[37%]` → `37%`, `[0.5]` / `[.8]` → `50%` /
|
|
516
|
+
* `80%` (a bracketed number ≤ 1 is a fraction), `[var(--a)]` / `(--a)` → `var(--a)`.
|
|
517
|
+
*/
|
|
518
|
+
function normalizeAlpha(raw) {
|
|
519
|
+
const v = raw.trim();
|
|
520
|
+
const cp = /^\((--[\w-]+)\)$/.exec(v) ?? /^\[var\((--[\w-]+)\)\]$/.exec(v);
|
|
521
|
+
if (cp) return {
|
|
522
|
+
amount: `var(${cp[1]})`,
|
|
523
|
+
isVar: true
|
|
524
|
+
};
|
|
525
|
+
const m = /^(\[)?(\d+(?:\.\d+)?|\.\d+)(%)?(\])?$/.exec(v);
|
|
526
|
+
if (!m || !!m[1] !== !!m[4] || m[3] && !m[1]) return null;
|
|
527
|
+
const n = Number(m[2]);
|
|
528
|
+
return {
|
|
529
|
+
amount: `${+(m[3] ? n : m[1] && n <= 1 ? n * 100 : n).toFixed(4)}%`,
|
|
530
|
+
isVar: false
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
var MIX_SUPPORTS = "(color:color-mix(in lab, red, red))";
|
|
534
|
+
var COLOR_PROP = /(^|-)color$|^(fill|stroke)$|^--baro-gradient-(from|via|to)$/;
|
|
535
|
+
/**
|
|
536
|
+
* #393: an arbitrary or custom-property colour with an opacity modifier, as Tailwind 4.3.3 emits it: a literal
|
|
537
|
+
* colour with a literal alpha mixes directly (`color-mix(in oklab, #f00 50%, transparent)`); a var colour or a var
|
|
538
|
+
* alpha keeps the plain colour and mixes only under `@supports`. Returns null for an alpha it can't express.
|
|
539
|
+
*/
|
|
540
|
+
function colorAlphaDecls(prop, color, opacity) {
|
|
541
|
+
const alpha = normalizeAlpha(opacity);
|
|
542
|
+
if (!alpha) return null;
|
|
543
|
+
const mix = `color-mix(in oklab, ${color} ${alpha.amount}, transparent)`;
|
|
544
|
+
if (alpha.isVar || color.startsWith("var(")) return [decl(prop, color), atRule("supports", MIX_SUPPORTS, [decl(prop, mix)])];
|
|
545
|
+
return [decl(prop, mix)];
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* #393: applies an opacity modifier to every declaration of `nodes` whose value is one of `colors` (the colour an
|
|
549
|
+
* arbitrary / custom-property utility emitted without the modifier). Returns null when none matched or the alpha
|
|
550
|
+
* is invalid, so the caller emits nothing rather than dropping the modifier or writing a malformed value.
|
|
551
|
+
*/
|
|
552
|
+
function applyColorAlpha(nodes, colors, opacity) {
|
|
553
|
+
let matched = false;
|
|
554
|
+
let invalid = false;
|
|
555
|
+
const walk = (list) => list.flatMap((n) => {
|
|
556
|
+
if (n.type === "decl" && typeof n.value === "string" && colors.includes(n.value)) {
|
|
557
|
+
matched = true;
|
|
558
|
+
const out = COLOR_PROP.test(n.prop) ? colorAlphaDecls(n.prop, n.value, opacity) : null;
|
|
559
|
+
if (!out) invalid = true;
|
|
560
|
+
return out ?? [];
|
|
561
|
+
}
|
|
562
|
+
if (n.type === "at-rule" || n.type === "rule" || n.type === "style-rule" || n.type === "at-root") return [{
|
|
563
|
+
...n,
|
|
564
|
+
nodes: walk(n.nodes)
|
|
565
|
+
}];
|
|
566
|
+
if (n.type === "wrap") return [{
|
|
567
|
+
...n,
|
|
568
|
+
items: walk(n.items)
|
|
569
|
+
}];
|
|
570
|
+
return [n];
|
|
571
|
+
});
|
|
572
|
+
const out = walk(nodes);
|
|
573
|
+
return matched && !invalid ? out : null;
|
|
574
|
+
}
|
|
575
|
+
//#endregion
|
|
576
|
+
//#region src/core/registry.ts
|
|
577
|
+
/** #393: a handler result meaning "this class is invalid": the engine stops trying other registrations. */
|
|
578
|
+
var REJECT_CLASS = Object.freeze([]);
|
|
579
|
+
var utilityRegistry = [];
|
|
580
|
+
function registerUtility(util, ctx) {
|
|
581
|
+
const state = ctx && getContextState(ctx);
|
|
582
|
+
if (ctx && !state) throw new Error("Utility registration requires a context from createContext");
|
|
583
|
+
(state?.utilities || utilityRegistry).push(util);
|
|
584
|
+
if (ctx) clearContextCaches(ctx);
|
|
585
|
+
else {
|
|
586
|
+
parseResultCache.clear();
|
|
587
|
+
utilityCache.clear();
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
function getUtility(ctx) {
|
|
591
|
+
return ctx && getContextState(ctx)?.utilities || utilityRegistry;
|
|
592
|
+
}
|
|
593
|
+
var modifierRegistry = [];
|
|
594
|
+
/**
|
|
595
|
+
* staticModifier: A helper that registers a modifier name and an array of CSS selectors directly to the registry
|
|
596
|
+
*
|
|
597
|
+
* @example
|
|
598
|
+
* ```
|
|
599
|
+
* staticModifier('disabled', ['&:disabled'], { source: 'pseudo' });
|
|
600
|
+
* ```
|
|
601
|
+
*
|
|
602
|
+
* @param name The name of the modifier
|
|
603
|
+
* @param selectors The selectors of the modifier
|
|
604
|
+
* @param options The options of the modifier
|
|
605
|
+
*
|
|
606
|
+
* @returns {void}
|
|
607
|
+
*/
|
|
608
|
+
function staticModifier(name, selectors, options = {}, ctx) {
|
|
609
|
+
registerModifier({
|
|
610
|
+
name,
|
|
611
|
+
match: (mod) => mod === name,
|
|
612
|
+
modifySelector: ({ ..._rest }) => {
|
|
613
|
+
return selectors.map((sel) => ({
|
|
614
|
+
selector: sel,
|
|
615
|
+
source: options.source
|
|
616
|
+
}));
|
|
617
|
+
},
|
|
618
|
+
...options
|
|
619
|
+
}, ctx);
|
|
620
|
+
}
|
|
621
|
+
function functionalModifier(match, modifySelector, wrap, options = {}, ctx) {
|
|
622
|
+
registerModifier({
|
|
623
|
+
match,
|
|
624
|
+
modifySelector,
|
|
625
|
+
wrap,
|
|
626
|
+
...options
|
|
627
|
+
}, ctx);
|
|
628
|
+
}
|
|
629
|
+
function registerModifier(modifier, ctx) {
|
|
630
|
+
const state = ctx && getContextState(ctx);
|
|
631
|
+
if (ctx && !state) throw new Error("Modifier registration requires a context from createContext");
|
|
632
|
+
(state?.modifiers || modifierRegistry).push(modifier);
|
|
633
|
+
if (ctx) clearContextCaches(ctx);
|
|
634
|
+
}
|
|
635
|
+
function getModifier(ctx) {
|
|
636
|
+
return ctx && getContextState(ctx)?.modifiers || modifierRegistry;
|
|
637
|
+
}
|
|
638
|
+
var ESCAPE_REGEX = /[^A-Za-z0-9_-]/gu;
|
|
639
|
+
var UNSAFE_RAW = /^[\s\p{C}\p{Z}]$/u;
|
|
640
|
+
function escapeClassName(className) {
|
|
641
|
+
if (className === "-") return "\\-";
|
|
642
|
+
const lead = /^-?[0-9]/.exec(className);
|
|
643
|
+
if (lead) {
|
|
644
|
+
const i = lead[0].length - 1;
|
|
645
|
+
return className.slice(0, i) + "\\" + className.charCodeAt(i).toString(16) + " " + escapeRest(className.slice(i + 1));
|
|
646
|
+
}
|
|
647
|
+
return escapeRest(className);
|
|
648
|
+
}
|
|
649
|
+
function escapeRest(className) {
|
|
650
|
+
return className.replace(ESCAPE_REGEX, (c) => {
|
|
651
|
+
if (c === " ") return "\\x20 ";
|
|
652
|
+
if (c === ".") return "\\.";
|
|
653
|
+
if (c === "/") return "\\/";
|
|
654
|
+
if (c === ":") return "\\:";
|
|
655
|
+
if (c === "[") return "\\[";
|
|
656
|
+
if (c === "]") return "\\]";
|
|
657
|
+
if (c === "(") return "\\(";
|
|
658
|
+
if (c === ")") return "\\)";
|
|
659
|
+
if (c === "%") return "\\%";
|
|
660
|
+
if (c === "#") return "\\#";
|
|
661
|
+
if (c === ",") return "\\,";
|
|
662
|
+
if (c === "=") return "\\=";
|
|
663
|
+
if (c === "&") return "\\&";
|
|
664
|
+
if (c === "~") return "\\~";
|
|
665
|
+
if (c === "*") return "\\*";
|
|
666
|
+
if (c === "$") return "\\$";
|
|
667
|
+
if (c === "^") return "\\^";
|
|
668
|
+
if (c === "+") return "\\+";
|
|
669
|
+
if (c === "?") return "\\?";
|
|
670
|
+
if (c === "!") return "\\!";
|
|
671
|
+
if (c === "@") return "\\@";
|
|
672
|
+
if (c === "'") return "\\'";
|
|
673
|
+
if (c === "\"") return "\\\"";
|
|
674
|
+
if (c === "`") return "\\`";
|
|
675
|
+
if (c === ";") return "\\;";
|
|
676
|
+
if (c === "<") return "\\<";
|
|
677
|
+
if (c === ">") return "\\>";
|
|
678
|
+
if (c === "{") return "\\{";
|
|
679
|
+
if (c === "}") return "\\}";
|
|
680
|
+
if (c === "|") return "\\|";
|
|
681
|
+
if (c === "\\") return "\\\\";
|
|
682
|
+
if (UNSAFE_RAW.test(c)) return "\\" + c.codePointAt(0).toString(16) + " ";
|
|
683
|
+
return "\\" + c;
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* staticUtility: A helper that registers a utility name and an array of CSS declaration pairs directly to the registry
|
|
688
|
+
*
|
|
689
|
+
* @example
|
|
690
|
+
* ```
|
|
691
|
+
* staticUtility('block', [['display', 'block']]);
|
|
692
|
+
* staticUtility('hidden', [['display', 'none']]);
|
|
693
|
+
* staticUtility('space-x-px', [
|
|
694
|
+
* [
|
|
695
|
+
* '& > :not([hidden]) ~ :not([hidden])', // selector
|
|
696
|
+
* [
|
|
697
|
+
* ['margin-inline-start', '1px'], // [prop, value]
|
|
698
|
+
* ['margin-inline-end', '1px'], // [prop, value]
|
|
699
|
+
* ],
|
|
700
|
+
* ],
|
|
701
|
+
* ]);
|
|
702
|
+
* ```
|
|
703
|
+
*
|
|
704
|
+
* @param name The name of the utility
|
|
705
|
+
* @param decls The declarations of the utility
|
|
706
|
+
* @param opts The options of the utility
|
|
707
|
+
*
|
|
708
|
+
* @returns {void}
|
|
709
|
+
*/
|
|
710
|
+
function staticUtility(name, decls, opts, ctx) {
|
|
711
|
+
registerUtility({
|
|
712
|
+
name,
|
|
713
|
+
match: (className) => {
|
|
714
|
+
return className === name;
|
|
715
|
+
},
|
|
716
|
+
handler: (value) => {
|
|
717
|
+
return decls.flatMap((params) => {
|
|
718
|
+
if (params.type) return [params];
|
|
719
|
+
if (typeof params === "function") return [params(value)];
|
|
720
|
+
const [a, b] = params;
|
|
721
|
+
if (typeof b === "string") return [decl(a, b)];
|
|
722
|
+
else if (Array.isArray(b)) return [rule(a, b.map(([prop, value]) => decl(prop, value)))];
|
|
723
|
+
return [];
|
|
724
|
+
});
|
|
725
|
+
},
|
|
726
|
+
description: opts?.description,
|
|
727
|
+
category: opts?.category,
|
|
728
|
+
priority: opts?.priority
|
|
729
|
+
}, ctx);
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* functionalUtility: A helper that registers dynamic utilities (theme, arbitrary, custom, negative, fraction, etc.) directly
|
|
733
|
+
*
|
|
734
|
+
* Example:
|
|
735
|
+
* functionalUtility({
|
|
736
|
+
* name: 'z',
|
|
737
|
+
* supportsNegative: true,
|
|
738
|
+
* themeKeys: ['--z-index'],
|
|
739
|
+
* handleBareValue: ({ value }) => isPositiveInteger(value) ? value : null,
|
|
740
|
+
* handle: (value) => [decl('z-index', value)],
|
|
741
|
+
* description: 'z-index utility',
|
|
742
|
+
* category: 'layout',
|
|
743
|
+
* });
|
|
744
|
+
*/
|
|
745
|
+
/**
|
|
746
|
+
* #300: a theme key that no built-in utility names (`theme.extend.borderRadius.card`) still resolves, as in
|
|
747
|
+
* Tailwind 4 where `--radius-card` gives `rounded-card`. Only word keys that start with a letter (numbers stay
|
|
748
|
+
* bare values), never `DEFAULT`; unknown keys return null so the utility emits nothing (#213).
|
|
749
|
+
*/
|
|
750
|
+
function themeKeyEntry(ctx, namespace, key) {
|
|
751
|
+
if (key === "DEFAULT" || !/^[a-zA-Z][\w-]*$/.test(key) || typeof ctx?.theme !== "function") return void 0;
|
|
752
|
+
const table = ctx.theme(namespace);
|
|
753
|
+
if (!table || typeof table !== "object" || !Object.prototype.hasOwnProperty.call(table, key)) return void 0;
|
|
754
|
+
return table[key] ?? void 0;
|
|
755
|
+
}
|
|
756
|
+
/** #300: the literal value of `theme.<namespace>.<key>` when it is a string, else null. */
|
|
757
|
+
function themeKeyValue(ctx, namespace, key) {
|
|
758
|
+
const v = themeKeyEntry(ctx, namespace, key);
|
|
759
|
+
return typeof v === "string" ? v : null;
|
|
760
|
+
}
|
|
761
|
+
/** #300: `var(--<varPrefix>-<key>)` when `theme.<namespace>.<key>` exists (the :root var BaroCSS emits for it), else null. */
|
|
762
|
+
function themeKeyVar(ctx, namespace, key, varPrefix) {
|
|
763
|
+
return themeKeyEntry(ctx, namespace, key) === void 0 ? null : `var(--${varPrefix}-${key})`;
|
|
764
|
+
}
|
|
765
|
+
/** #261: `var(--spacing-<key>)` for a named (non-numeric) `theme.spacing` key, else null. */
|
|
766
|
+
function spacingKeyValue(ctx, key, negative) {
|
|
767
|
+
if (key === "px" || !/^[a-zA-Z][\w-]*$/.test(key) || ctx.theme("spacing", key) == null) return null;
|
|
768
|
+
const ref = `var(--spacing-${key})`;
|
|
769
|
+
return negative ? `calc(${ref} * -1)` : ref;
|
|
770
|
+
}
|
|
771
|
+
function functionalUtility(opts, ctx) {
|
|
772
|
+
registerUtility({
|
|
773
|
+
name: opts.name,
|
|
774
|
+
match: (className) => className.startsWith(opts.name + "-"),
|
|
775
|
+
handler: (value, ctx, token, _options) => {
|
|
776
|
+
let finalValue = value;
|
|
777
|
+
const parsedUtility = token;
|
|
778
|
+
const extra = { opacity: token.opacity };
|
|
779
|
+
if (opts.supportsOpacity && !token.arbitrary && !token.customProperty && value.includes("/")) {
|
|
780
|
+
const list = value.split("/");
|
|
781
|
+
if (list.length >= 2) {
|
|
782
|
+
extra.opacity = list.pop();
|
|
783
|
+
finalValue = list.join("/");
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
const splitModifier = !token.arbitrary && !token.customProperty && value.includes("/");
|
|
787
|
+
if (opts.supportsOpacity && (extra.opacity || splitModifier) && !normalizeAlpha(String(extra.opacity ?? ""))) {
|
|
788
|
+
const v = parsedUtility.arbitrary ? finalValue.replace(/_/g, " ") : finalValue;
|
|
789
|
+
return (parsedUtility.customProperty ? !/^[\w-]+:/.test(v) || v.startsWith("color:") : parsedUtility.arbitrary ? !!parseColor(v) || /^var\(--/.test(v) || v.startsWith("color:") : false) ? REJECT_CLASS : [];
|
|
790
|
+
}
|
|
791
|
+
const direct = (x) => {
|
|
792
|
+
if (opts.supportsArbitrary && parsedUtility.arbitrary) {
|
|
793
|
+
const processedValue = normalizeMathSpacing(expandThemeFunctions(finalValue.replace(/_/g, " ")));
|
|
794
|
+
if (opts.handle) {
|
|
795
|
+
const result = opts.handle(processedValue, ctx, token, x);
|
|
796
|
+
if (result) return result;
|
|
797
|
+
}
|
|
798
|
+
if (opts.prop) return [decl(opts.prop, processedValue)];
|
|
799
|
+
return [];
|
|
800
|
+
}
|
|
801
|
+
if (opts.supportsCustomProperty && parsedUtility.customProperty) {
|
|
802
|
+
if (opts.handleCustomProperty) return opts.handleCustomProperty(finalValue, ctx, token, x) ?? null;
|
|
803
|
+
const customValue = `var(${finalValue})`;
|
|
804
|
+
if (opts.handle) {
|
|
805
|
+
const result = opts.handle(customValue, ctx, token, x);
|
|
806
|
+
if (result) return result;
|
|
807
|
+
}
|
|
808
|
+
if (opts.prop) return [decl(opts.prop, customValue)];
|
|
809
|
+
return [];
|
|
810
|
+
}
|
|
811
|
+
return null;
|
|
812
|
+
};
|
|
813
|
+
if (opts.supportsArbitrary && parsedUtility.arbitrary || opts.supportsCustomProperty && parsedUtility.customProperty) {
|
|
814
|
+
const result = direct(extra);
|
|
815
|
+
if (opts.supportsOpacity && !opts.ownsOpacity && extra.opacity && result?.length) {
|
|
816
|
+
const raw = parsedUtility.arbitrary ? normalizeMathSpacing(expandThemeFunctions(finalValue.replace(/_/g, " "))) : `var(${finalValue})`;
|
|
817
|
+
const hint = parsedUtility.arbitrary ? /^color:(.+)$/.exec(raw)?.[1] : /^color:(--.+)$/.exec(finalValue)?.[1];
|
|
818
|
+
return applyColorAlpha(result, [raw, ...hint ? [hint, `var(${hint})`] : []], String(extra.opacity)) ?? [];
|
|
819
|
+
}
|
|
820
|
+
return result;
|
|
821
|
+
}
|
|
822
|
+
let themeValue;
|
|
823
|
+
if (opts.themeKey && ctx.theme) themeValue = themeScalar(ctx.theme(opts.themeKey, finalValue));
|
|
824
|
+
let namespace = themeValue !== void 0 ? opts.themeKey : void 0;
|
|
825
|
+
if (!themeValue && opts.themeKeys && ctx.theme) for (const key of opts.themeKeys) {
|
|
826
|
+
themeValue = themeScalar(ctx.theme(key, finalValue));
|
|
827
|
+
if (themeValue !== void 0) {
|
|
828
|
+
namespace = key;
|
|
829
|
+
break;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
if (themeValue !== void 0) {
|
|
833
|
+
extra.themeNamespace = namespace;
|
|
834
|
+
extra.themeKey = finalValue;
|
|
835
|
+
if (namespace === "colors" || !(opts.themeKeys ?? [opts.themeKey]).includes("colors")) extra.realThemeValue = finalValue;
|
|
836
|
+
finalValue = themeValue;
|
|
837
|
+
if (opts.prop) return [decl(opts.prop, finalValue)];
|
|
516
838
|
if (opts.handle) {
|
|
517
839
|
const result = opts.handle(finalValue, ctx, token, extra);
|
|
518
840
|
if (result) return result;
|
|
@@ -913,6 +1235,48 @@ function isBalancedPrelude(text) {
|
|
|
913
1235
|
return stack.length === 0 && !quote;
|
|
914
1236
|
}
|
|
915
1237
|
/**
|
|
1238
|
+
* #396: returns `selector` with every quoted string and every `[...]` group (brackets included, nested groups and
|
|
1239
|
+
* escapes inside them too) replaced by a NUL placeholder per character. Backslash escapes outside those regions
|
|
1240
|
+
* are kept verbatim; parentheses are kept. The placeholder is not an identifier character, so it ends a token.
|
|
1241
|
+
*/
|
|
1242
|
+
function maskStringsAndBrackets(selector) {
|
|
1243
|
+
let out = "";
|
|
1244
|
+
let quote = "";
|
|
1245
|
+
let bracket = 0;
|
|
1246
|
+
for (let i = 0; i < selector.length; i++) {
|
|
1247
|
+
const c = selector[i];
|
|
1248
|
+
const masked = quote !== "" || bracket > 0;
|
|
1249
|
+
if (c === "\\") {
|
|
1250
|
+
const pair = selector.slice(i, i + 2);
|
|
1251
|
+
out += masked ? "\0".repeat(pair.length) : pair;
|
|
1252
|
+
i++;
|
|
1253
|
+
continue;
|
|
1254
|
+
}
|
|
1255
|
+
if (quote) {
|
|
1256
|
+
if (c === quote) quote = "";
|
|
1257
|
+
out += "\0";
|
|
1258
|
+
continue;
|
|
1259
|
+
}
|
|
1260
|
+
if (c === "\"" || c === "'") {
|
|
1261
|
+
quote = c;
|
|
1262
|
+
out += "\0";
|
|
1263
|
+
continue;
|
|
1264
|
+
}
|
|
1265
|
+
if (c === "[") {
|
|
1266
|
+
bracket++;
|
|
1267
|
+
out += "\0";
|
|
1268
|
+
continue;
|
|
1269
|
+
}
|
|
1270
|
+
if (c === "]" && bracket > 0) {
|
|
1271
|
+
bracket--;
|
|
1272
|
+
out += "\0";
|
|
1273
|
+
continue;
|
|
1274
|
+
}
|
|
1275
|
+
out += masked ? "\0" : c;
|
|
1276
|
+
}
|
|
1277
|
+
return out;
|
|
1278
|
+
}
|
|
1279
|
+
/**
|
|
916
1280
|
* #392: true when every top-level comma part of an emitted selector names `escapedClass` (a class selector
|
|
917
1281
|
* already escaped with escapeClassName, including its leading dot) as a whole class token, or, when
|
|
918
1282
|
* `allowNesting` is set, uses the nesting selector `&`. Escapes, quoted strings and bracket groups are skipped
|
|
@@ -942,7 +1306,8 @@ function isScopedSelector(selector, escapedClass, allowNesting = false) {
|
|
|
942
1306
|
}
|
|
943
1307
|
}
|
|
944
1308
|
parts.push(selector.slice(start));
|
|
945
|
-
return parts.every((
|
|
1309
|
+
return parts.every((raw) => {
|
|
1310
|
+
const part = maskStringsAndBrackets(raw);
|
|
946
1311
|
if (allowNesting && part.includes("&")) return true;
|
|
947
1312
|
for (let at = part.indexOf(escapedClass); at !== -1; at = part.indexOf(escapedClass, at + 1)) {
|
|
948
1313
|
if (at > 0 && part[at - 1] === "\\") continue;
|
|
@@ -1044,6 +1409,13 @@ function parseModifier(value) {
|
|
|
1044
1409
|
function nameSort(a, b) {
|
|
1045
1410
|
return b.name.length - a.name.length;
|
|
1046
1411
|
}
|
|
1412
|
+
/** #393: index of the `close` that balances the value opened just before `s` (depth starts at 1), or -1. */
|
|
1413
|
+
function matchingClose(s, open, close) {
|
|
1414
|
+
let depth = 1;
|
|
1415
|
+
for (let i = 0; i < s.length; i++) if (s[i] === open) depth++;
|
|
1416
|
+
else if (s[i] === close && --depth === 0) return i;
|
|
1417
|
+
return -1;
|
|
1418
|
+
}
|
|
1047
1419
|
/**
|
|
1048
1420
|
* Parse utility token
|
|
1049
1421
|
*/
|
|
@@ -1072,15 +1444,27 @@ function parseUtility(value, ctx) {
|
|
|
1072
1444
|
if (value.startsWith("-")) negative = true;
|
|
1073
1445
|
if (value.includes("-[")) {
|
|
1074
1446
|
[prefix, utilityValue] = value.split("-[");
|
|
1075
|
-
const closeIdx = utilityValue
|
|
1447
|
+
const closeIdx = matchingClose(utilityValue, "[", "]");
|
|
1076
1448
|
if (closeIdx !== -1 && closeIdx < utilityValue.length - 1 && utilityValue[closeIdx + 1] === "/") {
|
|
1077
1449
|
opacity = utilityValue.slice(closeIdx + 2);
|
|
1450
|
+
if (!opacity) return {
|
|
1451
|
+
prefix: "",
|
|
1452
|
+
value: ""
|
|
1453
|
+
};
|
|
1078
1454
|
utilityValue = utilityValue.slice(0, closeIdx);
|
|
1079
1455
|
} else utilityValue = utilityValue.replace(/]$/, "");
|
|
1080
1456
|
arbitrary = true;
|
|
1081
1457
|
} else if (value.includes("-(")) {
|
|
1082
1458
|
[prefix, utilityValue] = value.split("-(");
|
|
1083
|
-
|
|
1459
|
+
const closeIdx = matchingClose(utilityValue, "(", ")");
|
|
1460
|
+
if (closeIdx !== -1 && closeIdx < utilityValue.length - 1 && utilityValue[closeIdx + 1] === "/") {
|
|
1461
|
+
opacity = utilityValue.slice(closeIdx + 2);
|
|
1462
|
+
if (!opacity) return {
|
|
1463
|
+
prefix: "",
|
|
1464
|
+
value: ""
|
|
1465
|
+
};
|
|
1466
|
+
utilityValue = utilityValue.slice(0, closeIdx);
|
|
1467
|
+
} else utilityValue = utilityValue.replace(/\)$/, "");
|
|
1084
1468
|
customProperty = true;
|
|
1085
1469
|
} else {
|
|
1086
1470
|
const sortedUtilities = [...getUtility(ctx)].sort(nameSort);
|
|
@@ -1132,6 +1516,13 @@ var uniqueDescriptors = (node) => {
|
|
|
1132
1516
|
const seen = /* @__PURE__ */ new Set();
|
|
1133
1517
|
return node.nodes.filter((c) => c.type !== "decl" || !seen.has(c.prop) && !!seen.add(c.prop));
|
|
1134
1518
|
};
|
|
1519
|
+
var NO_IMPORTANT_AT = /* @__PURE__ */ new Set([
|
|
1520
|
+
"property",
|
|
1521
|
+
"font-face",
|
|
1522
|
+
"keyframes",
|
|
1523
|
+
"-webkit-keyframes",
|
|
1524
|
+
"counter-style"
|
|
1525
|
+
]);
|
|
1135
1526
|
var isSafeDecl = (prop, value) => isStructureSafeValue(String(prop)) && isStructureSafeValue(String(value ?? "")) && !hasHtmlEndTagOpener(String(prop)) && !hasHtmlEndTagOpener(String(value ?? ""));
|
|
1136
1527
|
var importantPrefix = "!important";
|
|
1137
1528
|
/**
|
|
@@ -1202,10 +1593,15 @@ function astToCss(ast, baseSelector, opts, _indent = "") {
|
|
|
1202
1593
|
if (!isSafePrelude(node.selector) || !inScope(node.selector)) return "";
|
|
1203
1594
|
if (minify) return `${indent}${node.selector} {${astToCss(node.nodes, baseSelector, nestedOpts, nextIndent)}}`;
|
|
1204
1595
|
else return `${indent}${node.selector} {\n${astToCss(node.nodes, baseSelector, nestedOpts, nextIndent)}${indent}}`;
|
|
1205
|
-
case "at-rule":
|
|
1596
|
+
case "at-rule": {
|
|
1206
1597
|
if (!isSafePrelude(node.name) || !isSafePrelude(node.params)) return "";
|
|
1207
|
-
|
|
1208
|
-
|
|
1598
|
+
const atOpts = opts?.important && NO_IMPORTANT_AT.has(node.name) ? {
|
|
1599
|
+
...opts,
|
|
1600
|
+
important: false
|
|
1601
|
+
} : opts;
|
|
1602
|
+
if (minify) return `${indent}@${node.name} ${node.params}{${astToCss(node.nodes, baseSelector, atOpts, nextIndent)}}`;
|
|
1603
|
+
else return `${indent}@${node.name} ${node.params} {\n${astToCss(node.nodes, baseSelector, atOpts, nextIndent)}${indent}}`;
|
|
1604
|
+
}
|
|
1209
1605
|
case "comment": return minify ? "" : `${indent}/* ${node.text} */`;
|
|
1210
1606
|
case "raw": return `${indent}${node.value}`;
|
|
1211
1607
|
default:
|
|
@@ -1564,6 +1960,552 @@ function applyVarPrefix(ast, ctx) {
|
|
|
1564
1960
|
return walk(ast);
|
|
1565
1961
|
}
|
|
1566
1962
|
//#endregion
|
|
1963
|
+
//#region src/core/tw-property-order.ts
|
|
1964
|
+
var TW_PROPERTY_ORDER = [
|
|
1965
|
+
"container-type",
|
|
1966
|
+
"pointer-events",
|
|
1967
|
+
"visibility",
|
|
1968
|
+
"position",
|
|
1969
|
+
"inset",
|
|
1970
|
+
"inset-inline",
|
|
1971
|
+
"inset-block",
|
|
1972
|
+
"inset-inline-start",
|
|
1973
|
+
"inset-inline-end",
|
|
1974
|
+
"inset-block-start",
|
|
1975
|
+
"inset-block-end",
|
|
1976
|
+
"top",
|
|
1977
|
+
"right",
|
|
1978
|
+
"bottom",
|
|
1979
|
+
"left",
|
|
1980
|
+
"isolation",
|
|
1981
|
+
"z-index",
|
|
1982
|
+
"order",
|
|
1983
|
+
"grid-column",
|
|
1984
|
+
"grid-column-start",
|
|
1985
|
+
"grid-column-end",
|
|
1986
|
+
"grid-row",
|
|
1987
|
+
"grid-row-start",
|
|
1988
|
+
"grid-row-end",
|
|
1989
|
+
"float",
|
|
1990
|
+
"clear",
|
|
1991
|
+
"--tw-container-component",
|
|
1992
|
+
"margin",
|
|
1993
|
+
"margin-inline",
|
|
1994
|
+
"margin-block",
|
|
1995
|
+
"margin-inline-start",
|
|
1996
|
+
"margin-inline-end",
|
|
1997
|
+
"margin-block-start",
|
|
1998
|
+
"margin-block-end",
|
|
1999
|
+
"margin-top",
|
|
2000
|
+
"margin-right",
|
|
2001
|
+
"margin-bottom",
|
|
2002
|
+
"margin-left",
|
|
2003
|
+
"box-sizing",
|
|
2004
|
+
"display",
|
|
2005
|
+
"field-sizing",
|
|
2006
|
+
"aspect-ratio",
|
|
2007
|
+
"height",
|
|
2008
|
+
"max-height",
|
|
2009
|
+
"min-height",
|
|
2010
|
+
"width",
|
|
2011
|
+
"max-width",
|
|
2012
|
+
"min-width",
|
|
2013
|
+
"flex",
|
|
2014
|
+
"flex-shrink",
|
|
2015
|
+
"flex-grow",
|
|
2016
|
+
"flex-basis",
|
|
2017
|
+
"table-layout",
|
|
2018
|
+
"caption-side",
|
|
2019
|
+
"border-collapse",
|
|
2020
|
+
"border-spacing",
|
|
2021
|
+
"transform-origin",
|
|
2022
|
+
"translate",
|
|
2023
|
+
"--tw-translate-x",
|
|
2024
|
+
"--tw-translate-y",
|
|
2025
|
+
"--tw-translate-z",
|
|
2026
|
+
"scale",
|
|
2027
|
+
"--tw-scale-x",
|
|
2028
|
+
"--tw-scale-y",
|
|
2029
|
+
"--tw-scale-z",
|
|
2030
|
+
"rotate",
|
|
2031
|
+
"--tw-rotate-x",
|
|
2032
|
+
"--tw-rotate-y",
|
|
2033
|
+
"--tw-rotate-z",
|
|
2034
|
+
"--tw-skew-x",
|
|
2035
|
+
"--tw-skew-y",
|
|
2036
|
+
"transform",
|
|
2037
|
+
"zoom",
|
|
2038
|
+
"animation",
|
|
2039
|
+
"cursor",
|
|
2040
|
+
"touch-action",
|
|
2041
|
+
"--tw-pan-x",
|
|
2042
|
+
"--tw-pan-y",
|
|
2043
|
+
"--tw-pinch-zoom",
|
|
2044
|
+
"resize",
|
|
2045
|
+
"scroll-snap-type",
|
|
2046
|
+
"--tw-scroll-snap-strictness",
|
|
2047
|
+
"scroll-snap-align",
|
|
2048
|
+
"scroll-snap-stop",
|
|
2049
|
+
"scroll-margin",
|
|
2050
|
+
"scroll-margin-inline",
|
|
2051
|
+
"scroll-margin-block",
|
|
2052
|
+
"scroll-margin-inline-start",
|
|
2053
|
+
"scroll-margin-inline-end",
|
|
2054
|
+
"scroll-margin-block-start",
|
|
2055
|
+
"scroll-margin-block-end",
|
|
2056
|
+
"scroll-margin-top",
|
|
2057
|
+
"scroll-margin-right",
|
|
2058
|
+
"scroll-margin-bottom",
|
|
2059
|
+
"scroll-margin-left",
|
|
2060
|
+
"scroll-padding",
|
|
2061
|
+
"scroll-padding-inline",
|
|
2062
|
+
"scroll-padding-block",
|
|
2063
|
+
"scroll-padding-inline-start",
|
|
2064
|
+
"scroll-padding-inline-end",
|
|
2065
|
+
"scroll-padding-block-start",
|
|
2066
|
+
"scroll-padding-block-end",
|
|
2067
|
+
"scroll-padding-top",
|
|
2068
|
+
"scroll-padding-right",
|
|
2069
|
+
"scroll-padding-bottom",
|
|
2070
|
+
"scroll-padding-left",
|
|
2071
|
+
"scrollbar-width",
|
|
2072
|
+
"scrollbar-color",
|
|
2073
|
+
"scrollbar-gutter",
|
|
2074
|
+
"list-style-position",
|
|
2075
|
+
"list-style-type",
|
|
2076
|
+
"list-style-image",
|
|
2077
|
+
"appearance",
|
|
2078
|
+
"columns",
|
|
2079
|
+
"break-before",
|
|
2080
|
+
"break-inside",
|
|
2081
|
+
"break-after",
|
|
2082
|
+
"grid-auto-columns",
|
|
2083
|
+
"grid-auto-flow",
|
|
2084
|
+
"grid-auto-rows",
|
|
2085
|
+
"grid-template-columns",
|
|
2086
|
+
"grid-template-rows",
|
|
2087
|
+
"flex-direction",
|
|
2088
|
+
"flex-wrap",
|
|
2089
|
+
"place-content",
|
|
2090
|
+
"place-items",
|
|
2091
|
+
"align-content",
|
|
2092
|
+
"align-items",
|
|
2093
|
+
"justify-content",
|
|
2094
|
+
"justify-items",
|
|
2095
|
+
"gap",
|
|
2096
|
+
"column-gap",
|
|
2097
|
+
"row-gap",
|
|
2098
|
+
"--tw-space-x-reverse",
|
|
2099
|
+
"--tw-space-y-reverse",
|
|
2100
|
+
"divide-x-width",
|
|
2101
|
+
"divide-y-width",
|
|
2102
|
+
"--tw-divide-y-reverse",
|
|
2103
|
+
"divide-style",
|
|
2104
|
+
"divide-color",
|
|
2105
|
+
"place-self",
|
|
2106
|
+
"align-self",
|
|
2107
|
+
"justify-self",
|
|
2108
|
+
"overflow",
|
|
2109
|
+
"overflow-x",
|
|
2110
|
+
"overflow-y",
|
|
2111
|
+
"overscroll-behavior",
|
|
2112
|
+
"overscroll-behavior-x",
|
|
2113
|
+
"overscroll-behavior-y",
|
|
2114
|
+
"scroll-behavior",
|
|
2115
|
+
"border-radius",
|
|
2116
|
+
"border-start-radius",
|
|
2117
|
+
"border-end-radius",
|
|
2118
|
+
"border-top-radius",
|
|
2119
|
+
"border-right-radius",
|
|
2120
|
+
"border-bottom-radius",
|
|
2121
|
+
"border-left-radius",
|
|
2122
|
+
"border-start-start-radius",
|
|
2123
|
+
"border-start-end-radius",
|
|
2124
|
+
"border-end-end-radius",
|
|
2125
|
+
"border-end-start-radius",
|
|
2126
|
+
"border-top-left-radius",
|
|
2127
|
+
"border-top-right-radius",
|
|
2128
|
+
"border-bottom-right-radius",
|
|
2129
|
+
"border-bottom-left-radius",
|
|
2130
|
+
"border-width",
|
|
2131
|
+
"border-inline-width",
|
|
2132
|
+
"border-block-width",
|
|
2133
|
+
"border-inline-start-width",
|
|
2134
|
+
"border-inline-end-width",
|
|
2135
|
+
"border-block-start-width",
|
|
2136
|
+
"border-block-end-width",
|
|
2137
|
+
"border-top-width",
|
|
2138
|
+
"border-right-width",
|
|
2139
|
+
"border-bottom-width",
|
|
2140
|
+
"border-left-width",
|
|
2141
|
+
"border-style",
|
|
2142
|
+
"border-inline-style",
|
|
2143
|
+
"border-block-style",
|
|
2144
|
+
"border-inline-start-style",
|
|
2145
|
+
"border-inline-end-style",
|
|
2146
|
+
"border-block-start-style",
|
|
2147
|
+
"border-block-end-style",
|
|
2148
|
+
"border-top-style",
|
|
2149
|
+
"border-right-style",
|
|
2150
|
+
"border-bottom-style",
|
|
2151
|
+
"border-left-style",
|
|
2152
|
+
"border-color",
|
|
2153
|
+
"border-inline-color",
|
|
2154
|
+
"border-block-color",
|
|
2155
|
+
"border-inline-start-color",
|
|
2156
|
+
"border-inline-end-color",
|
|
2157
|
+
"border-block-start-color",
|
|
2158
|
+
"border-block-end-color",
|
|
2159
|
+
"border-top-color",
|
|
2160
|
+
"border-right-color",
|
|
2161
|
+
"border-bottom-color",
|
|
2162
|
+
"border-left-color",
|
|
2163
|
+
"background-color",
|
|
2164
|
+
"background-image",
|
|
2165
|
+
"--tw-gradient-position",
|
|
2166
|
+
"--tw-gradient-stops",
|
|
2167
|
+
"--tw-gradient-via-stops",
|
|
2168
|
+
"--tw-gradient-from",
|
|
2169
|
+
"--tw-gradient-from-position",
|
|
2170
|
+
"--tw-gradient-via",
|
|
2171
|
+
"--tw-gradient-via-position",
|
|
2172
|
+
"--tw-gradient-to",
|
|
2173
|
+
"--tw-gradient-to-position",
|
|
2174
|
+
"mask-image",
|
|
2175
|
+
"--tw-mask-top",
|
|
2176
|
+
"--tw-mask-top-from-color",
|
|
2177
|
+
"--tw-mask-top-from-position",
|
|
2178
|
+
"--tw-mask-top-to-color",
|
|
2179
|
+
"--tw-mask-top-to-position",
|
|
2180
|
+
"--tw-mask-right",
|
|
2181
|
+
"--tw-mask-right-from-color",
|
|
2182
|
+
"--tw-mask-right-from-position",
|
|
2183
|
+
"--tw-mask-right-to-color",
|
|
2184
|
+
"--tw-mask-right-to-position",
|
|
2185
|
+
"--tw-mask-bottom",
|
|
2186
|
+
"--tw-mask-bottom-from-color",
|
|
2187
|
+
"--tw-mask-bottom-from-position",
|
|
2188
|
+
"--tw-mask-bottom-to-color",
|
|
2189
|
+
"--tw-mask-bottom-to-position",
|
|
2190
|
+
"--tw-mask-left",
|
|
2191
|
+
"--tw-mask-left-from-color",
|
|
2192
|
+
"--tw-mask-left-from-position",
|
|
2193
|
+
"--tw-mask-left-to-color",
|
|
2194
|
+
"--tw-mask-left-to-position",
|
|
2195
|
+
"--tw-mask-linear",
|
|
2196
|
+
"--tw-mask-linear-position",
|
|
2197
|
+
"--tw-mask-linear-from-color",
|
|
2198
|
+
"--tw-mask-linear-from-position",
|
|
2199
|
+
"--tw-mask-linear-to-color",
|
|
2200
|
+
"--tw-mask-linear-to-position",
|
|
2201
|
+
"--tw-mask-radial",
|
|
2202
|
+
"--tw-mask-radial-shape",
|
|
2203
|
+
"--tw-mask-radial-size",
|
|
2204
|
+
"--tw-mask-radial-position",
|
|
2205
|
+
"--tw-mask-radial-from-color",
|
|
2206
|
+
"--tw-mask-radial-from-position",
|
|
2207
|
+
"--tw-mask-radial-to-color",
|
|
2208
|
+
"--tw-mask-radial-to-position",
|
|
2209
|
+
"--tw-mask-conic",
|
|
2210
|
+
"--tw-mask-conic-position",
|
|
2211
|
+
"--tw-mask-conic-from-color",
|
|
2212
|
+
"--tw-mask-conic-from-position",
|
|
2213
|
+
"--tw-mask-conic-to-color",
|
|
2214
|
+
"--tw-mask-conic-to-position",
|
|
2215
|
+
"box-decoration-break",
|
|
2216
|
+
"background-size",
|
|
2217
|
+
"background-attachment",
|
|
2218
|
+
"background-clip",
|
|
2219
|
+
"background-position",
|
|
2220
|
+
"background-repeat",
|
|
2221
|
+
"background-origin",
|
|
2222
|
+
"mask-composite",
|
|
2223
|
+
"mask-mode",
|
|
2224
|
+
"mask-type",
|
|
2225
|
+
"mask-size",
|
|
2226
|
+
"mask-clip",
|
|
2227
|
+
"mask-position",
|
|
2228
|
+
"mask-repeat",
|
|
2229
|
+
"mask-origin",
|
|
2230
|
+
"fill",
|
|
2231
|
+
"stroke",
|
|
2232
|
+
"stroke-width",
|
|
2233
|
+
"object-fit",
|
|
2234
|
+
"object-position",
|
|
2235
|
+
"padding",
|
|
2236
|
+
"padding-inline",
|
|
2237
|
+
"padding-block",
|
|
2238
|
+
"padding-inline-start",
|
|
2239
|
+
"padding-inline-end",
|
|
2240
|
+
"padding-block-start",
|
|
2241
|
+
"padding-block-end",
|
|
2242
|
+
"padding-top",
|
|
2243
|
+
"padding-right",
|
|
2244
|
+
"padding-bottom",
|
|
2245
|
+
"padding-left",
|
|
2246
|
+
"text-align",
|
|
2247
|
+
"text-indent",
|
|
2248
|
+
"vertical-align",
|
|
2249
|
+
"font-family",
|
|
2250
|
+
"font-feature-settings",
|
|
2251
|
+
"font-size",
|
|
2252
|
+
"line-height",
|
|
2253
|
+
"font-weight",
|
|
2254
|
+
"letter-spacing",
|
|
2255
|
+
"text-wrap",
|
|
2256
|
+
"overflow-wrap",
|
|
2257
|
+
"word-break",
|
|
2258
|
+
"text-overflow",
|
|
2259
|
+
"hyphens",
|
|
2260
|
+
"white-space",
|
|
2261
|
+
"tab-size",
|
|
2262
|
+
"color",
|
|
2263
|
+
"text-transform",
|
|
2264
|
+
"font-style",
|
|
2265
|
+
"font-stretch",
|
|
2266
|
+
"font-variant-numeric",
|
|
2267
|
+
"text-decoration-line",
|
|
2268
|
+
"text-decoration-color",
|
|
2269
|
+
"text-decoration-style",
|
|
2270
|
+
"text-decoration-thickness",
|
|
2271
|
+
"text-underline-offset",
|
|
2272
|
+
"-webkit-font-smoothing",
|
|
2273
|
+
"placeholder-color",
|
|
2274
|
+
"caret-color",
|
|
2275
|
+
"accent-color",
|
|
2276
|
+
"color-scheme",
|
|
2277
|
+
"opacity",
|
|
2278
|
+
"background-blend-mode",
|
|
2279
|
+
"mix-blend-mode",
|
|
2280
|
+
"box-shadow",
|
|
2281
|
+
"--tw-shadow",
|
|
2282
|
+
"--tw-shadow-color",
|
|
2283
|
+
"--tw-ring-shadow",
|
|
2284
|
+
"--tw-ring-color",
|
|
2285
|
+
"--tw-inset-shadow",
|
|
2286
|
+
"--tw-inset-shadow-color",
|
|
2287
|
+
"--tw-inset-ring-shadow",
|
|
2288
|
+
"--tw-inset-ring-color",
|
|
2289
|
+
"--tw-ring-offset-width",
|
|
2290
|
+
"--tw-ring-offset-color",
|
|
2291
|
+
"outline",
|
|
2292
|
+
"outline-width",
|
|
2293
|
+
"outline-offset",
|
|
2294
|
+
"outline-color",
|
|
2295
|
+
"--tw-blur",
|
|
2296
|
+
"--tw-brightness",
|
|
2297
|
+
"--tw-contrast",
|
|
2298
|
+
"--tw-drop-shadow",
|
|
2299
|
+
"--tw-grayscale",
|
|
2300
|
+
"--tw-hue-rotate",
|
|
2301
|
+
"--tw-invert",
|
|
2302
|
+
"--tw-saturate",
|
|
2303
|
+
"--tw-sepia",
|
|
2304
|
+
"filter",
|
|
2305
|
+
"--tw-backdrop-blur",
|
|
2306
|
+
"--tw-backdrop-brightness",
|
|
2307
|
+
"--tw-backdrop-contrast",
|
|
2308
|
+
"--tw-backdrop-grayscale",
|
|
2309
|
+
"--tw-backdrop-hue-rotate",
|
|
2310
|
+
"--tw-backdrop-invert",
|
|
2311
|
+
"--tw-backdrop-opacity",
|
|
2312
|
+
"--tw-backdrop-saturate",
|
|
2313
|
+
"--tw-backdrop-sepia",
|
|
2314
|
+
"backdrop-filter",
|
|
2315
|
+
"transition-property",
|
|
2316
|
+
"transition-behavior",
|
|
2317
|
+
"transition-delay",
|
|
2318
|
+
"transition-duration",
|
|
2319
|
+
"transition-timing-function",
|
|
2320
|
+
"will-change",
|
|
2321
|
+
"contain",
|
|
2322
|
+
"content",
|
|
2323
|
+
"forced-color-adjust"
|
|
2324
|
+
];
|
|
2325
|
+
//#endregion
|
|
2326
|
+
//#region src/core/rule-order.ts
|
|
2327
|
+
/**
|
|
2328
|
+
* Tailwind-compatible cascade order for runtime-inserted rules (#254); shared by @barocss/server (#267).
|
|
2329
|
+
*
|
|
2330
|
+
* The runtime discovers classes in DOM order, so without sorting `lg:px-8`
|
|
2331
|
+
* seen before `sm:px-6` would land earlier and lose at >= 1024px. Each rule
|
|
2332
|
+
* gets a sort key derived from its leading `@media` / `@container` preludes:
|
|
2333
|
+
*
|
|
2334
|
+
* 0 base, negated media (`not-md:` → `@media not (…)`, as Tailwind 4.3.3 orders them, #352),
|
|
2335
|
+
* state media (hover), motion/contrast, unknown
|
|
2336
|
+
* 1 max-* breakpoints (larger width first)
|
|
2337
|
+
* 2 min-* breakpoints (smaller width first)
|
|
2338
|
+
* 3 @max-* container queries (larger width first)
|
|
2339
|
+
* 4 @min-* container queries (smaller width first)
|
|
2340
|
+
* 5 orientation, dark (prefers-color-scheme), print, forced-colors
|
|
2341
|
+
*
|
|
2342
|
+
* Nested at-rules (e.g. `sm:dark:`) contribute one key pair per level, so
|
|
2343
|
+
* `sm:` < `sm:dark:` < `md:`.
|
|
2344
|
+
*
|
|
2345
|
+
* #401: within one variant key, rules follow Tailwind 4's property order (the candidate sort of
|
|
2346
|
+
* Tailwind 4.3.3's `compile()`): compare the sorted TW property indices of each rule's declarations up
|
|
2347
|
+
* to the first difference (a rule that runs out of indices sorts last), then more declarations first,
|
|
2348
|
+
* then the class name (Tailwind's numeric-aware compare). Equal keys keep discovery order.
|
|
2349
|
+
*/
|
|
2350
|
+
var LEADING_AT = /^\s*@(media|container)\s+([^{]*)\{/;
|
|
2351
|
+
var LATE_MEDIA = /prefers-color-scheme|\bprint\b|forced-colors|orientation/;
|
|
2352
|
+
var MIN_W = /(?:min-width\s*:\s*|width\s*>=?\s*)([\d.]+)(px|rem|em)?/;
|
|
2353
|
+
var MAX_W = /(?:max-width\s*:\s*|width\s*<=?\s*)([\d.]+)(px|rem|em)?/;
|
|
2354
|
+
/** Separates the variant pairs (whose first slot is >= 0) from the property part of a key. */
|
|
2355
|
+
var PROPERTY_PART = -1;
|
|
2356
|
+
/** A rule that has run out of property indices sorts after every real index (TW: `?? Infinity`). */
|
|
2357
|
+
var NO_MORE = Number.MAX_SAFE_INTEGER;
|
|
2358
|
+
var PROPERTY_INDEX = new Map(TW_PROPERTY_ORDER.map((p, i) => [p, i]));
|
|
2359
|
+
var DECL = /(?:^|[{;])\s*(-{0,2}[a-zA-Z][\w-]*)\s*:[^;{}]*(?=[;}])/g;
|
|
2360
|
+
var AT_PRELUDE = /^\s*@[\w-]+[^{]*\{/;
|
|
2361
|
+
var CLASS = /\.((?:\\.|[\w-])+)/;
|
|
2362
|
+
function toPx(n, unit) {
|
|
2363
|
+
const v = parseFloat(n);
|
|
2364
|
+
return unit === "rem" || unit === "em" ? v * 16 : v;
|
|
2365
|
+
}
|
|
2366
|
+
function preludeKey(kind, prelude) {
|
|
2367
|
+
const container = kind === "container";
|
|
2368
|
+
if (!container && /^\s*not\b/i.test(prelude)) return [0, 0];
|
|
2369
|
+
const min = MIN_W.exec(prelude);
|
|
2370
|
+
if (min) return [container ? 4 : 2, toPx(min[1], min[2])];
|
|
2371
|
+
const max = MAX_W.exec(prelude);
|
|
2372
|
+
if (max) return [container ? 3 : 1, -toPx(max[1], max[2])];
|
|
2373
|
+
if (!container && LATE_MEDIA.test(prelude)) return [5, 0];
|
|
2374
|
+
return [0, 0];
|
|
2375
|
+
}
|
|
2376
|
+
/** The rule text after its leading at-rule preludes, up to its first `{` (the selector). */
|
|
2377
|
+
function ruleSelector(rule) {
|
|
2378
|
+
let rest = rule;
|
|
2379
|
+
let m;
|
|
2380
|
+
while (m = AT_PRELUDE.exec(rest)) rest = rest.slice(m[0].length);
|
|
2381
|
+
const end = rest.indexOf("{");
|
|
2382
|
+
return end === -1 ? "" : rest.slice(0, end);
|
|
2383
|
+
}
|
|
2384
|
+
/**
|
|
2385
|
+
* Tailwind's `--tw-sort` overrides (a utility sorts as one pseudo-property), recognised from BaroCSS's
|
|
2386
|
+
* output for the same utilities: space-x/y, divide-*, placeholder colour, gradient stops, container.
|
|
2387
|
+
* (TW's `size-*` override names no listed property, so Tailwind ignores it, and so does this.)
|
|
2388
|
+
*/
|
|
2389
|
+
function sortOverride(selector, props, candidate) {
|
|
2390
|
+
const first = props[0];
|
|
2391
|
+
if (first === "--tw-space-x-reverse") return "row-gap";
|
|
2392
|
+
if (first === "--tw-space-y-reverse") return "column-gap";
|
|
2393
|
+
if (first === "--tw-divide-x-reverse") return "divide-x-width";
|
|
2394
|
+
if (first === "--tw-divide-y-reverse") return "divide-y-width";
|
|
2395
|
+
if (selector.includes(":not(:last-child)")) {
|
|
2396
|
+
if (props.includes("border-color")) return "divide-color";
|
|
2397
|
+
if (props.includes("border-style")) return "divide-style";
|
|
2398
|
+
}
|
|
2399
|
+
if (selector.includes("::placeholder") && props.includes("color")) return "placeholder-color";
|
|
2400
|
+
for (const stop of [
|
|
2401
|
+
"from",
|
|
2402
|
+
"via",
|
|
2403
|
+
"to"
|
|
2404
|
+
]) if (props.includes(`--tw-gradient-${stop}`)) return `--tw-gradient-${stop}`;
|
|
2405
|
+
if (candidate.slice(candidate.lastIndexOf(":") + 1) === "container") return "--tw-container-component";
|
|
2406
|
+
return null;
|
|
2407
|
+
}
|
|
2408
|
+
/**
|
|
2409
|
+
* Tailwind's per-candidate property sort (#401): the sorted, de-duplicated TW property-order indices of
|
|
2410
|
+
* the rule's declarations (at any depth), and the declaration count. `--baro-*` vars count as `--tw-*`.
|
|
2411
|
+
*/
|
|
2412
|
+
/** @internal (#401) */ function rulePropertySort(rule, candidate = ruleCandidate(rule)) {
|
|
2413
|
+
const props = [];
|
|
2414
|
+
for (const d of rule.matchAll(DECL)) props.push(d[1].startsWith("--baro-") ? "--tw-" + d[1].slice(7) : d[1]);
|
|
2415
|
+
const override = sortOverride(ruleSelector(rule), props, candidate);
|
|
2416
|
+
const overrideIndex = override === null ? void 0 : PROPERTY_INDEX.get(override);
|
|
2417
|
+
if (overrideIndex !== void 0) return {
|
|
2418
|
+
order: [overrideIndex],
|
|
2419
|
+
count: props.length + 1
|
|
2420
|
+
};
|
|
2421
|
+
const set = /* @__PURE__ */ new Set();
|
|
2422
|
+
for (const p of props) {
|
|
2423
|
+
const i = PROPERTY_INDEX.get(p);
|
|
2424
|
+
if (i !== void 0) set.add(i);
|
|
2425
|
+
}
|
|
2426
|
+
return {
|
|
2427
|
+
order: Array.from(set).sort((a, b) => a - b),
|
|
2428
|
+
count: props.length
|
|
2429
|
+
};
|
|
2430
|
+
}
|
|
2431
|
+
/** The (unescaped) first class in the rule's selector, e.g. `sm:px-2`. */
|
|
2432
|
+
/** @internal (#401) */ function ruleCandidate(rule) {
|
|
2433
|
+
const c = CLASS.exec(ruleSelector(rule));
|
|
2434
|
+
return c ? c[1].replace(/\\(.)/g, "$1") : "";
|
|
2435
|
+
}
|
|
2436
|
+
/** Tailwind's candidate compare: runs of digits compare by value, other chars by code. */
|
|
2437
|
+
/** @internal (#401) */ function compareCandidates(a, b) {
|
|
2438
|
+
const n = Math.min(a.length, b.length);
|
|
2439
|
+
for (let i = 0; i < n; i++) {
|
|
2440
|
+
let x = a.charCodeAt(i);
|
|
2441
|
+
let y = b.charCodeAt(i);
|
|
2442
|
+
if (x >= 48 && x <= 57 && y >= 48 && y <= 57) {
|
|
2443
|
+
let ae = i + 1;
|
|
2444
|
+
let be = i + 1;
|
|
2445
|
+
for (x = a.charCodeAt(ae); x >= 48 && x <= 57;) x = a.charCodeAt(++ae);
|
|
2446
|
+
for (y = b.charCodeAt(be); y >= 48 && y <= 57;) y = b.charCodeAt(++be);
|
|
2447
|
+
const as = a.slice(i, ae);
|
|
2448
|
+
const bs = b.slice(i, be);
|
|
2449
|
+
const diff = Number(as) - Number(bs);
|
|
2450
|
+
if (diff) return diff;
|
|
2451
|
+
if (as < bs) return -1;
|
|
2452
|
+
if (as > bs) return 1;
|
|
2453
|
+
continue;
|
|
2454
|
+
}
|
|
2455
|
+
if (x !== y) return x - y;
|
|
2456
|
+
}
|
|
2457
|
+
return a.length - b.length;
|
|
2458
|
+
}
|
|
2459
|
+
/** The #254 variant part of the key (leading `@media` / `@container` preludes). */
|
|
2460
|
+
/** @internal (#401) */ function ruleVariantKey(rule) {
|
|
2461
|
+
const key = [];
|
|
2462
|
+
let rest = rule;
|
|
2463
|
+
let m;
|
|
2464
|
+
while (m = LEADING_AT.exec(rest)) {
|
|
2465
|
+
const [g, v] = preludeKey(m[1], m[2]);
|
|
2466
|
+
key.push(g, v);
|
|
2467
|
+
rest = rest.slice(m[0].length);
|
|
2468
|
+
}
|
|
2469
|
+
return key;
|
|
2470
|
+
}
|
|
2471
|
+
/**
|
|
2472
|
+
* Full sort key: the #254 variant pairs, then (#401) Tailwind's property sort and the class name.
|
|
2473
|
+
* `candidate` defaults to the rule's first class.
|
|
2474
|
+
*/
|
|
2475
|
+
function ruleSortKey(rule, candidate) {
|
|
2476
|
+
const name = candidate ?? ruleCandidate(rule);
|
|
2477
|
+
const { order, count } = rulePropertySort(rule, name);
|
|
2478
|
+
const key = ruleVariantKey(rule);
|
|
2479
|
+
key.push(PROPERTY_PART, ...order, NO_MORE, -count, name);
|
|
2480
|
+
return key;
|
|
2481
|
+
}
|
|
2482
|
+
function compareKeys(a, b) {
|
|
2483
|
+
const n = Math.min(a.length, b.length);
|
|
2484
|
+
for (let i = 0; i < n; i++) {
|
|
2485
|
+
const x = a[i];
|
|
2486
|
+
const y = b[i];
|
|
2487
|
+
if (x === y) continue;
|
|
2488
|
+
if (typeof x === "string" || typeof y === "string") {
|
|
2489
|
+
const d = compareCandidates(String(x), String(y));
|
|
2490
|
+
if (d) return d;
|
|
2491
|
+
continue;
|
|
2492
|
+
}
|
|
2493
|
+
return x - y;
|
|
2494
|
+
}
|
|
2495
|
+
return a.length - b.length;
|
|
2496
|
+
}
|
|
2497
|
+
/** Index after the last key <= `key` (stable upper bound) in sorted `keys`. */
|
|
2498
|
+
function upperBound(keys, key) {
|
|
2499
|
+
let lo = 0;
|
|
2500
|
+
let hi = keys.length;
|
|
2501
|
+
while (lo < hi) {
|
|
2502
|
+
const mid = lo + hi >> 1;
|
|
2503
|
+
if (compareKeys(keys[mid], key) <= 0) lo = mid + 1;
|
|
2504
|
+
else hi = mid;
|
|
2505
|
+
}
|
|
2506
|
+
return lo;
|
|
2507
|
+
}
|
|
2508
|
+
//#endregion
|
|
1567
2509
|
//#region src/core/engine.ts
|
|
1568
2510
|
var failureCache = /* @__PURE__ */ new Set();
|
|
1569
2511
|
/**
|
|
@@ -1762,6 +2704,10 @@ function parseClassToAst(fullClassName, ctx) {
|
|
|
1762
2704
|
let ast = [];
|
|
1763
2705
|
for (const utilReg of utilRegs) {
|
|
1764
2706
|
ast = utilReg.handler(value, ctx, utility, utilReg) || [];
|
|
2707
|
+
if (ast === REJECT_CLASS) {
|
|
2708
|
+
ast = [];
|
|
2709
|
+
break;
|
|
2710
|
+
}
|
|
1765
2711
|
if (ast.length > 0) break;
|
|
1766
2712
|
}
|
|
1767
2713
|
const wrappers = [];
|
|
@@ -1886,7 +2832,7 @@ var CLASS_SEPARATOR = /[ \t\n\f\r]+/;
|
|
|
1886
2832
|
function generateCss(classList, ctx, opts) {
|
|
1887
2833
|
const seen = /* @__PURE__ */ new Set();
|
|
1888
2834
|
const allAtRootNodes = [];
|
|
1889
|
-
const
|
|
2835
|
+
const generated = classList.split(CLASS_SEPARATOR).filter((cls) => {
|
|
1890
2836
|
if (!cls) return false;
|
|
1891
2837
|
if (opts?.dedup) {
|
|
1892
2838
|
if (seen.has(cls)) return false;
|
|
@@ -1895,12 +2841,31 @@ function generateCss(classList, ctx, opts) {
|
|
|
1895
2841
|
return true;
|
|
1896
2842
|
}).map((cls) => {
|
|
1897
2843
|
try {
|
|
1898
|
-
return
|
|
2844
|
+
return {
|
|
2845
|
+
cls,
|
|
2846
|
+
css: generateOne(cls)
|
|
2847
|
+
};
|
|
1899
2848
|
} catch (err) {
|
|
1900
2849
|
debugWarn("[generateCss] class generation failed:", cls, err);
|
|
1901
|
-
return
|
|
2850
|
+
return {
|
|
2851
|
+
cls,
|
|
2852
|
+
css: ""
|
|
2853
|
+
};
|
|
1902
2854
|
}
|
|
1903
|
-
})
|
|
2855
|
+
});
|
|
2856
|
+
const slots = generated.flatMap((g, i) => g.css ? [i] : []);
|
|
2857
|
+
const sorted = slots.map((i) => ({
|
|
2858
|
+
i,
|
|
2859
|
+
css: generated[i].css,
|
|
2860
|
+
key: ruleSortKey(generated[i].css, generated[i].cls)
|
|
2861
|
+
})).sort((a, b) => compareKeys(a.key, b.key) || a.i - b.i);
|
|
2862
|
+
slots.forEach((slot, j) => {
|
|
2863
|
+
generated[slot] = {
|
|
2864
|
+
cls: generated[slot].cls,
|
|
2865
|
+
css: sorted[j].css
|
|
2866
|
+
};
|
|
2867
|
+
});
|
|
2868
|
+
const results = generated.map((g) => g.css).join(opts?.minify ? "" : "\n");
|
|
1904
2869
|
function generateOne(cls) {
|
|
1905
2870
|
const ast = parseClassToAst(cls, ctx);
|
|
1906
2871
|
const parsedResult = (getContextState(ctx)?.parseResultCache || parseResultCache).get(cls);
|
|
@@ -3049,500 +4014,232 @@ function configGetter(config, ...path) {
|
|
|
3049
4014
|
else keys = path;
|
|
3050
4015
|
return keys.reduce((acc, key) => acc ? acc[key] : void 0, config);
|
|
3051
4016
|
}
|
|
3052
|
-
function hasPreset(themeObj, category, preset) {
|
|
3053
|
-
return themeObj[category]?.includes?.(preset);
|
|
3054
|
-
}
|
|
3055
|
-
function resolveTheme(config) {
|
|
3056
|
-
let theme = {};
|
|
3057
|
-
if (config.presets) {
|
|
3058
|
-
for (const preset of config.presets) if (preset.theme) theme = deepMerge(theme, preset.theme);
|
|
3059
|
-
}
|
|
3060
|
-
if (config.theme) {
|
|
3061
|
-
const { extend, ...overrideTheme } = config.theme;
|
|
3062
|
-
theme = deepMerge(theme, overrideTheme);
|
|
3063
|
-
if (extend) theme = deepMerge(theme, extend);
|
|
3064
|
-
}
|
|
3065
|
-
return theme;
|
|
3066
|
-
}
|
|
3067
|
-
function themeToCssVars(theme) {
|
|
3068
|
-
return toCssVarsBlock(themeToCssVarsAll(theme));
|
|
3069
|
-
}
|
|
3070
|
-
function createContext(configObj) {
|
|
3071
|
-
if (configObj.debug !== void 0) setDebug(!!configObj.debug);
|
|
3072
|
-
const configWithDefaults = {
|
|
3073
|
-
presets: [{ theme: defaultTheme }, ...configObj.presets || []],
|
|
3074
|
-
...configObj
|
|
3075
|
-
};
|
|
3076
|
-
const themeObj = resolveTheme(configWithDefaults);
|
|
3077
|
-
const ctx = {
|
|
3078
|
-
hasPreset: (category, preset) => {
|
|
3079
|
-
return hasPreset(themeObj, category, preset);
|
|
3080
|
-
},
|
|
3081
|
-
theme: (...args) => {
|
|
3082
|
-
return themeGetter(themeObj, ...args);
|
|
3083
|
-
},
|
|
3084
|
-
config: (...args) => {
|
|
3085
|
-
return configGetter(configWithDefaults, ...args);
|
|
3086
|
-
},
|
|
3087
|
-
themeToCssVars: () => themeToCssVars(themeObj),
|
|
3088
|
-
extendTheme: (category, values) => {
|
|
3089
|
-
if (typeof values === "function") {
|
|
3090
|
-
const result = values(ctx.theme);
|
|
3091
|
-
if (result && typeof result === "object") {
|
|
3092
|
-
const existingValues = themeObj[category] || {};
|
|
3093
|
-
themeObj[category] = {
|
|
3094
|
-
...existingValues,
|
|
3095
|
-
...result
|
|
3096
|
-
};
|
|
3097
|
-
}
|
|
3098
|
-
} else if (typeof values === "object" && values !== null && !Array.isArray(values)) {
|
|
3099
|
-
const existingValues = themeObj[category] || {};
|
|
3100
|
-
themeObj[category] = {
|
|
3101
|
-
...existingValues,
|
|
3102
|
-
...values
|
|
3103
|
-
};
|
|
3104
|
-
}
|
|
3105
|
-
clearContextCaches(ctx);
|
|
3106
|
-
},
|
|
3107
|
-
getPreflightCSS: (level = true) => {
|
|
3108
|
-
return getPreflightCSS(level);
|
|
3109
|
-
}
|
|
3110
|
-
};
|
|
3111
|
-
initializeContextState(ctx, getUtility(), getModifier());
|
|
3112
|
-
registerCustomUtilities(ctx, configObj.utilities);
|
|
3113
|
-
return ctx;
|
|
3114
|
-
}
|
|
3115
|
-
//#endregion
|
|
3116
|
-
//#region src/core/jsonToAst.ts
|
|
3117
|
-
/**
|
|
3118
|
-
* Converts a single BaroJsonInput object into an AST tree.
|
|
3119
|
-
* Bypasses string parsing and directly invokes utility/modifier handlers.
|
|
3120
|
-
*
|
|
3121
|
-
* @param input BaroJsonInput object
|
|
3122
|
-
* @param ctx Context
|
|
3123
|
-
* @returns AstNode[]
|
|
3124
|
-
*/
|
|
3125
|
-
function jsonToAst(input, ctx) {
|
|
3126
|
-
if ((input.variants || []).some((v) => typeof v === "string" ? !isSafeVariantToken(v) : !isSafeVariantValue(v.name || "") || !isSafeVariantValue(v.value || "") || hasCommentToken(v.name || "") || hasCommentToken(v.value || ""))) return [];
|
|
3127
|
-
let utilReg = getUtility(ctx).find((u) => u.name === input.utility.name);
|
|
3128
|
-
if (input.utility.value && !input.utility.arbitrary && !input.utility.customProperty) {
|
|
3129
|
-
const fullName = `${input.utility.name}-${input.utility.value}`;
|
|
3130
|
-
const exactMatch = getUtility(ctx).find((u) => u.name === fullName);
|
|
3131
|
-
if (exactMatch) utilReg = exactMatch;
|
|
3132
|
-
}
|
|
3133
|
-
if (!utilReg) {
|
|
3134
|
-
debugWarn(`[jsonToAst] Unknown utility: "${input.utility.name}"`);
|
|
3135
|
-
return [];
|
|
3136
|
-
}
|
|
3137
|
-
const parsedUtility = {
|
|
3138
|
-
prefix: input.utility.name,
|
|
3139
|
-
value: input.utility.value,
|
|
3140
|
-
arbitrary: input.utility.arbitrary,
|
|
3141
|
-
negative: input.utility.negative,
|
|
3142
|
-
opacity: input.utility.opacity,
|
|
3143
|
-
important: input.utility.important,
|
|
3144
|
-
customProperty: input.utility.customProperty,
|
|
3145
|
-
category: utilReg.category,
|
|
3146
|
-
priority: utilReg.priority
|
|
3147
|
-
};
|
|
3148
|
-
let value = input.utility.value;
|
|
3149
|
-
if (input.utility.negative && value) value = "-" + value;
|
|
3150
|
-
let ast = utilReg.handler(value || "", ctx, parsedUtility, utilReg) || [];
|
|
3151
|
-
if (input.variants && input.variants.length > 0) {
|
|
3152
|
-
const wrappers = [];
|
|
3153
|
-
const selector = "&";
|
|
3154
|
-
for (let i = input.variants.length - 1; i >= 0; i--) {
|
|
3155
|
-
const variantInput = input.variants[i];
|
|
3156
|
-
const variantName = typeof variantInput === "string" ? variantInput : variantInput.name;
|
|
3157
|
-
const variantValue = typeof variantInput === "string" ? void 0 : variantInput.value;
|
|
3158
|
-
const variantArbitrary = typeof variantInput === "string" ? false : variantInput.arbitrary;
|
|
3159
|
-
const parsedModifier = {
|
|
3160
|
-
type: variantName,
|
|
3161
|
-
value: variantValue,
|
|
3162
|
-
arbitrary: variantArbitrary
|
|
3163
|
-
};
|
|
3164
|
-
let matchKey = variantName;
|
|
3165
|
-
if (variantArbitrary && variantValue) {
|
|
3166
|
-
if (variantName) {
|
|
3167
|
-
matchKey = `${variantName}-[${variantValue}]`;
|
|
3168
|
-
parsedModifier.type = matchKey;
|
|
3169
|
-
} else {
|
|
3170
|
-
matchKey = `[${variantValue}]`;
|
|
3171
|
-
parsedModifier.type = matchKey;
|
|
3172
|
-
}
|
|
3173
|
-
} else if (variantValue) {
|
|
3174
|
-
matchKey = `${variantName}-[${variantValue}]`;
|
|
3175
|
-
parsedModifier.type = matchKey;
|
|
3176
|
-
}
|
|
3177
|
-
const plugin = getModifier(ctx).find((p) => p.match(matchKey, ctx));
|
|
3178
|
-
if (!plugin) {
|
|
3179
|
-
debugWarn(`[jsonToAst] Unknown variant: "${matchKey}"`);
|
|
3180
|
-
continue;
|
|
3181
|
-
}
|
|
3182
|
-
if (plugin.astHandler) ast = plugin.astHandler(ast, parsedModifier, ctx, [], i);
|
|
3183
|
-
if (plugin.modifySelector) {
|
|
3184
|
-
const result = plugin.modifySelector({
|
|
3185
|
-
selector,
|
|
3186
|
-
fullClassName: "JSON_GENERATED",
|
|
3187
|
-
mod: parsedModifier,
|
|
3188
|
-
context: ctx,
|
|
3189
|
-
variantChain: [],
|
|
3190
|
-
index: i
|
|
3191
|
-
});
|
|
3192
|
-
if (result == null) continue;
|
|
3193
|
-
if (plugin.wrap && (result === "&" || typeof result === "object" && !Array.isArray(result) && result.selector === "&" || Array.isArray(result) && result.length === 1 && result[0].selector === "&")) {} else if (typeof result === "string" && result.includes("&")) wrappers.push({
|
|
3194
|
-
type: "rule",
|
|
3195
|
-
selector: result
|
|
3196
|
-
});
|
|
3197
|
-
else if (typeof result === "object" && !Array.isArray(result) && result.selector) {
|
|
3198
|
-
const r = result;
|
|
3199
|
-
const wrappingType = r.wrappingType || "rule";
|
|
3200
|
-
wrappers.push({
|
|
3201
|
-
type: wrappingType,
|
|
3202
|
-
selector: r.selector,
|
|
3203
|
-
flatten: r.flatten,
|
|
3204
|
-
source: r.source
|
|
3205
|
-
});
|
|
3206
|
-
} else if (Array.isArray(result)) wrappers.push({
|
|
3207
|
-
type: "wrap",
|
|
3208
|
-
items: result.map((r) => ({
|
|
3209
|
-
type: r.wrappingType || "rule",
|
|
3210
|
-
selector: r.selector,
|
|
3211
|
-
source: r.source,
|
|
3212
|
-
nodes: []
|
|
3213
|
-
}))
|
|
3214
|
-
});
|
|
3215
|
-
}
|
|
3216
|
-
if (plugin.wrap) wrappers.push({
|
|
3217
|
-
type: "wrap",
|
|
3218
|
-
items: plugin.wrap(parsedModifier, ctx)
|
|
3219
|
-
});
|
|
3220
|
-
}
|
|
3221
|
-
for (let i = 0; i < wrappers.length; i++) {
|
|
3222
|
-
const wrap = wrappers[i];
|
|
3223
|
-
if (wrap.type === "wrap") ast = wrap.items.map((item) => item.type === "rule" || item.type === "style-rule" || item.type === "at-rule" || item.type === "at-root" ? {
|
|
3224
|
-
...item,
|
|
3225
|
-
nodes: [...item.nodes || [], ...ast]
|
|
3226
|
-
} : item);
|
|
3227
|
-
else if (wrap.type === "style-rule") ast = [{
|
|
3228
|
-
type: "style-rule",
|
|
3229
|
-
selector: wrap.selector,
|
|
3230
|
-
source: wrap.source,
|
|
3231
|
-
nodes: Array.isArray(ast) ? ast : [ast]
|
|
3232
|
-
}];
|
|
3233
|
-
else if (wrap.type === "at-rule") ast = [{
|
|
3234
|
-
type: "at-rule",
|
|
3235
|
-
name: wrap.name || "media",
|
|
3236
|
-
params: wrap.params,
|
|
3237
|
-
source: wrap.source,
|
|
3238
|
-
nodes: Array.isArray(ast) ? ast : [ast]
|
|
3239
|
-
}];
|
|
3240
|
-
else if (wrap.type === "rule") ast = [{
|
|
3241
|
-
type: "rule",
|
|
3242
|
-
selector: wrap.selector,
|
|
3243
|
-
source: wrap.source,
|
|
3244
|
-
nodes: Array.isArray(ast) ? ast : [ast]
|
|
3245
|
-
}];
|
|
3246
|
-
}
|
|
3247
|
-
}
|
|
3248
|
-
return applyVarPrefix(ast, ctx);
|
|
3249
|
-
}
|
|
3250
|
-
/**
|
|
3251
|
-
* Generates CSS from a list of BaroJsonInput objects.
|
|
3252
|
-
*
|
|
3253
|
-
* @param inputs Array of BaroJsonInput
|
|
3254
|
-
* @param ctx Context
|
|
3255
|
-
* @param opts Options (minify, etc.)
|
|
3256
|
-
* @returns CSS string
|
|
3257
|
-
*/
|
|
3258
|
-
function generateCssFromJson(inputs, ctx, opts) {
|
|
3259
|
-
const allAtRootNodes = [];
|
|
3260
|
-
const cssList = [];
|
|
3261
|
-
inputs.forEach((input) => {
|
|
3262
|
-
const cleanAst = optimizeAst(jsonToAst(input, ctx));
|
|
3263
|
-
cleanAst.forEach((node) => {
|
|
3264
|
-
if (node.type === "at-root") allAtRootNodes.push(...node.nodes);
|
|
3265
|
-
});
|
|
3266
|
-
let reconstructedName = input.utility.name;
|
|
3267
|
-
if (input.utility.value) reconstructedName += `-${input.utility.value}`;
|
|
3268
|
-
if (input.utility.arbitrary) reconstructedName = `${input.utility.name}-[${input.utility.value}]`;
|
|
3269
|
-
if (input.variants) reconstructedName = `${input.variants.map((v) => typeof v === "string" ? v : v.name).join(":")}:${reconstructedName}`;
|
|
3270
|
-
const css = astToCss(cleanAst, cleanAst.some((node) => node.type === "style-rule") ? void 0 : `.${reconstructedName.replace(/[^a-zA-Z0-9-_]/g, "\\$&")}`, {
|
|
3271
|
-
minify: opts?.minify,
|
|
3272
|
-
important: input.utility.important ?? false
|
|
3273
|
-
});
|
|
3274
|
-
if (css) cssList.push(css);
|
|
3275
|
-
});
|
|
3276
|
-
const rootCss = rootToCss(allAtRootNodes);
|
|
3277
|
-
return `${rootCss ? `:root,:host {${rootCss}}` : ""}${cssList.join(opts?.minify ? "" : "\n")}`;
|
|
3278
|
-
}
|
|
3279
|
-
//#endregion
|
|
3280
|
-
//#region src/core/utils.ts
|
|
3281
|
-
/**
|
|
3282
|
-
* Parses a fraction string (e.g., '1/2') and returns a percentage string (e.g., '50%'), or null if not a valid fraction.
|
|
3283
|
-
*/
|
|
3284
|
-
function parseFraction(input) {
|
|
3285
|
-
if (input.includes("/")) {
|
|
3286
|
-
const [num, denom] = input.split("/").map(Number);
|
|
3287
|
-
if (!isNaN(num) && !isNaN(denom) && denom !== 0) return `${num / denom * 100}%`;
|
|
3288
|
-
}
|
|
3289
|
-
return null;
|
|
3290
|
-
}
|
|
3291
|
-
/**
|
|
3292
|
-
* Returns the input if it is a valid non-negative integer string, else null.
|
|
3293
|
-
*
|
|
3294
|
-
* @example
|
|
3295
|
-
* parseNumber("10") // "10"
|
|
3296
|
-
* parseNumber("-10") // "-10"
|
|
3297
|
-
* parseNumber("10.5") // "10.5"
|
|
3298
|
-
*/
|
|
3299
|
-
function parseNumber(input) {
|
|
3300
|
-
return /^-?\d+(?:\.\d+)?$/.test(input) ? input : null;
|
|
3301
|
-
}
|
|
3302
|
-
/**
|
|
3303
|
-
* Returns the input if it is a valid length string, else null.
|
|
3304
|
-
*/
|
|
3305
|
-
function parseLength(input) {
|
|
3306
|
-
return /^\d+(px|em|rem|vh|vw|vmin|vmax|%|in|cm|mm|pt|pc|ex|ch|fr)$/.test(input) ? input : null;
|
|
3307
|
-
}
|
|
3308
|
-
/**
|
|
3309
|
-
* Unified parser for fraction or number, with options for percent or repeat syntax.
|
|
3310
|
-
* - percent: if true, returns percentage for fraction (e.g., '1/2' -> '50%')
|
|
3311
|
-
* - repeat: if true, returns repeat() for number (e.g., '3' -> 'repeat(3, minmax(0, 1fr))')
|
|
3312
|
-
*/
|
|
3313
|
-
function parseFractionOrNumber(value, opts = {}) {
|
|
3314
|
-
if (/^\d+$/.test(value)) {
|
|
3315
|
-
if (opts.repeat) return `repeat(${value}, minmax(0, 1fr))`;
|
|
3316
|
-
return value;
|
|
4017
|
+
function hasPreset(themeObj, category, preset) {
|
|
4018
|
+
return themeObj[category]?.includes?.(preset);
|
|
4019
|
+
}
|
|
4020
|
+
function resolveTheme(config) {
|
|
4021
|
+
let theme = {};
|
|
4022
|
+
if (config.presets) {
|
|
4023
|
+
for (const preset of config.presets) if (preset.theme) theme = deepMerge(theme, preset.theme);
|
|
3317
4024
|
}
|
|
3318
|
-
if (
|
|
3319
|
-
const
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
if (opts.percent) return `${result * 100}%`;
|
|
3323
|
-
return result.toString();
|
|
3324
|
-
}
|
|
4025
|
+
if (config.theme) {
|
|
4026
|
+
const { extend, ...overrideTheme } = config.theme;
|
|
4027
|
+
theme = deepMerge(theme, overrideTheme);
|
|
4028
|
+
if (extend) theme = deepMerge(theme, extend);
|
|
3325
4029
|
}
|
|
3326
|
-
return
|
|
4030
|
+
return theme;
|
|
3327
4031
|
}
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
"antiquewhite",
|
|
3331
|
-
"aqua",
|
|
3332
|
-
"aquamarine",
|
|
3333
|
-
"azure",
|
|
3334
|
-
"beige",
|
|
3335
|
-
"bisque",
|
|
3336
|
-
"black",
|
|
3337
|
-
"blanchedalmond",
|
|
3338
|
-
"blue",
|
|
3339
|
-
"blueviolet",
|
|
3340
|
-
"brown",
|
|
3341
|
-
"burlywood",
|
|
3342
|
-
"cadetblue",
|
|
3343
|
-
"chartreuse",
|
|
3344
|
-
"chocolate",
|
|
3345
|
-
"coral",
|
|
3346
|
-
"cornflowerblue",
|
|
3347
|
-
"cornsilk",
|
|
3348
|
-
"crimson",
|
|
3349
|
-
"cyan",
|
|
3350
|
-
"darkblue",
|
|
3351
|
-
"darkcyan",
|
|
3352
|
-
"darkgoldenrod",
|
|
3353
|
-
"darkgray",
|
|
3354
|
-
"darkgreen",
|
|
3355
|
-
"darkgrey",
|
|
3356
|
-
"darkkhaki",
|
|
3357
|
-
"darkmagenta",
|
|
3358
|
-
"darkolivegreen",
|
|
3359
|
-
"darkorange",
|
|
3360
|
-
"darkorchid",
|
|
3361
|
-
"darkred",
|
|
3362
|
-
"darksalmon",
|
|
3363
|
-
"darkseagreen",
|
|
3364
|
-
"darkslateblue",
|
|
3365
|
-
"darkslategray",
|
|
3366
|
-
"darkslategrey",
|
|
3367
|
-
"darkturquoise",
|
|
3368
|
-
"darkviolet",
|
|
3369
|
-
"deeppink",
|
|
3370
|
-
"deepskyblue",
|
|
3371
|
-
"dimgray",
|
|
3372
|
-
"dimgrey",
|
|
3373
|
-
"dodgerblue",
|
|
3374
|
-
"firebrick",
|
|
3375
|
-
"floralwhite",
|
|
3376
|
-
"forestgreen",
|
|
3377
|
-
"fuchsia",
|
|
3378
|
-
"gainsboro",
|
|
3379
|
-
"ghostwhite",
|
|
3380
|
-
"gold",
|
|
3381
|
-
"goldenrod",
|
|
3382
|
-
"gray",
|
|
3383
|
-
"grey",
|
|
3384
|
-
"green",
|
|
3385
|
-
"greenyellow",
|
|
3386
|
-
"honeydew",
|
|
3387
|
-
"hotpink",
|
|
3388
|
-
"indianred",
|
|
3389
|
-
"indigo",
|
|
3390
|
-
"ivory",
|
|
3391
|
-
"khaki",
|
|
3392
|
-
"lavender",
|
|
3393
|
-
"lavenderblush",
|
|
3394
|
-
"lawngreen",
|
|
3395
|
-
"lemonchiffon",
|
|
3396
|
-
"lightblue",
|
|
3397
|
-
"lightcoral",
|
|
3398
|
-
"lightcyan",
|
|
3399
|
-
"lightgoldenrodyellow",
|
|
3400
|
-
"lightgray",
|
|
3401
|
-
"lightgreen",
|
|
3402
|
-
"lightgrey",
|
|
3403
|
-
"lightpink",
|
|
3404
|
-
"lightsalmon",
|
|
3405
|
-
"lightseagreen",
|
|
3406
|
-
"lightskyblue",
|
|
3407
|
-
"lightslategray",
|
|
3408
|
-
"lightslategrey",
|
|
3409
|
-
"lightsteelblue",
|
|
3410
|
-
"lightyellow",
|
|
3411
|
-
"lime",
|
|
3412
|
-
"limegreen",
|
|
3413
|
-
"linen",
|
|
3414
|
-
"magenta",
|
|
3415
|
-
"maroon",
|
|
3416
|
-
"mediumaquamarine",
|
|
3417
|
-
"mediumblue",
|
|
3418
|
-
"mediumorchid",
|
|
3419
|
-
"mediumpurple",
|
|
3420
|
-
"mediumseagreen",
|
|
3421
|
-
"mediumslateblue",
|
|
3422
|
-
"mediumspringgreen",
|
|
3423
|
-
"mediumturquoise",
|
|
3424
|
-
"mediumvioletred",
|
|
3425
|
-
"midnightblue",
|
|
3426
|
-
"mintcream",
|
|
3427
|
-
"mistyrose",
|
|
3428
|
-
"moccasin",
|
|
3429
|
-
"navajowhite",
|
|
3430
|
-
"navy",
|
|
3431
|
-
"oldlace",
|
|
3432
|
-
"olive",
|
|
3433
|
-
"olivedrab",
|
|
3434
|
-
"orange",
|
|
3435
|
-
"orangered",
|
|
3436
|
-
"orchid",
|
|
3437
|
-
"palegoldenrod",
|
|
3438
|
-
"palegreen",
|
|
3439
|
-
"paleturquoise",
|
|
3440
|
-
"palevioletred",
|
|
3441
|
-
"papayawhip",
|
|
3442
|
-
"peachpuff",
|
|
3443
|
-
"peru",
|
|
3444
|
-
"pink",
|
|
3445
|
-
"plum",
|
|
3446
|
-
"powderblue",
|
|
3447
|
-
"purple",
|
|
3448
|
-
"red",
|
|
3449
|
-
"rosybrown",
|
|
3450
|
-
"royalblue",
|
|
3451
|
-
"saddlebrown",
|
|
3452
|
-
"salmon",
|
|
3453
|
-
"sandybrown",
|
|
3454
|
-
"seagreen",
|
|
3455
|
-
"seashell",
|
|
3456
|
-
"sienna",
|
|
3457
|
-
"silver",
|
|
3458
|
-
"skyblue",
|
|
3459
|
-
"slateblue",
|
|
3460
|
-
"slategray",
|
|
3461
|
-
"slategrey",
|
|
3462
|
-
"snow",
|
|
3463
|
-
"springgreen",
|
|
3464
|
-
"steelblue",
|
|
3465
|
-
"tan",
|
|
3466
|
-
"teal",
|
|
3467
|
-
"thistle",
|
|
3468
|
-
"tomato",
|
|
3469
|
-
"turquoise",
|
|
3470
|
-
"violet",
|
|
3471
|
-
"wheat",
|
|
3472
|
-
"white",
|
|
3473
|
-
"whitesmoke",
|
|
3474
|
-
"yellow",
|
|
3475
|
-
"yellowgreen"
|
|
3476
|
-
]);
|
|
3477
|
-
/**
|
|
3478
|
-
* Returns the input if it is a valid color string, else null.
|
|
3479
|
-
*
|
|
3480
|
-
* #rgb, #rgba, #rrggbb, #rrggbbaa, rgb(r, g, b), rgb(r, g, b, a), hsl(h, s, l), hsl(h, s, l, a), hwb(h, w, b), hwb(h, w, b, a), lab(l, a, b), lab(l, a, b, a), lch(l, c, h), lch(l, c, h, a), oklab(l, a, b), oklab(l, a, b, a), oklch(l, c, h), oklch(l, c, h, a), color-mix(in oklab, var(--color-blue-500) 60%, transparent)
|
|
3481
|
-
*/
|
|
3482
|
-
function parseColor(input) {
|
|
3483
|
-
if (CSS_COLOR_NAMES.has(input.toLowerCase())) return input;
|
|
3484
|
-
if (input.startsWith("color:var(")) return input.slice(6);
|
|
3485
|
-
if (input.startsWith("color:")) return parseColor(input.slice(6));
|
|
3486
|
-
if (input.startsWith("#") && input.length === 4) return `#${input.slice(1)}`;
|
|
3487
|
-
if (input.startsWith("#") && input.length === 5) return `#${input.slice(1)}`;
|
|
3488
|
-
if (input.startsWith("#") && input.length === 7) return `#${input.slice(1)}`;
|
|
3489
|
-
if (input.startsWith("#") && input.length === 9) return `#${input.slice(1)}`;
|
|
3490
|
-
if (input.startsWith("rgb(")) return input.slice(4, -1);
|
|
3491
|
-
if (input.startsWith("rgba(")) return input.slice(5, -1);
|
|
3492
|
-
if (input.startsWith("hsl(")) return input.slice(4, -1);
|
|
3493
|
-
if (input.startsWith("hsla(")) return input.slice(5, -1);
|
|
3494
|
-
if (input.startsWith("hwb(")) return input.slice(4, -1);
|
|
3495
|
-
if (input.startsWith("lab(")) return input.slice(4, -1);
|
|
3496
|
-
if (input.startsWith("lch(")) return input.slice(4, -1);
|
|
3497
|
-
if (input.startsWith("oklab(")) return input.slice(5, -1);
|
|
3498
|
-
if (input.startsWith("oklch(")) return input.slice(6, -1);
|
|
3499
|
-
if (input.startsWith("color-mix(")) return input.slice(9, -1);
|
|
3500
|
-
return null;
|
|
4032
|
+
function themeToCssVars(theme) {
|
|
4033
|
+
return toCssVarsBlock(themeToCssVarsAll(theme));
|
|
3501
4034
|
}
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
4035
|
+
function createContext(configObj) {
|
|
4036
|
+
if (configObj.debug !== void 0) setDebug(!!configObj.debug);
|
|
4037
|
+
const configWithDefaults = {
|
|
4038
|
+
presets: [{ theme: defaultTheme }, ...configObj.presets || []],
|
|
4039
|
+
...configObj
|
|
4040
|
+
};
|
|
4041
|
+
const themeObj = resolveTheme(configWithDefaults);
|
|
4042
|
+
const ctx = {
|
|
4043
|
+
hasPreset: (category, preset) => {
|
|
4044
|
+
return hasPreset(themeObj, category, preset);
|
|
4045
|
+
},
|
|
4046
|
+
theme: (...args) => {
|
|
4047
|
+
return themeGetter(themeObj, ...args);
|
|
4048
|
+
},
|
|
4049
|
+
config: (...args) => {
|
|
4050
|
+
return configGetter(configWithDefaults, ...args);
|
|
4051
|
+
},
|
|
4052
|
+
themeToCssVars: () => themeToCssVars(themeObj),
|
|
4053
|
+
extendTheme: (category, values) => {
|
|
4054
|
+
if (typeof values === "function") {
|
|
4055
|
+
const result = values(ctx.theme);
|
|
4056
|
+
if (result && typeof result === "object") {
|
|
4057
|
+
const existingValues = themeObj[category] || {};
|
|
4058
|
+
themeObj[category] = {
|
|
4059
|
+
...existingValues,
|
|
4060
|
+
...result
|
|
4061
|
+
};
|
|
4062
|
+
}
|
|
4063
|
+
} else if (typeof values === "object" && values !== null && !Array.isArray(values)) {
|
|
4064
|
+
const existingValues = themeObj[category] || {};
|
|
4065
|
+
themeObj[category] = {
|
|
4066
|
+
...existingValues,
|
|
4067
|
+
...values
|
|
4068
|
+
};
|
|
4069
|
+
}
|
|
4070
|
+
clearContextCaches(ctx);
|
|
4071
|
+
},
|
|
4072
|
+
getPreflightCSS: (level = true) => {
|
|
4073
|
+
return getPreflightCSS(level);
|
|
4074
|
+
}
|
|
4075
|
+
};
|
|
4076
|
+
initializeContextState(ctx, getUtility(), getModifier());
|
|
4077
|
+
registerCustomUtilities(ctx, configObj.utilities);
|
|
4078
|
+
return ctx;
|
|
4079
|
+
}
|
|
4080
|
+
//#endregion
|
|
4081
|
+
//#region src/core/jsonToAst.ts
|
|
3507
4082
|
/**
|
|
3508
|
-
*
|
|
3509
|
-
*
|
|
4083
|
+
* Converts a single BaroJsonInput object into an AST tree.
|
|
4084
|
+
* Bypasses string parsing and directly invokes utility/modifier handlers.
|
|
4085
|
+
*
|
|
4086
|
+
* @param input BaroJsonInput object
|
|
4087
|
+
* @param ctx Context
|
|
4088
|
+
* @returns AstNode[]
|
|
3510
4089
|
*/
|
|
3511
|
-
function
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
if (!
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
4090
|
+
function jsonToAst(input, ctx) {
|
|
4091
|
+
if ((input.variants || []).some((v) => typeof v === "string" ? !isSafeVariantToken(v) : !isSafeVariantValue(v.name || "") || !isSafeVariantValue(v.value || "") || hasCommentToken(v.name || "") || hasCommentToken(v.value || ""))) return [];
|
|
4092
|
+
let utilReg = getUtility(ctx).find((u) => u.name === input.utility.name);
|
|
4093
|
+
if (input.utility.value && !input.utility.arbitrary && !input.utility.customProperty) {
|
|
4094
|
+
const fullName = `${input.utility.name}-${input.utility.value}`;
|
|
4095
|
+
const exactMatch = getUtility(ctx).find((u) => u.name === fullName);
|
|
4096
|
+
if (exactMatch) utilReg = exactMatch;
|
|
4097
|
+
}
|
|
4098
|
+
if (!utilReg) {
|
|
4099
|
+
debugWarn(`[jsonToAst] Unknown utility: "${input.utility.name}"`);
|
|
4100
|
+
return [];
|
|
4101
|
+
}
|
|
4102
|
+
const parsedUtility = {
|
|
4103
|
+
prefix: input.utility.name,
|
|
4104
|
+
value: input.utility.value,
|
|
4105
|
+
arbitrary: input.utility.arbitrary,
|
|
4106
|
+
negative: input.utility.negative,
|
|
4107
|
+
opacity: input.utility.opacity,
|
|
4108
|
+
important: input.utility.important,
|
|
4109
|
+
customProperty: input.utility.customProperty,
|
|
4110
|
+
category: utilReg.category,
|
|
4111
|
+
priority: utilReg.priority
|
|
4112
|
+
};
|
|
4113
|
+
let value = input.utility.value;
|
|
4114
|
+
if (input.utility.negative && value) value = "-" + value;
|
|
4115
|
+
let ast = utilReg.handler(value || "", ctx, parsedUtility, utilReg) || [];
|
|
4116
|
+
if (input.variants && input.variants.length > 0) {
|
|
4117
|
+
const wrappers = [];
|
|
4118
|
+
const selector = "&";
|
|
4119
|
+
for (let i = input.variants.length - 1; i >= 0; i--) {
|
|
4120
|
+
const variantInput = input.variants[i];
|
|
4121
|
+
const variantName = typeof variantInput === "string" ? variantInput : variantInput.name;
|
|
4122
|
+
const variantValue = typeof variantInput === "string" ? void 0 : variantInput.value;
|
|
4123
|
+
const variantArbitrary = typeof variantInput === "string" ? false : variantInput.arbitrary;
|
|
4124
|
+
const parsedModifier = {
|
|
4125
|
+
type: variantName,
|
|
4126
|
+
value: variantValue,
|
|
4127
|
+
arbitrary: variantArbitrary
|
|
4128
|
+
};
|
|
4129
|
+
let matchKey = variantName;
|
|
4130
|
+
if (variantArbitrary && variantValue) {
|
|
4131
|
+
if (variantName) {
|
|
4132
|
+
matchKey = `${variantName}-[${variantValue}]`;
|
|
4133
|
+
parsedModifier.type = matchKey;
|
|
4134
|
+
} else {
|
|
4135
|
+
matchKey = `[${variantValue}]`;
|
|
4136
|
+
parsedModifier.type = matchKey;
|
|
4137
|
+
}
|
|
4138
|
+
} else if (variantValue) {
|
|
4139
|
+
matchKey = `${variantName}-[${variantValue}]`;
|
|
4140
|
+
parsedModifier.type = matchKey;
|
|
4141
|
+
}
|
|
4142
|
+
const plugin = getModifier(ctx).find((p) => p.match(matchKey, ctx));
|
|
4143
|
+
if (!plugin) {
|
|
4144
|
+
debugWarn(`[jsonToAst] Unknown variant: "${matchKey}"`);
|
|
4145
|
+
continue;
|
|
4146
|
+
}
|
|
4147
|
+
if (plugin.astHandler) ast = plugin.astHandler(ast, parsedModifier, ctx, [], i);
|
|
4148
|
+
if (plugin.modifySelector) {
|
|
4149
|
+
const result = plugin.modifySelector({
|
|
4150
|
+
selector,
|
|
4151
|
+
fullClassName: "JSON_GENERATED",
|
|
4152
|
+
mod: parsedModifier,
|
|
4153
|
+
context: ctx,
|
|
4154
|
+
variantChain: [],
|
|
4155
|
+
index: i
|
|
4156
|
+
});
|
|
4157
|
+
if (result == null) continue;
|
|
4158
|
+
if (plugin.wrap && (result === "&" || typeof result === "object" && !Array.isArray(result) && result.selector === "&" || Array.isArray(result) && result.length === 1 && result[0].selector === "&")) {} else if (typeof result === "string" && result.includes("&")) wrappers.push({
|
|
4159
|
+
type: "rule",
|
|
4160
|
+
selector: result
|
|
4161
|
+
});
|
|
4162
|
+
else if (typeof result === "object" && !Array.isArray(result) && result.selector) {
|
|
4163
|
+
const r = result;
|
|
4164
|
+
const wrappingType = r.wrappingType || "rule";
|
|
4165
|
+
wrappers.push({
|
|
4166
|
+
type: wrappingType,
|
|
4167
|
+
selector: r.selector,
|
|
4168
|
+
flatten: r.flatten,
|
|
4169
|
+
source: r.source
|
|
4170
|
+
});
|
|
4171
|
+
} else if (Array.isArray(result)) wrappers.push({
|
|
4172
|
+
type: "wrap",
|
|
4173
|
+
items: result.map((r) => ({
|
|
4174
|
+
type: r.wrappingType || "rule",
|
|
4175
|
+
selector: r.selector,
|
|
4176
|
+
source: r.source,
|
|
4177
|
+
nodes: []
|
|
4178
|
+
}))
|
|
4179
|
+
});
|
|
4180
|
+
}
|
|
4181
|
+
if (plugin.wrap) wrappers.push({
|
|
4182
|
+
type: "wrap",
|
|
4183
|
+
items: plugin.wrap(parsedModifier, ctx)
|
|
4184
|
+
});
|
|
4185
|
+
}
|
|
4186
|
+
for (let i = 0; i < wrappers.length; i++) {
|
|
4187
|
+
const wrap = wrappers[i];
|
|
4188
|
+
if (wrap.type === "wrap") ast = wrap.items.map((item) => item.type === "rule" || item.type === "style-rule" || item.type === "at-rule" || item.type === "at-root" ? {
|
|
4189
|
+
...item,
|
|
4190
|
+
nodes: [...item.nodes || [], ...ast]
|
|
4191
|
+
} : item);
|
|
4192
|
+
else if (wrap.type === "style-rule") ast = [{
|
|
4193
|
+
type: "style-rule",
|
|
4194
|
+
selector: wrap.selector,
|
|
4195
|
+
source: wrap.source,
|
|
4196
|
+
nodes: Array.isArray(ast) ? ast : [ast]
|
|
4197
|
+
}];
|
|
4198
|
+
else if (wrap.type === "at-rule") ast = [{
|
|
4199
|
+
type: "at-rule",
|
|
4200
|
+
name: wrap.name || "media",
|
|
4201
|
+
params: wrap.params,
|
|
4202
|
+
source: wrap.source,
|
|
4203
|
+
nodes: Array.isArray(ast) ? ast : [ast]
|
|
4204
|
+
}];
|
|
4205
|
+
else if (wrap.type === "rule") ast = [{
|
|
4206
|
+
type: "rule",
|
|
4207
|
+
selector: wrap.selector,
|
|
4208
|
+
source: wrap.source,
|
|
4209
|
+
nodes: Array.isArray(ast) ? ast : [ast]
|
|
4210
|
+
}];
|
|
4211
|
+
}
|
|
4212
|
+
}
|
|
4213
|
+
return applyVarPrefix(ast, ctx);
|
|
3519
4214
|
}
|
|
3520
4215
|
/**
|
|
3521
|
-
*
|
|
3522
|
-
*
|
|
4216
|
+
* Generates CSS from a list of BaroJsonInput objects.
|
|
4217
|
+
*
|
|
4218
|
+
* @param inputs Array of BaroJsonInput
|
|
4219
|
+
* @param ctx Context
|
|
4220
|
+
* @param opts Options (minify, etc.)
|
|
4221
|
+
* @returns CSS string
|
|
3523
4222
|
*/
|
|
3524
|
-
function
|
|
3525
|
-
|
|
3526
|
-
const
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
};
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
isVar: false
|
|
3545
|
-
};
|
|
4223
|
+
function generateCssFromJson(inputs, ctx, opts) {
|
|
4224
|
+
const allAtRootNodes = [];
|
|
4225
|
+
const cssList = [];
|
|
4226
|
+
inputs.forEach((input) => {
|
|
4227
|
+
const cleanAst = optimizeAst(jsonToAst(input, ctx));
|
|
4228
|
+
cleanAst.forEach((node) => {
|
|
4229
|
+
if (node.type === "at-root") allAtRootNodes.push(...node.nodes);
|
|
4230
|
+
});
|
|
4231
|
+
let reconstructedName = input.utility.name;
|
|
4232
|
+
if (input.utility.value) reconstructedName += `-${input.utility.value}`;
|
|
4233
|
+
if (input.utility.arbitrary) reconstructedName = `${input.utility.name}-[${input.utility.value}]`;
|
|
4234
|
+
if (input.variants) reconstructedName = `${input.variants.map((v) => typeof v === "string" ? v : v.name).join(":")}:${reconstructedName}`;
|
|
4235
|
+
const css = astToCss(cleanAst, cleanAst.some((node) => node.type === "style-rule") ? void 0 : `.${reconstructedName.replace(/[^a-zA-Z0-9-_]/g, "\\$&")}`, {
|
|
4236
|
+
minify: opts?.minify,
|
|
4237
|
+
important: input.utility.important ?? false
|
|
4238
|
+
});
|
|
4239
|
+
if (css) cssList.push(css);
|
|
4240
|
+
});
|
|
4241
|
+
const rootCss = rootToCss(allAtRootNodes);
|
|
4242
|
+
return `${rootCss ? `:root,:host {${rootCss}}` : ""}${cssList.join(opts?.minify ? "" : "\n")}`;
|
|
3546
4243
|
}
|
|
3547
4244
|
//#endregion
|
|
3548
4245
|
//#region src/presets/interactivity.ts
|
|
@@ -3556,10 +4253,7 @@ functionalUtility({
|
|
|
3556
4253
|
supportsArbitrary: true,
|
|
3557
4254
|
supportsCustomProperty: true,
|
|
3558
4255
|
handle: (value, _ctx, _token, extra) => {
|
|
3559
|
-
if (extra?.realThemeValue)
|
|
3560
|
-
if (extra.opacity) return [atRule("supports", `(color:color-mix(in lab, red, red))`, [decl("accent-color", `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`)]), decl("accent-color", value)];
|
|
3561
|
-
return [decl("accent-color", `var(--color-${extra.realThemeValue})`)];
|
|
3562
|
-
}
|
|
4256
|
+
if (extra?.realThemeValue) return themeColorDecls("accent-color", value, extra);
|
|
3563
4257
|
return [decl("accent-color", value)];
|
|
3564
4258
|
},
|
|
3565
4259
|
handleCustomProperty: (value) => [decl("accent-color", `var(${value})`)],
|
|
@@ -3578,10 +4272,7 @@ functionalUtility({
|
|
|
3578
4272
|
supportsArbitrary: true,
|
|
3579
4273
|
supportsCustomProperty: true,
|
|
3580
4274
|
handle: (value, ctx, token, extra) => {
|
|
3581
|
-
if (extra?.realThemeValue)
|
|
3582
|
-
if (extra.opacity) return [atRule("supports", `(color:color-mix(in lab, red, red))`, [decl("caret-color", `color-mix(in lab, ${value} ${extra.opacity}%, transparent)`)]), decl("caret-color", value)];
|
|
3583
|
-
return [decl("caret-color", `var(--color-${extra.realThemeValue})`)];
|
|
3584
|
-
}
|
|
4275
|
+
if (extra?.realThemeValue) return themeColorDecls("caret-color", value, extra);
|
|
3585
4276
|
return [decl("caret-color", value)];
|
|
3586
4277
|
},
|
|
3587
4278
|
handleCustomProperty: (value) => [decl("caret-color", `var(${value})`)],
|
|
@@ -3946,22 +4637,11 @@ staticUtility("caption-bottom", [["caption-side", "bottom"]], { category: "table
|
|
|
3946
4637
|
//#region src/presets/shadow-color.ts
|
|
3947
4638
|
/** Opacity modifier to an alpha: `50` → 50%, `[20%]` → 20%, `(--o)` → var(--o); anything else is invalid. */
|
|
3948
4639
|
function parseAlpha(op) {
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
alpha:
|
|
3952
|
-
isVar:
|
|
3953
|
-
};
|
|
3954
|
-
const pct = /^\[(\d+(?:\.\d+)?)%\]$/.exec(op);
|
|
3955
|
-
if (pct) return {
|
|
3956
|
-
alpha: `${pct[1]}%`,
|
|
3957
|
-
isVar: false
|
|
3958
|
-
};
|
|
3959
|
-
const cp = /^\((--[\w-]+)\)$/.exec(op);
|
|
3960
|
-
if (cp) return {
|
|
3961
|
-
alpha: `var(${cp[1]})`,
|
|
3962
|
-
isVar: true
|
|
4640
|
+
const a = op ? normalizeAlpha(op) : null;
|
|
4641
|
+
return a && {
|
|
4642
|
+
alpha: a.amount,
|
|
4643
|
+
isVar: a.isVar
|
|
3963
4644
|
};
|
|
3964
|
-
return null;
|
|
3965
4645
|
}
|
|
3966
4646
|
function splitTop(value, sep) {
|
|
3967
4647
|
const out = [];
|
|
@@ -4470,6 +5150,11 @@ function layerColor(layer, main, opacity, token, realThemeValue) {
|
|
|
4470
5150
|
if (main.startsWith("color:")) return shadowColorDecls(layer, `var(${main.slice(6)})`, opacity);
|
|
4471
5151
|
if (token.arbitrary && parseColor(main)) return shadowColorDecls(layer, main, opacity);
|
|
4472
5152
|
}
|
|
5153
|
+
function customShadowAlpha(layer, opacity) {
|
|
5154
|
+
if (!opacity) return [];
|
|
5155
|
+
const a = parseAlpha(opacity);
|
|
5156
|
+
return a ? [decl(`--baro-${layer}-alpha`, a.alpha)] : null;
|
|
5157
|
+
}
|
|
4473
5158
|
for (const layer of ["shadow", "inset-shadow"]) functionalUtility({
|
|
4474
5159
|
name: layer,
|
|
4475
5160
|
supportsArbitrary: true,
|
|
@@ -4486,11 +5171,17 @@ for (const layer of ["shadow", "inset-shadow"]) functionalUtility({
|
|
|
4486
5171
|
if (token.arbitrary) return boxShadowLayer(layer, layer === "inset-shadow" ? insetEach(value) : value, opacity);
|
|
4487
5172
|
return null;
|
|
4488
5173
|
},
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
5174
|
+
ownsOpacity: true,
|
|
5175
|
+
handleCustomProperty: (value, _ctx, _token, extra) => {
|
|
5176
|
+
if (value.startsWith("color:")) return shadowColorDecls(layer, `var(${value.slice(6)})`, extra?.opacity) ?? [];
|
|
5177
|
+
const alpha = customShadowAlpha(layer, extra?.opacity);
|
|
5178
|
+
return alpha ? [
|
|
5179
|
+
ringShadowProperties(),
|
|
5180
|
+
...alpha,
|
|
5181
|
+
decl(`--baro-${layer}`, layer === "inset-shadow" ? `inset var(${value})` : `var(${value})`),
|
|
5182
|
+
decl("box-shadow", SHADOW_COMPOSITE)
|
|
5183
|
+
] : [];
|
|
5184
|
+
}
|
|
4494
5185
|
});
|
|
4495
5186
|
var textShadowProperties = () => atRoot([property("--baro-text-shadow-color"), property("--baro-text-shadow-alpha", "100%", "<percentage>")]);
|
|
4496
5187
|
var namedTextShadow = (ctx, name) => {
|
|
@@ -4520,7 +5211,19 @@ functionalUtility({
|
|
|
4520
5211
|
if (token.arbitrary) return textShadowValue(value, opacity);
|
|
4521
5212
|
return null;
|
|
4522
5213
|
},
|
|
4523
|
-
|
|
5214
|
+
ownsOpacity: true,
|
|
5215
|
+
handleCustomProperty: (value, _ctx, _token, extra) => {
|
|
5216
|
+
if (value.startsWith("color:")) {
|
|
5217
|
+
const color = shadowColorDecls("text-shadow", `var(${value.slice(6)})`, extra?.opacity);
|
|
5218
|
+
return color ? [textShadowProperties(), ...color] : [];
|
|
5219
|
+
}
|
|
5220
|
+
const alpha = customShadowAlpha("text-shadow", extra?.opacity);
|
|
5221
|
+
return alpha ? [
|
|
5222
|
+
textShadowProperties(),
|
|
5223
|
+
...alpha,
|
|
5224
|
+
decl("text-shadow", `var(${value})`)
|
|
5225
|
+
] : [];
|
|
5226
|
+
},
|
|
4524
5227
|
category: "effects"
|
|
4525
5228
|
});
|
|
4526
5229
|
[
|
|
@@ -4584,17 +5287,6 @@ functionalUtility({
|
|
|
4584
5287
|
], { category: "effects" });
|
|
4585
5288
|
});
|
|
4586
5289
|
staticUtility("ring-inset", [["--baro-ring-inset", "inset"]], { category: "effects" });
|
|
4587
|
-
function createRingColorDecls(key, main, opacity, realThemeValue) {
|
|
4588
|
-
const colorVar = `var(--color-${realThemeValue})`;
|
|
4589
|
-
let colorMix = colorVar;
|
|
4590
|
-
let fallback = colorVar;
|
|
4591
|
-
if (opacity) {
|
|
4592
|
-
colorMix = `color-mix(in oklab, ${colorVar} ${opacity}%, transparent)`;
|
|
4593
|
-
if (parseColor(main) && main.startsWith("#")) fallback = `${main}${Math.round(Number(opacity) / 100 * 255).toString(16).padStart(2, "0")}`;
|
|
4594
|
-
else fallback = colorMix;
|
|
4595
|
-
}
|
|
4596
|
-
return [atRule("supports", "(color:color-mix(in lab, red, red))", [decl(key, colorMix)]), decl(key, fallback)];
|
|
4597
|
-
}
|
|
4598
5290
|
functionalUtility({
|
|
4599
5291
|
name: "ring",
|
|
4600
5292
|
supportsArbitrary: true,
|
|
@@ -4608,28 +5300,9 @@ functionalUtility({
|
|
|
4608
5300
|
decl("--baro-ring-shadow", ringShadowValue(value)),
|
|
4609
5301
|
decl("box-shadow", SHADOW_COMPOSITE)
|
|
4610
5302
|
];
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
if (realThemeValue) return createRingColorDecls("--baro-ring-color", main, opacity, realThemeValue);
|
|
4614
|
-
if (main.startsWith("color:")) {
|
|
4615
|
-
const cp = main.replace("color:", "");
|
|
4616
|
-
let colorMix = `var(${cp})`;
|
|
4617
|
-
let fallback = colorMix;
|
|
4618
|
-
if (opacity) {
|
|
4619
|
-
colorMix = `color-mix(in oklab, var(${cp}) ${opacity}%, transparent)`;
|
|
4620
|
-
fallback = colorMix;
|
|
4621
|
-
}
|
|
4622
|
-
return [atRule("supports", "(color:color-mix(in lab, red, red))", [decl("--baro-ring-color", colorMix)]), decl("--baro-ring-color", fallback)];
|
|
4623
|
-
}
|
|
5303
|
+
if (extra?.realThemeValue) return themeColorDecls("--baro-ring-color", main, extra);
|
|
5304
|
+
if (main.startsWith("color:")) return [decl("--baro-ring-color", `var(${main.slice(6)})`)];
|
|
4624
5305
|
if (token.arbitrary) {
|
|
4625
|
-
let colorMix = main;
|
|
4626
|
-
let fallback = main;
|
|
4627
|
-
if (opacity) {
|
|
4628
|
-
colorMix = `color-mix(in oklab, ${main} ${opacity}%, transparent)`;
|
|
4629
|
-
if (parseColor(main) && main.startsWith("#")) fallback = `${main}${Math.round(Number(opacity) / 100 * 255).toString(16).padStart(2, "0")}`;
|
|
4630
|
-
else fallback = colorMix;
|
|
4631
|
-
return [atRule("supports", "(color:color-mix(in lab, red, red))", [decl("--baro-ring-color", colorMix)]), decl("--baro-ring-color", fallback)];
|
|
4632
|
-
}
|
|
4633
5306
|
if (!parseColor(main) && /^(-?(\d+\.?\d*|\.\d+)(px|rem|em|%|vw|vh|vmin|vmax|ch|ex|pt|cm|mm|in|pc)|0|(length:.+)|calc\(.+\))$/i.test(main)) {
|
|
4634
5307
|
const width = main.startsWith("length:") ? main.slice(7) : main;
|
|
4635
5308
|
return [
|
|
@@ -4656,30 +5329,9 @@ functionalUtility({
|
|
|
4656
5329
|
themeKeys: ["colors", "shadows"],
|
|
4657
5330
|
handle: (value, ctx, token, extra) => {
|
|
4658
5331
|
const main = value;
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
if (
|
|
4662
|
-
if (main.startsWith("color:")) {
|
|
4663
|
-
const cp = main.replace("color:", "");
|
|
4664
|
-
let colorMix = `var(${cp})`;
|
|
4665
|
-
let fallback = colorMix;
|
|
4666
|
-
if (opacity) {
|
|
4667
|
-
colorMix = `color-mix(in oklab, var(${cp}) ${opacity}%, transparent)`;
|
|
4668
|
-
fallback = colorMix;
|
|
4669
|
-
}
|
|
4670
|
-
return [atRule("supports", "(color:color-mix(in lab, red, red))", [decl("--baro-inset-ring-color", colorMix)]), decl("--baro-inset-ring-color", fallback)];
|
|
4671
|
-
}
|
|
4672
|
-
if (token.arbitrary) {
|
|
4673
|
-
let colorMix = main;
|
|
4674
|
-
let fallback = main;
|
|
4675
|
-
if (opacity) {
|
|
4676
|
-
colorMix = `color-mix(in oklab, ${main} ${opacity}%, transparent)`;
|
|
4677
|
-
if (parseColor(main) && main.startsWith("#")) fallback = `${main}${Math.round(Number(opacity) / 100 * 255).toString(16).padStart(2, "0")}`;
|
|
4678
|
-
else fallback = colorMix;
|
|
4679
|
-
return [atRule("supports", "(color:color-mix(in lab, red, red))", [decl("--baro-inset-ring-color", colorMix)]), decl("--baro-inset-ring-color", fallback)];
|
|
4680
|
-
}
|
|
4681
|
-
return [decl("box-shadow", `inset ${main}`)];
|
|
4682
|
-
}
|
|
5332
|
+
if (extra?.realThemeValue) return themeColorDecls("--baro-inset-ring-color", main, extra);
|
|
5333
|
+
if (main.startsWith("color:")) return [decl("--baro-inset-ring-color", `var(${main.slice(6)})`)];
|
|
5334
|
+
if (token.arbitrary) return [parseColor(main) || /^var\(--[^)]+\)$/.test(main) ? decl("--baro-inset-ring-color", main) : decl("box-shadow", `inset ${main}`)];
|
|
4683
5335
|
if (main === "inherit" || main === "current" || main === "transparent") return [decl("--baro-inset-ring-color", main === "current" ? "currentColor" : main)];
|
|
4684
5336
|
return null;
|
|
4685
5337
|
},
|
|
@@ -6504,7 +7156,7 @@ functionalUtility({
|
|
|
6504
7156
|
supportsOpacity: true,
|
|
6505
7157
|
handle: (value, _ctx, _token, extra) => {
|
|
6506
7158
|
if (extra?.realThemeValue) return [rule("&::placeholder", themeColorDecls("color", value, extra))];
|
|
6507
|
-
if (parseColor(value)) return placeholderColor(value);
|
|
7159
|
+
if (parseColor(value) || /^var\(--[\w-]+\)$/.test(value)) return placeholderColor(value);
|
|
6508
7160
|
return null;
|
|
6509
7161
|
},
|
|
6510
7162
|
handleCustomProperty: (value) => placeholderColor(`var(${value})`),
|
|
@@ -6710,7 +7362,7 @@ var stopsDecls = (stop, color) => {
|
|
|
6710
7362
|
if (parseColor(value)) return stopsDecls(stop, value);
|
|
6711
7363
|
return null;
|
|
6712
7364
|
},
|
|
6713
|
-
handleCustomProperty: (value) => [decl(`--baro-gradient-${stop}`, `var(${value})`)],
|
|
7365
|
+
handleCustomProperty: (value) => value.startsWith("color:") ? stopsDecls(stop, `var(${value.slice(6)})`) : [decl(`--baro-gradient-${stop}`, `var(${value})`)],
|
|
6714
7366
|
description: `${stop} gradient stop utility (color, percent, custom property, arbitrary supported)`,
|
|
6715
7367
|
category: "background"
|
|
6716
7368
|
});
|
|
@@ -6892,11 +7544,11 @@ var withBorderStyle = (props, width) => [
|
|
|
6892
7544
|
...propList.map((prop) => [prop.replace("width", "style"), "var(--baro-border-style)"]),
|
|
6893
7545
|
...propList.map((prop) => [prop, width])
|
|
6894
7546
|
];
|
|
6895
|
-
staticUtility(`${name}-0`, styled("0px"));
|
|
6896
|
-
staticUtility(`${name}-2`, styled("2px"));
|
|
6897
|
-
staticUtility(`${name}-4`, styled("4px"));
|
|
6898
|
-
staticUtility(`${name}-8`, styled("8px"));
|
|
6899
|
-
staticUtility(`${name}`, styled("1px"));
|
|
7547
|
+
staticUtility(`${name}-0`, styled("0px"), { category: "borders" });
|
|
7548
|
+
staticUtility(`${name}-2`, styled("2px"), { category: "borders" });
|
|
7549
|
+
staticUtility(`${name}-4`, styled("4px"), { category: "borders" });
|
|
7550
|
+
staticUtility(`${name}-8`, styled("8px"), { category: "borders" });
|
|
7551
|
+
staticUtility(`${name}`, styled("1px"), { category: "borders" });
|
|
6900
7552
|
functionalUtility({
|
|
6901
7553
|
name,
|
|
6902
7554
|
themeKeys: ["colors", "borderWidth"],
|
|
@@ -7066,7 +7718,7 @@ functionalUtility({
|
|
|
7066
7718
|
return null;
|
|
7067
7719
|
},
|
|
7068
7720
|
handleCustomProperty: (value) => {
|
|
7069
|
-
if (value.startsWith("color:")) return [decl("outline-color", value.
|
|
7721
|
+
if (value.startsWith("color:")) return [decl("outline-color", `var(${value.slice(6)})`)];
|
|
7070
7722
|
if (value.startsWith("length:")) return withOutlineStyle(`var(${value.replace("length:", "")})`);
|
|
7071
7723
|
return [decl("outline-color", `var(${value})`)];
|
|
7072
7724
|
},
|
|
@@ -7098,7 +7750,7 @@ functionalUtility({
|
|
|
7098
7750
|
handle: (value, _ctx, token, extra) => {
|
|
7099
7751
|
if (token.prefix !== "divide") return null;
|
|
7100
7752
|
if (extra?.realThemeValue) return [rule(":where(& > :not(:last-child))", themeColorDecls("border-color", value, extra))];
|
|
7101
|
-
if (parseColor(value)) return divideColor(value);
|
|
7753
|
+
if (parseColor(value) || /^var\(--[\w-]+\)$/.test(value)) return divideColor(value);
|
|
7102
7754
|
return null;
|
|
7103
7755
|
},
|
|
7104
7756
|
handleCustomProperty: (value, _ctx, token) => token.prefix === "divide" ? divideColor(`var(${value})`) : [],
|
|
@@ -7517,8 +8169,9 @@ functionalUtility({
|
|
|
7517
8169
|
themeKeys: ["colors"],
|
|
7518
8170
|
supportsArbitrary: true,
|
|
7519
8171
|
supportsCustomProperty: true,
|
|
8172
|
+
supportsOpacity: true,
|
|
7520
8173
|
handle: (value, ctx, token, extra) => {
|
|
7521
|
-
if (extra?.realThemeValue) return
|
|
8174
|
+
if (extra?.realThemeValue) return themeColorDecls("fill", value, extra);
|
|
7522
8175
|
return [decl("fill", value)];
|
|
7523
8176
|
},
|
|
7524
8177
|
description: "fill utility (static, theme, arbitrary, custom property supported)",
|
|
@@ -7534,6 +8187,7 @@ functionalUtility({
|
|
|
7534
8187
|
themeKeys: ["colors", "strokeWidth"],
|
|
7535
8188
|
supportsArbitrary: true,
|
|
7536
8189
|
supportsCustomProperty: true,
|
|
8190
|
+
supportsOpacity: true,
|
|
7537
8191
|
handle: (value, ctx, token, extra) => {
|
|
7538
8192
|
if (parseNumber(value) || extra?.themeNamespace === "strokeWidth") return [decl("stroke-width", value)];
|
|
7539
8193
|
if (token.arbitrary) {
|
|
@@ -7541,7 +8195,7 @@ functionalUtility({
|
|
|
7541
8195
|
if (hint) return [decl("stroke-width", hint[2])];
|
|
7542
8196
|
if (!parseColor(value) && (STROKE_LENGTH.test(value) || /^calc\(/.test(value))) return [decl("stroke-width", value)];
|
|
7543
8197
|
}
|
|
7544
|
-
if (extra?.realThemeValue) return
|
|
8198
|
+
if (extra?.realThemeValue) return themeColorDecls("stroke", value, extra);
|
|
7545
8199
|
return [decl("stroke", value)];
|
|
7546
8200
|
},
|
|
7547
8201
|
handleCustomProperty: (value) => {
|
|
@@ -8550,53 +9204,6 @@ functionalModifier((mod) => /^child-(.+)$/.test(mod), ({ selector, mod }) => {
|
|
|
8550
9204
|
};
|
|
8551
9205
|
}, void 0);
|
|
8552
9206
|
//#endregion
|
|
8553
|
-
|
|
8554
|
-
var LEADING_AT = /^\s*@(media|container)\s+([^{]*)\{/;
|
|
8555
|
-
var LATE_MEDIA = /prefers-color-scheme|\bprint\b|forced-colors|orientation/;
|
|
8556
|
-
var MIN_W = /(?:min-width\s*:\s*|width\s*>=?\s*)([\d.]+)(px|rem|em)?/;
|
|
8557
|
-
var MAX_W = /(?:max-width\s*:\s*|width\s*<=?\s*)([\d.]+)(px|rem|em)?/;
|
|
8558
|
-
function toPx(n, unit) {
|
|
8559
|
-
const v = parseFloat(n);
|
|
8560
|
-
return unit === "rem" || unit === "em" ? v * 16 : v;
|
|
8561
|
-
}
|
|
8562
|
-
function preludeKey(kind, prelude) {
|
|
8563
|
-
const container = kind === "container";
|
|
8564
|
-
if (!container && /^\s*not\b/i.test(prelude)) return [0, 0];
|
|
8565
|
-
const min = MIN_W.exec(prelude);
|
|
8566
|
-
if (min) return [container ? 4 : 2, toPx(min[1], min[2])];
|
|
8567
|
-
const max = MAX_W.exec(prelude);
|
|
8568
|
-
if (max) return [container ? 3 : 1, -toPx(max[1], max[2])];
|
|
8569
|
-
if (!container && LATE_MEDIA.test(prelude)) return [5, 0];
|
|
8570
|
-
return [0, 0];
|
|
8571
|
-
}
|
|
8572
|
-
function ruleSortKey(rule) {
|
|
8573
|
-
const key = [];
|
|
8574
|
-
let rest = rule;
|
|
8575
|
-
let m;
|
|
8576
|
-
while (m = LEADING_AT.exec(rest)) {
|
|
8577
|
-
const [g, v] = preludeKey(m[1], m[2]);
|
|
8578
|
-
key.push(g, v);
|
|
8579
|
-
rest = rest.slice(m[0].length);
|
|
8580
|
-
}
|
|
8581
|
-
return key;
|
|
8582
|
-
}
|
|
8583
|
-
function compareKeys(a, b) {
|
|
8584
|
-
const n = Math.min(a.length, b.length);
|
|
8585
|
-
for (let i = 0; i < n; i++) if (a[i] !== b[i]) return a[i] - b[i];
|
|
8586
|
-
return a.length - b.length;
|
|
8587
|
-
}
|
|
8588
|
-
/** Index after the last key <= `key` (stable upper bound) in sorted `keys`. */
|
|
8589
|
-
function upperBound(keys, key) {
|
|
8590
|
-
let lo = 0;
|
|
8591
|
-
let hi = keys.length;
|
|
8592
|
-
while (lo < hi) {
|
|
8593
|
-
const mid = lo + hi >> 1;
|
|
8594
|
-
if (compareKeys(keys[mid], key) <= 0) lo = mid + 1;
|
|
8595
|
-
else hi = mid;
|
|
8596
|
-
}
|
|
8597
|
-
return lo;
|
|
8598
|
-
}
|
|
8599
|
-
//#endregion
|
|
8600
|
-
export { AstCache, IncrementalParser, ParseResultCache, UtilityCache, WeakCache, arbitraryPropertyRegistration, astCache, astToCss, atRoot, atRule, clearAllCaches, clearAstCache, collectDeclPaths, comment, compareKeys, configGetter, createContext, decl, declPathToAst, deepMerge, defaultConfig, escapeClassName, expandThemeFunctions, functionalModifier, functionalUtility, generateCss, generateCssFromJson, generateCssRules, getAstCacheStats, getModifier, getPreflightCSS, getUtility, hasCommentDelimiter, hasCommentToken, hasHtmlEndTagOpener, hasPreset, isBalancedPrelude, isDebug, isSafeVariantToken, isSafeVariantValue, isScopedSelector, isStructureSafeValue, isWellFormedVariantBrackets, jsonToAst, mergeAstTreeList, modifierRegistry, normalizeMathSpacing, optimizeAst, parseClassName, parseClassToAst, parseResultCache, property, raw, registerModifier, registerUtility, resolveTheme, rootToCss, rule, ruleSortKey, setContextCacheReset, setDebug, staticModifier, staticUtility, styleRule, themeGetter, themeKeyValue, themeKeyVar, themeToCssVars, tokenize, upperBound, utilityCache };
|
|
9207
|
+
export { AstCache, IncrementalParser, ParseResultCache, REJECT_CLASS, UtilityCache, WeakCache, arbitraryPropertyRegistration, astCache, astToCss, atRoot, atRule, clearAllCaches, clearAstCache, collectDeclPaths, comment, compareKeys, configGetter, createContext, decl, declPathToAst, deepMerge, defaultConfig, escapeClassName, expandThemeFunctions, functionalModifier, functionalUtility, generateCss, generateCssFromJson, generateCssRules, getAstCacheStats, getModifier, getPreflightCSS, getUtility, hasCommentDelimiter, hasCommentToken, hasHtmlEndTagOpener, hasPreset, isBalancedPrelude, isDebug, isSafeVariantToken, isSafeVariantValue, isScopedSelector, isStructureSafeValue, isWellFormedVariantBrackets, jsonToAst, mergeAstTreeList, modifierRegistry, normalizeMathSpacing, optimizeAst, parseClassName, parseClassToAst, parseResultCache, property, raw, registerModifier, registerUtility, resolveTheme, rootToCss, rule, ruleSortKey, setContextCacheReset, setDebug, staticModifier, staticUtility, styleRule, themeGetter, themeKeyValue, themeKeyVar, themeToCssVars, tokenize, upperBound, utilityCache };
|
|
8601
9208
|
|
|
8602
9209
|
//# sourceMappingURL=index.js.map
|